如何阅读EBNF语法中的替换项

时间:2010-06-20 20:16:13

标签: grammar ebnf alternate

我有一个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)*

3 个答案:

答案 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星运算符。