Question

Can a LR(1) parser parse a grammar of this type?

S -> SA  | A
A -> aSb | ab

I'm trying to write a Java program that implements this type of parser, but I only get the right results on a grammars without left recursion.

Was it helpful?

Solution

LR(1) parsers can handle some types of left recursion, though not all left-recursive grammars are LR(1).

Let's see if your particular grammar is LR(1). Augmenting the grammar gives

S' → S

S → SA | A

A → aSb | ab

Our configurating sets are therefore

 (1)
 S' -> .S    [$]     (Go to 2)
 S  -> .SA   [$a]    (Go to 2)
 S  -> .A    [$a]    (Go to 3)
 A  -> .aSb  [$a]    (Shift on a and go to 4)
 A  -> .ab   [$a]    (Shift on a and go to 4)

 (2)
 S' -> S.    [$]     (Accept on $)
 S  -> S.A   [$a]    (Go to 3)
 A  -> .aSb  [$a]    (Shift on a and go to 4)
 A  -> .ab   [$a]    (Shift on a and go to 4)

 (3)
 S  -> A.    [$a]    (reduce on $ or a)

 (4)
 A  -> a.Sb  [$a]    (Go to 6)
 A  -> a.b   [$a]    (Shift on b and go to 10)
 S  -> .SA   [ab]    (Go to 11)
 S  -> .A    [ab]    (Go to 12)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (5)
 A  -> ab.   [$a]    (Reduce on a or $)

 (6)
 A  -> aS.b  [$a]    (Shift on b and go to 7)
 S  -> S.A   [ab]    (Go to 13)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (7)
 A  -> aSb.  [$a]    (Reduce on a or $)

 (8)
 A  -> a.Sb  [ab]    (Go to 14)
 A  -> a.b   [ab]    (Shift on b and go to 16)
 S  -> .SA   [ab]    (Go to 11)
 S  -> .A    [ab]    (Go to 12)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (9)
 S  -> SA.   [$a]    (Reduce on a or $)

 (10)
 A  -> ab.   [$a]    (Reduce on a or b)

 (11)
 S  -> S.A   [ab]    (Go to 13)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (12)
 S  -> A.    [ab]    (Reduce on a or b)

 (13)
 S  -> SA.   [ab]    (Reduce on a or b)

 (14)
 A  -> aS.b  [ab]    (Shift on b and go to 15)
 S  -> S.A   [ab]    (Go to 13)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)   

 (15)
 A  -> aSb.  [ab]    (Reduce on a or b)

 (16)
 A  -> ab.   [ab]    (Reduce on a or b)

There are no shift/reduce or reduce/reduce conflicts in this grammar, and so it should be LR(1) (unless I made a mistake somewhere!)

Hope this helps!

OTHER TIPS

Turns out it's also an SLR grammar, so LR is overkill. Instead of requiring 16 states with LR, only 10 states are needed with SLR.

(1)
 S' -> .S    S => (Go to 2)
 S  -> .SA   A => (Go to 3)
 S  -> .A    a => (Shift and go to 4)
 A  -> .aSb     
 A  -> .ab   

 (2)
 S' -> S.    $ => (Accept on $)
 S  -> S.A   A => (Go to 5)
 A  -> .aSb  a => (Shift and go to 6)
 A  -> .ab   

 (3)
 S  -> A.    [$b] => (reduce on $ or b)

 (4)
 A  -> a.Sb  S => (Go to 7)
 A  -> a.b   A => (Go to 9)
 S  -> .SA   a => (Shift and go to 6)
 S  -> .A    b => (Shift and go to 8)
 A  -> .aSb  
 A  -> .ab   

 (5)
 S  -> SA.   [$b] => (reduce on $ or b)

 (6)
 A  -> a.Sb  S => (Go to 7)
 A  -> a.b   A => (Go to 3)
 S  -> .SA   a => (Shift and go to 4)
 S  -> .A    b => (Shift and go to 8)
 A  -> .aSb  
 A  -> .ab   

 (7)
 A  -> aS.b  A => (Go to 5)
 S  -> S.A   a => (Shift and go to 6)
 A  -> .aSb  b => (Shift and go to 10)
 A  -> .ab   

 (8)
 A  -> ab.   [$b] => (reduce on $ or b)

 (9)
 S  -> A.    [$b] => (reduce on $ or b)

 (10)
 A  -> aSb.  [$b] => (reduce on $ or b)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top