CFG 中的匹配标签:是否可以定义类似的产品?
Matching Tags in CFG: Is it possible to define a suchlike production?
真正的 CFG 解析器比正则表达式解析器更重要的是匹配嵌套括号。这些很容易在 CFG 中指定。
但我想知道:匹配标签呢?为了,exemplum gratia,解析 BBCode。
匹配标签(BBCode、XML、HTML)是否可以在上下文无关语法中使用?
祝福!
除非可能的标签数量是有限的,否则无法在 context-free 语法中表达它。 context-free 文法无法识别必须重复子字符串才能使句子有效的语言,这是该规则的一个特例;这也排除了,例如,编写一个 context-free 语法来表达标识符必须在使用前声明的共同约束。 (在这种情况下,子字符串是标签的名称;在编程语言的情况下,它将是标识符的名称。)
如果可能的标签数量有限,您只需为每个可能的标签编写一个 parenthesis-like 规则。
或者,如果所有标签 必须 显式关闭(如 XHTML,但不是 HTML),则语法不需要区分不同的标签;检查关闭标签的名称是否与它正在关闭的标签的名称相匹配就足够了。
上述两种策略的混合可用于语言(例如 HTML5),其中具有特定语法的标签数量有限,而所有其他标签都需要明确的关闭标签。
不过,我不建议尝试为 HTML5 编写 CF 语法,除非您想花大量时间阅读和重新解释围绕 stack-based state machine 的规范。事实上,我不建议尝试为 HTML5 编写解析器,因为有 freely-available 是由理解 "specification" 的复杂性的人编写的,这确实是一个移动的目标.
另一方面,HTML5 的某些方面本来可以使用 CFG 更自然地处理,其中状态机既不容易理解也不容易实现。 (这里我 不是 指的是 adoption agency algorithm, which is well outside of the scope of context-free grammars.) For example the end-tag and start-tag omission rules for <table>
contents could be a lot more straightforward if written in EBNF. (I haven't verified if these are actually correct, and since I left out comment-handling, some tags which I never use, 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
,并为正确的名称嵌套进行语义检查。语法有歧义;它需要增加评论,即所有 shift-reduce 冲突都已解决以支持转移。为避免 Comment
(和其他一些标签)触发可选开放标签的虚假缩减,Comment
需要在许多地方明确包含,除非您只是在词法扫描中删除注释。 (我会这样做,但标准禁止这样做。)
真正的 CFG 解析器比正则表达式解析器更重要的是匹配嵌套括号。这些很容易在 CFG 中指定。
但我想知道:匹配标签呢?为了,exemplum gratia,解析 BBCode。
匹配标签(BBCode、XML、HTML)是否可以在上下文无关语法中使用?
祝福!
除非可能的标签数量是有限的,否则无法在 context-free 语法中表达它。 context-free 文法无法识别必须重复子字符串才能使句子有效的语言,这是该规则的一个特例;这也排除了,例如,编写一个 context-free 语法来表达标识符必须在使用前声明的共同约束。 (在这种情况下,子字符串是标签的名称;在编程语言的情况下,它将是标识符的名称。)
如果可能的标签数量有限,您只需为每个可能的标签编写一个 parenthesis-like 规则。
或者,如果所有标签 必须 显式关闭(如 XHTML,但不是 HTML),则语法不需要区分不同的标签;检查关闭标签的名称是否与它正在关闭的标签的名称相匹配就足够了。
上述两种策略的混合可用于语言(例如 HTML5),其中具有特定语法的标签数量有限,而所有其他标签都需要明确的关闭标签。
不过,我不建议尝试为 HTML5 编写 CF 语法,除非您想花大量时间阅读和重新解释围绕 stack-based state machine 的规范。事实上,我不建议尝试为 HTML5 编写解析器,因为有 freely-available 是由理解 "specification" 的复杂性的人编写的,这确实是一个移动的目标.
另一方面,HTML5 的某些方面本来可以使用 CFG 更自然地处理,其中状态机既不容易理解也不容易实现。 (这里我 不是 指的是 adoption agency algorithm, which is well outside of the scope of context-free grammars.) For example the end-tag and start-tag omission rules for <table>
contents could be a lot more straightforward if written in EBNF. (I haven't verified if these are actually correct, and since I left out comment-handling, some tags which I never use, 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
,并为正确的名称嵌套进行语义检查。语法有歧义;它需要增加评论,即所有 shift-reduce 冲突都已解决以支持转移。为避免 Comment
(和其他一些标签)触发可选开放标签的虚假缩减,Comment
需要在许多地方明确包含,除非您只是在词法扫描中删除注释。 (我会这样做,但标准禁止这样做。)