Search code examples
antlr4left-recursion

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


I'm learning ANTLR4 and I'm confused at one point. For a Java-like language, I'm trying to add rules for constructs like member chaining, something like that:

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

I'm getting an error, saying that two of my rules are mutually left-recursive:

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

memberAccess: expression DOT (methodCall | fieldReference);

I thought I understood why the above rule combination is considered left-recursive: because memberAccess is a candidate of expression and memberAccess starts with an expression.

However, my understanding broke down when I saw (by looking at the Java example) that if I just move the contents of memberAccess to expression, I got no errors from ANTLR4 (even though it still doesn't parse what I want, seems to fall into a loop):

expression
    : literal
    | variableReference
    | LPAREN expression RPAREN
    | statementExpression
    | expression DOT (methodCall | fieldReference)
    ;
  1. Why is the first example left-recursive but the second isn't?
  2. And what do I have to do to actually parse the initial line?

Solution

  • The second is left-recursive but not mutually left recursive. ANTLR4 can eliminate left-recursive rules with an inbuilt algorithm. It cannot eliminate mutually left recursive rules. There probably exists an algorithm, but this would hardly preserve actions and semantic predicates.