通过正则表达式解析器,真正的CFG解析器经常构成严重激励的是匹配嵌套括号。这些很容易在CFG中指定。
但我想知道:匹配标签怎么样?按顺序 exemplum gratia 来解析BBCode。
匹配标签(BBCode,XML,HTML)是否可以在无上下文语法中使用?
祝福!
答案 0 :(得分:1)
除非可能的标签数量有限,否则无法在无上下文语法中表达。规则的一个特定情况是,无上下文的语法无法识别必须重复子字符串才能使句子有效的语言;例如,这也排除了编写无上下文语法,该语法表达了在使用之前必须声明标识符的公共约束。 (在这种情况下,子字符串是标记的名称;在编程语言的情况下,它将是标识符的名称。)
如果可能的标签数量是有限的,您只需要为每个可能的标签编写一个类似括号的规则。
或者,如果所有标记必须明确关闭(如XHTML,而不是HTML),那么语法不需要区分不同的标记;检查close标签的名称是否与其正在关闭的标签的名称相匹配就足够了。
上述两种策略的混合可用于语言(例如HTML5),其中有特定语法的标签数量有限,而所有其他标签都需要显式关闭标记。
我不建议尝试为HTML5编写CF语法,除非你想花费大量的时间阅读并重新解释围绕stack-based state machine的规范。实际上,我不建议尝试为HTML5编写一个解析器,因为有些人可以自由地理解这些解释器"规范"的复杂性,这实际上是一个移动目标。 / p>
另一方面,HTML5的某些方面可以使用CFG更自然地处理,其中状态机既不易理解也不易于实现。 (这里我&#39; m 不引用adoption agency algorithm,这远远超出了无上下文语法的范围。)例如end-tag和start-tag省略规则如果用EBNF编写的话,<table>
内容可能会更直接。 (我还没有验证这些是否真的是正确的,而且由于我遗漏了评论处理,一些我从未使用的标签,foster-parenting以及其他强制树操作以进行错误恢复,因此它不应该除了作为一个模糊的轮廓之外使用):
Table ::= (Caption | Colgroup | Thead | Tfoot | TBody)*
Caption ::= CaptionOpenTag Content* CaptionCloseTag
Colgroup ::= ColgroupOpenTag? Col* ColgroupCloseTag?
Thead ::= TheadOpenTag Tr* TheadCloseTag?
Tfoot ::= TfootOpenTag Tr* TfootCloseTag?
Tbody ::= TbodyOpenTag? Tr* TbodyCloseTag?
Tr ::= TrOpenTag (Td|Th)* TrCloseTag?
Td ::= TdOpenTag Content* TdCloseTag?
Th ::= ThOpenTag Content* ThCloseTag?
这里,Content
不包括上述语法中特别提到的任何标签,并且它有自己的标签遗漏的古怪规则。 包括UnknownOpenTag
,UnknownCloseTag
和UnknownEmptyTag
,并对语法进行正确的名称嵌套检查。语法含糊不清;它需要增加评论,即所有转移 - 减少冲突都有利于转移。为了避免Comment
(以及其他一些标记)触发可选开放标记的虚假减少,Comment
需要在许多地方明确包含,除非您只是在词法扫描中删除注释。 (我会这样做,但标准禁止它。)