Question

I'm trying to make my own LR(0) parser, and I'm running into trouble with some grammars.

Basically, for the grammar

exp:  mexp
mexp: '1'
mexp: mexp '*' '1'

my parser is outputting

State 0: • 1
       | • mexp
       | • exp
       | • mexp * 1
State 1: 1 •
State 2: exp •
State 3: mexp • * 1
       | mexp •
State 4: mexp * • 1
State 5: mexp * 1 •

with the warning

(state 3, *) already has reduction:  exp: mexp

The LR(0) table my program derived for this grammar is:

         '1' exp mexp '*'    $
State 0:  s1  s2   s3         
State 1:  r3           r3   r3
State 2:                   acc
State 3:  r2           s4   r2
State 4:  s5                 
State 5:  r4           r4   r4

where $ denotes the end of file.

The warning stems from the fact that state 3 -- which corresponds to mexp • * 1 | mexp • -- has both a reduction r2 and a state transition s4 for the input *.

But it seems like according to Wikipedia, this should not be happening -- I should only have reductions:

If an item set i contains an item of the form A → w • and A → w is rule m with m > 0 then the row for state i in the action table is completely filled with the reduce action rm.

The funny thing is, when I remove the rule exp: mexp, I don't get any such conflicts.

So what I'm having trouble figuring out is, is this indeed a genuine problem in the grammar?
(In other words, is this grammar not, in fact, LR(0)?)
I don't believe this to be the case but I'm not sure.

If so, why? And if not, then what's wrong? (Is my table wrong, or am I doing something else incorrectly?)

Was it helpful?

Solution

(After reading that Wikipedia page more carefully.)

The Wikipeda quote is (emphasis added):

If an item set i contains an item of the form A → w • and A → w is rule m with m > 0 then the row for state i in the action table is completely filled with the reduce action rm.

Rule 0 is the augmented start rule, which in your case should be:

start : mexp '$'

(Personally, I prefer adding the EOF token explicitly; there are fewer exceptions that way.)

However, what you've got, I think, is:

start : exp '$'
exp   : mexp

which actually isn't LR(0), because the unit reduction rule ( exp → mexp ) leads to the shift-reduce conflict you discovered.

The Wikipedia article's exception for m = 0 would be unnecessary if the rule were written with an explicit end-marker; in this case, the action acc is generated according to modified action 3:

  1. An extra column for '$' (end of input) is added to the action table that contains acc for every item set that contains S → E • '$'.

(Actually, you don't need the "extra column" part; with an explicit end-marker you should already have a column for it. The point is to override the shift action with an acc action.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top