1

So I have some grammar that doesn't work for a top-down parser due to it having left recursion:

L::= A a | B b
A::= L b | a a
B::= b B b | b a

So in order to fix this, I have to remove the left recursion. To do this, I do a little substitute-like-thing:

L::= A a | B b
A::= A a b | B b b | a a (I plugged in the possible values of "L")

A then turns to (I believe):

A::= a a A' | B b b
A'::= a b A' | ε

I'm fairly certain that I'm correct up to there (wouldn't be surprised if I'm not, though). Where I'm struggling is now removing the left recursion out of "B b b". I've tried going about this so many ways, and I don't think any of them work. Here's one that seems most logical, but ugly as well (thus saying it's probably wrong). Starting by manipulating B::= b B b | b a

B::= b B b | b a
B::= b B' (they both start with b, so maybe i can pull it out?)
B'::= B b | a
B'::= b B' b | a (substituted B's value in)
B'::= b B" | a
B"::= b B" |a B" | ε

So I guess to show what the finalized B's would be:

B::= b B'
B'::= b B" | a
B"::= b B" | a B" | ε

This seems way too ugly to be correct. Especially since I'd have to plug that into the new "A" terminals that I created.

Can someone help me out? No idea if I'm going about this the right way. I'm supposed to be able to create an LL(1) parse table afterward (should be able to do that part on my own).

Thanks.

user2869231
  • 1,431
  • 5
  • 24
  • 53
  • Looking at this again, I might not actually have to plug the new B into the newly created A o.O The "B::=b B b | b a" does still need to have the recursion fixed, though. – user2869231 Feb 13 '14 at 05:25
  • Do you need to remove the `B b b`? I don't think it counts as left recursion, since `B` can't expand to anything with an `A` or `B` on the left. [Wikipedia's definition](http://en.wikipedia.org/wiki/Left_recursion) seems to indicate that it's not a problem. – user2357112 Feb 13 '14 at 05:26
  • that's the part i'm saying I probably don't have to change. However, if you go down to the original "B::= b B b | b a", I'm pretty sure THAT needs changed – user2869231 Feb 13 '14 at 05:29
  • Why would that need to be changed? It doesn't even have a nonterminal on the left in any of the productions. – user2357112 Feb 13 '14 at 05:30
  • quite simply because I thought it did... being in the middle makes it to the left of the b though. so yeah, it's not all the way to the left, but how would "B::= B b" be different from "B::= b B b" when it comes to needing to remove the recursion – user2869231 Feb 13 '14 at 05:41

1 Answers1

0

In a parser that tries to expand nonterminals from the left, if some nonterminal can expand to a string with itself on the left, the parser may expand that nonterminal forever without actually parsing anything. This is left recursion. On the other hand, it is perfectly fine if a nonterminal expands to a string with some different nonterminal on the left, as long as no chain of expansions produces a string with the original nonterminal on the left. Similarly, it is fine if nonterminals aren't all the way to the right in the expansion, as long as they're not all the way to the left.

tl;dr There's nothing wrong with B b b or b B b. You've removed all the left recursion. You don't need to keep going.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • well.. that sounds fantastic! hehe and good to know; I actually went into this knowing very little so that definitely helps. Thanks! – user2869231 Feb 13 '14 at 06:09