我正在学习ANTLR4,我一度感到困惑。对于类似Java的语言,我正在尝试为成员链接等构造添加规则,类似于:
expr1.MethodCall(expr2).MethodCall(expr3);
我收到一个错误,说我的两条规则是相互左递归的:
expression
: literal
| variableReference
| LPAREN expression RPAREN
| statementExpression
| memberAccess
;
memberAccess: expression DOT (methodCall | fieldReference);
我认为我理解为什么上述规则组合被认为是左递归的:因为memberAccess
是expression
的候选者而memberAccess
以expression
开头。
然而,当我看到(通过查看the Java example)如果我只是将memberAccess
的内容移动到expression
时,我的理解就失败了,我没有从ANTLR4中获得任何错误(甚至虽然它仍然没有解析我想要的东西,但似乎陷入了一个循环):
expression
: literal
| variableReference
| LPAREN expression RPAREN
| statementExpression
| expression DOT (methodCall | fieldReference)
;
答案 0 :(得分:1)
第二个是左递归但不是相互左递归。 ANTLR4可以使用内置算法消除左递归规则。它不能消除相互留下的递归规则。可能存在一种算法,但这很难保留动作和语义谓词。
答案 1 :(得分:0)
出于某种原因,当我的语法出现左递归时,ANTLRWorks 2没有响应,导致我(错误地)认为我的语法错了。
从命令行进行编译和测试显示,具有立即左递归的版本实际上已正确编译和解析。
(我将此处留在此处以防其他人对IDE的行为感到困惑。)