从这个奇怪的表达式语法中消除左递归
Eliminating Left Recursion from this weird 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)*
然后错误就消除了。我很迷惑。需要一些帮助!
我对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)
时,我得到了这个解析树:
可能是 Xtext 使用的是旧版本的 Antlr。这是一个很棒的软件,但在旧版本中尤其不完美。根据标准定义,此文法不是左递归的。有可能 Antlr 正在将其转换为更简单的语法, 是 左递归,但这将是一个显然已修复的错误。
因此,如果我的猜测是正确的,您将成功使用以下显式 "simplified" 语法:
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 ;
新的解析树:
我正在尝试编写一个表达式语法,其中有 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)*
然后错误就消除了。我很迷惑。需要一些帮助!
我对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)
时,我得到了这个解析树:
可能是 Xtext 使用的是旧版本的 Antlr。这是一个很棒的软件,但在旧版本中尤其不完美。根据标准定义,此文法不是左递归的。有可能 Antlr 正在将其转换为更简单的语法, 是 左递归,但这将是一个显然已修复的错误。
因此,如果我的猜测是正确的,您将成功使用以下显式 "simplified" 语法:
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 ;
新的解析树: