从这个奇怪的表达语法中消除左递归

时间:2017-07-01 01:17:57

标签: parsing grammar left-recursion

我正在尝试编写一个Expression Grammar,其中有3个运算符'+',' - '和'/'。乘法运算符由并置隐含,如:

(1+2)(3+4 5)

这是语法:

S -> A ('+' A)*

A -> B ('-' B)*

B -> C ('/' C)*

C -> D ( D )*

D ->ID
    |Num
    |'(' S ')'

我正在使用Xtext,它使用ANTLR解析器,它说这在规则C上是递归的。如果我要将规则4更改为

C -> D ('\*' D)*

然后消除错误。我很迷惑。想要一些帮助!

1 个答案:

答案 0 :(得分:1)

我对Xtext一无所知,但Antlr 4对这个语法没有任何问题:

grammar Expr; 
s: a ('+' a)* ;
a: b ('-' b)* ;
b: c ('/' c)* ;
c: d ( d )* ;
d: ID | NUM |'(' s ')' ;
ID: [a-z][a-z0-9]* ;
NUM: [0-9]+ ;
WS: [ \t\r\n]+ -> skip ;

当我编译并运行您的示例(1+2)(3+4 5)时,我得到了这个解析树: parse tree

可能是Xtext正在使用旧版本的Antlr。它是一个很好的软件,但在旧版本中,它并不完美。该语法不是标准定义的左递归。可能Antlr正在将其转换为 左递归的更简单的语法,但这将是一个明显被修复的错误。

因此,如果我的猜测是正确的,那么您将明确地成功使用以下内容"简化"语法:

grammar Expr; 
s: a ap ;
ap: '+' a ap | /* eps */ ;
a: b bp ;
bp: '-' b bp | /* eps */ ;
b: c cp ;
cp: '/' c cp | /* eps */ ;
c: d dp ;
dp: d dp | ;
d: ID | NUM |'(' s ')' ;
ID: [a-z][a-z0-9]* ;
NUM: [0-9]+ ;
WS: [ \t\r\n]+ -> skip ;

新的解析树:new parse tree