为什么这是左递归的,我该如何解决?

Why is this left-recursive and how do I fix it?

我正在学习 ANTLR4,我一度感到困惑。对于类似 Java 的语言,我正在尝试为成员链等结构添加规则,类似的东西:

expr1.MethodCall(expr2).MethodCall(expr3);

我收到一个错误,说我的两个规则是相互左递归的:

expression
    : literal
    | variableReference
    | LPAREN expression RPAREN
    | statementExpression
    | memberAccess
    ;

memberAccess: expression DOT (methodCall | fieldReference);

我想我理解了为什么上面的规则组合被认为是左递归的:因为 memberAccessexpression 的候选者并且 memberAccessexpression 开头。

然而,当我看到(通过查看 the Java example)如果我只是将 memberAccess 的内容移动到 expression 时,我的理解就崩溃了,我没有从 ANTLR4 中得到任何错误(即使它仍然没有解析我想要的,似乎陷入了循环):

expression
    : literal
    | variableReference
    | LPAREN expression RPAREN
    | statementExpression
    | expression DOT (methodCall | fieldReference)
    ;
  1. 为什么第一个示例是左递归的而第二个不是?
  2. 我需要做什么才能真正解析初始行?

第二个是左递归但不是互左递归。 ANTLR4 可以使用内置算法消除左递归规则。它不能消除互左递归规则。可能存在一种算法,但这很难保留动作和语义谓词。

出于某种原因,当我的语法有左递归时 ANTLRWorks 2 没有响应,导致我(错误地)认为我的语法是错误的。

从命令行编译和测试表明,具有直接左递归的版本实际上可以正确编译和解析。

(我把它留在这里以防其他人对 IDE 的行为感到困惑。)