关于ANTLR中左递归的错误。现在需要做什么?

时间:2017-07-05 17:25:10

标签: recursion antlr antlr4

//Expression

exp: exp1 ASS_OP exp | exp1;

exp1: exp1 OR_OP exp2 | exp2;

exp2: exp2 AND_OP exp3 | exp3;

exp3: exp4 (EQUAL_OP | NOT_EQUAL_OP) exp4 | exp4;

exp4: exp5 (LESS_OP|GREATER_OP|LESS_EQUAL_OP|GREATER_EQUAL_OP) exp5 | exp5;

exp5: exp5 (ADD_OP | SUB_OP) exp6 | exp6;

exp6: exp6 (MUL_OP | DIV_OP | MOD_OP) exp7 | exp7;

exp7: (ADD_OP | SUB_OP | NOT_OP) exp7 | exp8;

exp8: LB exp RB | expl;

expl: invocation_exp | index_exp | ID | INTLIT |FLOATLIT | BOOLEANLIT | STRINGLIT;

index_exp: exp LSB exp RSB;

invocation_exp: ID LB (exp (COMMA exp)*)? RB;

[error] error(119):MC.g4 :::以下几组规则是相互左递归的[exp,index_exp,exp1,exp2,exp3,exp4,exp5,exp6,exp7,exp8,expl]

[trace]抑制堆栈跟踪:run last *:Antlr为完整输出生成词法分析器和解析器。

你好,我是新人。我读了一些主题,以便ANTLR4只支持直接左递归。作者似乎不想改变这一点。所以任何人都可以帮我修改我的代码?感谢您阅读本文。

1 个答案:

答案 0 :(得分:1)

与一些较旧的工具相比,ANTLR4的一大优点是,您通常不必像这样“链接”您的运算符优先级:

exp: exp1 ASS_OP exp | exp1;
exp1: exp1 OR_OP exp2 | exp2;
exp2: exp2 AND_OP exp3 | exp3;

我记得那些为严格的BNF语法链接表达规则的日子。但是在ANTLR4中,我们可以做得更好,也有更清晰的语法。由于规则是从上到下进行评估的,因此首先列出了最高层次的规则,如下面的代码段所示:

expr
 : expr POW<assoc=right> expr           #powExpr
 | MINUS expr                           #unaryMinusExpr
 | NOT expr                             #notExpr
 | expr op=(MULT | DIV | MOD) expr      #multiplicationExpr
 | expr op=(PLUS | MINUS) expr          #additiveExpr
 | expr op=(LTEQ | GTEQ | LT | GT) expr #relationalExpr
 | expr op=(EQ | NEQ) expr              #equalityExpr
 | expr AND expr                        #andExpr
 | expr OR expr                         #orExpr
 | atom                                 #atomExpr

这可以解决您的运算符优先级问题,而不会与相互左递归争论。在顶部具有最高优先级,在此示例中具有幂(取幂)(并且通过数学约定)在表达式中具有最高绑定。