Search code examples
antlr4left-recursionmutual-recursion

ANTLR4 self and mutual left-recursion


Is there a simple transformation or workaround to make this work in ANTLR4?

a : a p
  | b q
  | c
  ;

b : b r
  | a s
  | d
  ;

That is, a and b are self-left-recursive and mutual-left-recursive, the other rules (c, d, p, q, r, s) are just placeholders for simple rules.


Solution

  • Firstly, remove direct left recursion from both rules. Let's consider the rule a:

    a
        : (b q | c) p+
        | b q
        | c
        ;
    

    Simplify:

    a
        : (b q | c) p*
        ;
    

    Do a similar transformation for the rule b:

    b
        : (a s | d) r*
        ;
    

    Now it's possible to replace b identifier in rule a with the body of rule b:

    a
        : (c | (a s | d) r* q) p*
        ;
    

    Or to replace a identifier in rule b with the body of rule a:

    b
        : ((b q | c) p* s | d) r*
        ;
    

    It's also possible to get rid of direct left recursion if needed.