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

时间:2015-04-01 13:40:56

标签: antlr4 left-recursion

我正在学习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. 我需要做些什么来实际解析初始行?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

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

从命令行进行编译和测试显示,具有立即左递归的版本实际上已正确编译和解析。

(我将此处留在此处以防其他人对IDE的行为感到困惑。)