[antlr-interest] newbie Q: infinite recursion in grammar
Chris Rebert
cvrebert at gmail.com
Thu Sep 7 17:16:38 PDT 2006
Darn. Hmmm. In that case, could someone point me to a parser (if any)
that could parse this?
Or does anyone else have some advice? I really would like to stick with
ANTLR if possible.
Thanks.
- Chris R.
Kay Roepke wrote:
> Hi Chris!
>
> On 7. Sep 2006, at 6:54 Uhr, Chris Rebert wrote:
>
>> "infinite recursion to rule expr from rule $some_grammar_production"
>>
>> when running ANTLR on it.
>> I think this has something to do with precedence in my grammar.
>
> Actually, it has to do with the (non-immediate) left recursion involving
> expr and type.
> I didn't check for other left recursion, but the same principle applies.
>
> If you've got the Dragon Book (Compilers - Principles, Techniques, and
> Tools by Aho et al) check out
> Chapter 2.4 Heading "Left Recursion", Chapter 2.5 and Chapter 4.3
> "Elimination of Left Recursion". If you don't, get it ;)
> (Or look for those terms on Google, there should be a lot of material
> available.)
> Anyway, here's the gist of it:
>
> If you've got a rule like
> expr : expr "+" term | term;
> it is left-recursive and cannot be recognized by a LL recursive-descent
> parser like ANTLR. This is because
> expr would end up calling itself, being on the left edge of the rule,
> endlessly and eventually you'd run out of
> stack space.
> A solution to this is to restructure like this:
> expr : term expr_dash;
> expr_dash : "+" term expr_dash | /* empty */;
> or alternatively without recursion:
> expr : term ("+" term)*
> The problem with it is that + will not be left-associative anymore, but
> instead right-associative, if you generate trees.
> Big Pain here. But you could stick the action inside the ("+" term)*
> loop and calculate the value like this (as an example to achieve
> left-associativity, a bit contrived, but still ;) ):
> expr : t:term {sum = $t.somehowGetValueHere(); }("+" t1:term { sum
> += $t1.somehowGetValueHere();})*
>
> In your case, you have the really nasty case of indirect left-recursion,
> in that it takes a couple rule invocations to complete
> for the recursion to appear.
> This, naturally, is a bit more difficult to solve. I'm not gonna write
> down the algorithm here, since it is available on the net (and I'm
> a lazy SOB and have a serious lack of coffee :)) See
> http://web.cs.wpi.edu/~kal/courses/compilers/module2/mytopdown.html (at
> the end of
> Section 2.1.2) for an example. This just popped out of Google, I'm sure
> there are better presentations to be found (maybe even at wikipedia
> *shudder*).
>
>> I couldn't find any way to set the precedence of grammar rules like I
>> can in yacc in the docs.
>> If it's not possible to set precedence in this way, could someone advise
>> me (roughly) as to how I need to restructure my grammar?
>
> As I outlined above, precedence in LL-grammars is determined with the
> direction of recursion (right-recursion yields right-associativity).
> There is no mechanism to spell out precendence rules like in bison/yacc.
> Since left-recursion isn't possible, you'll have to hack around it
> (unless Ter has a really smart idea *wink* ;))
>
> Somehow this got more verbose than I intended it to be, but maybe it
> will help and is not completely wrong, considering the aforementioned lack
> of fuel, err, coffee.
>
> Good morning :),
>
> -k
> --Kay Röpke <kroepke at classdump.org>
> classdump Software
> Key fingerprint = A849 0F2C C322 4022 379E 8661 7E1B FE0D 4CD2 A6D0
>
>
>
>
More information about the antlr-interest
mailing list