我有一个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)*
答案 0 :(得分:2)
此规则也等同于sequence ::= (item extra*)*
,从而删除sequence
上的递归。
答案 1 :(得分:2)
不是真的,他们似乎有不同的错误。第一个序列在“item”周围是不明确的,因为“extra”是可选的。您可以将其重写为以下内容以消除歧义:
sequence3 ::=
item extra* sequence3
第二个是关于“额外”的围观,因为它基本上是两个嵌套循环,都以“额外”开头。您可以将其重写为以下内容以消除歧义:
sequence4 ::=
item ((extra|item))*
您的第一个版本可能会阻塞由单个“项目”组成的输入序列(这取决于解析器实现),因为它不会消除歧义。
我的重写假设您想要匹配以“item”开头的序列,并且可选地后跟任意顺序的一系列(0或更多)“item”或“extra”。
e.g。
item
item extra
item extra item
item extra extra item
item item item item
item item item item extra
etc.
如果没有附加信息,我会个人倾向于选择标记为“sequence4”的选项,因为所有其他选项仅仅使用递归作为昂贵的循环结构。如果您愿意给我更多信息,我可能会给出更好的答案。
编辑:基于Jorn的出色观察(使用小mod)。
如果您重写“sequence3”以删除递归,则会得到以下内容:
sequence5 ::=
(item extra*)+
它认为这将是我的首选版本,而不是“sequence4”。
我必须指出,上述所有三个版本在功能上都是等效的(作为识别器或生成器)。 3的解析树将与4和5不同,但我不认为这会影响除了性能之外的任何事情。
修改强> 关于以下内容:
lineto-argument-sequence:
coordinate-pair
| coordinate-pair comma-wsp? lineto-argument-sequence
这个作品所说的是lineto-argument-sequence
由至少一个coordinate-pair
组成,后跟零或多个coordinate-pair
分隔的可选白/逗号。以下任何一项都构成lineto-argument-sequence
(读 - >为'变成'):
1,2 -> (1, 2)
1.5.6 -> (1.5, 0.6)
1.5.06 -> (1.5, 0.06)
2 3 3 4 -> (2,3) (3,4)
2,3-3-4 -> (2,3) (-3,-4)
2 3 3 -> ERROR
所以coordinate-pair
实际上是连续2 number
个。{/ p>
我在ANTLR中嘲笑了一个似乎有效的语法。请注意,用于lineto_argument_sequence
的模式类似于我之前推荐的Jorn。
grammar SVG;
lineto_argument_sequence
: coordinate_pair (COMMA_WSP? coordinate_pair)*
;
coordinate_pair
: coordinate COMMA_WSP? coordinate
;
coordinate
: NUMBER
;
COMMA_WSP
: ( WS+|WS*','WS*) //{ $channel=HIDDEN; }
;
NUMBER
: '-'? (INT | FLOAT) ;
fragment
INT
: '0'..'9'+ ;
fragment
FLOAT
: ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
| '.' ('0'..'9')+ EXPONENT?
| ('0'..'9')+ EXPONENT
;
fragment
WS : ' ' | '\t' | '\r' | '\n' ;
fragment
EXPONENT
: ('e'|'E') ('+'|'-')? ('0'..'9')+ ;
给出以下输入:
2, 3 -3 -4 5.5.65.5.6
它生成这个解析树。
alt text http://www.freeimagehosting.net/uploads/85fc77bc3c.png
答案 2 :(得分:0)
是的,这两个语法描述的是同一种语言。
但这真的是EBNF吗? Wikipedia article on EBNF不包括Kleene星运算符。