【发布时间】:2010-06-20 20:16:13
【问题描述】:
我有一个 EBNF 语法,其中包含一些具有这种模式的规则:
sequence ::=
item
| item extra* sequence
上面和下面是等价的吗?
sequence ::=
item (extra* sequence)*
编辑
由于你们中的一些人观察到两个序列中的错误或歧义,我将给出一个具体的例子。 SVG specification 提供grammar for path data。该语法有几个具有这种模式的生成器:
lineto-argument-sequence:
coordinate-pair
| coordinate-pair comma-wsp? lineto-argument-sequence
上面可以改写成下面这样吗?
lineto-argument-sequence:
coordinate-pair (comma-wsp? lineto-argument-sequence)*
【问题讨论】:
-
你想知道你是否可以这样做,或者你是否应该这样做? EBNF 优于 BNF 的重点是(除其他外)消除对循环构造使用递归的需要。查看您链接的规范后,我可以告诉您它非常模棱两可,可能需要一堆前瞻规则。我会修改我的答案以考虑您的编辑。
-
好吧,我想知道的一件事是,当第二种样式似乎等效但也更短时,SVG 规范是否会使用第一种样式样式是否有特殊原因,或者为什么它们没有像您建议的那样使用无递归版本。
-
您可能会发现这些文件格式历来都有手写解析器。当一个人阅读语法时,他们会看到递归并对自己说,“看看一个循环”,但即使是最好的解析器生成器也没有人类那么聪明。像任何编程语言(这就是生成器的语法)一样,程序执行它被告知执行的操作,而不一定是您希望它执行的操作。
-
许多著名的编译器,至少在某些时候,都是手工滚动的。没有生成器可以比手动解析器的速度和灵活性更好。解析器生成器为您提供的是在短时间内启动和运行的能力。有一些强大的生成器可以处理各种蓬松的语法,但它们有性能损失。如果你想设计一种像蝙蝠一样解析的语言,那么你应该尽可能地限制回溯和前瞻。
-
您修改原始语法的方式(在 BNF 中有效)的问题是您保留了递归元素,在 BNF 中表示“重复和重复”,并将其包含在 [EBNF ] 可选循环,这意味着同样的事情。如果您要将语法从 BNF 翻译为 EBNF,那么您会尽可能多地尝试删除 BNF 语法中固有的递归元素和空产生式。