[antlr-interest] Improvements to left recursive grammars

Oliver Zeigermann oliver.zeigermann at gmail.com
Fri Jan 6 15:43:22 PST 2012


Really, really cool and to my big surprise it actually does work :P

Nervously awaiting context labels to be able to have different
callbacks/contexts for each alternative of e.g.

expr
: '(' e=expr ')' -> parenExpr
| left=expr (op='*'|op='/') right=expr -> opExpr
| left=expr (op='+'|op='-') right=expr -> opExpr
| atom -> atomExpr
;

FYI: Tried to figure out how to generate custom heterogeneous ASTs,
and do not think one should use parse trees/callbacks as a starting
point. One should rather create them directly in the grammar, like
e.g.

expr returns [Expression expr]
: '(' e=expr ')' { $expr = $e.expr; }
| left=expr (op='*'|op='/') right=expr
  { $expr = new Operation($op.text, $left.expr, $right.expr); }
| left=expr (op='+'|op='-') right=expr
  { $expr = new Operation($op.text, $left.expr, $right.expr); }
| atom { $expr = $atom.expr; }
;

Thoughts on this?

- Oliver

2012/1/6 Terence Parr <parrt at cs.usfca.edu>:
> Howdy. Ok,These left recursive grammar rules are craaaazy. Now they behave
> just as you would expect regular rules. For example, you could have return
> values and actions (on the right edge). The cool thing is you can label the
> left recursive rule references (a=e) even though those disappear in the
> implementation. :)
>
>     s : e {System.out.println($e.v);} ;
>     e returns [int v]
>       : a=e '*' b=e {$v = $a.v * $b.v;}
>       | a=e '+' b=e {$v = $a.v + $b.v;}
>       | INT         {$v = $INT.int;}
>       | '(' x=e ')' {$v = $x.v;}
>       ;
>
> For example, I passed an input 1+2*3 and got the following parse tree
>
> (s (e (e 1) + (e (e 2) * (e 3))))
>
> just like you would get if this were a bottom-up tool. Moreover, it fires
> exit rule events as you would expect. you will see something like this, if
> you pass in a listener that prints out the ctx. see the example page.
>
> exit 1: (e 1)
> exit 1: (e 2)
> exit 1: (e 3)
> exit 1: (e (e 2) * (e 3))
> exit 1: (e (e 1) + (e (e 2) * (e 3)))
> 7
> exit 0: (s (e (e 1) + (e (e 2) * (e 3))))
>
> just pushed to the website dist directory. also updated this page:
>
> http://www.antlr.org/wiki/display/ANTLR4/Examples
>
> see
>
> http://antlr.org/depot/antlr4/main/CHANGES.txt
>
> Ter
>


More information about the antlr-interest mailing list