0

我一直在考虑使用 Scala 的解析器组合库(基本上是 PEG 解析器)编写 Textile 解析器,并且想知道我应该使用哪种方法来解析内联修饰符

This is *bold* text, _italic_ text, +underlined+ text, etc.

在这种情况下,很清楚什么是什么,应该解析什么。但是,有很多边缘情况不是很清楚。仅关注粗体文本:

Which sections get bolded: 
*onomato*poeia* ?
bold *word*, without a space after?
tyr*annos*aurus
a bold word in a (*bracket*)?
How about *This *case?

显然这是主观(哪些东西应该算作粗体)和客观(如何使解析规则正确解析它)的混合。

我倾向于 PEG 之类的东西

wordChar = [a-zA-Z]
nonWordChar = [^a-zA-Z]
boldStart = nonWordChar ~ * ~ wordChar
boldEnd = wordChar ~ * ~ nonWordChar
boldSection = boldStart ~ rep(not(boldEnd) ~ anyChar) ~ boldEnd

它将按如下方式解析上述内容:

<b>onomato*poeia</b> ?
bold <b>word</b>, without a space after?
tyr*annos*aurus    <- fails because of lack of whitespace
a bold word in a (<b>bracket</b>)?
How about *This *case? <- fails because there is no correct closing *

但是,我不确定此方法是否适用于所有用例,并且是否适用于所有边缘情况。有没有我可以复制和依赖的标准方法?如果可以避免的话,我宁愿不依赖我的临时未经过深思熟虑的语言规范。

4

2 回答 2

1

在降价的情况下没有标准,并且在边缘情况下实现有所不同。对于 markdown 的一组选择,您可以查看peg-markdown,它也在 MultiMarkdown 中使用。当然,markdown 在这方面比纺织品更复杂,因为它使用**粗体和*斜体,从而产生更多关于如何处理诸如*hello**there**.

PHP markdown extra 的开发人员 Michel Fortin 有一个测试套件,其中包括许多粗体/斜体的边缘案例。但是,我认为他在这里的决定并没有普遍的共识,并且许多实现的解析方式不同。

也就是说,我认为以下决定在降价中是没有争议的:

  • *仅在下一个字符是非空白字符时才开始强调。
  • *仅当前面的字符是非空白字符时才结束强调。
  • 强调可以出现在一个单词中,因此在 中he*ll*o,两个 l 被强调(尽管一些 markdown 实现禁用了该_字符的此功能,因为下划线在标识符中很常见)。
于 2012-08-08T23:02:46.457 回答
0

经过一段时间的采购,我找到了reStructuredText 的内联标记识别规则

它不遵循降价规则;特别是诸如t*hi*s不被解析为内联标签之类的东西,但它非常相似并且具有相似的总体目的。

它也是一个有些复杂的规范(例如,括号和标点符号的特殊大小写),但它的规范非常好,经过彻底的解释和证明。我发现它的规格是一个非常坚实的基础。

于 2012-08-08T23:23:03.607 回答