a
into
the terminal id
S → S; S S → id := E S → print ( L ) E → id E → num E → E + E E → (S, E) L → E L → L, E
a := 7; b := c + (d := 5 + 6, d) $
S' → .S$ S → .x S → .(L)We call this state 1. Each state consists of a set of items where an item is one of the productions in the state.
S → x.This will lead to a reduction; more later
S → (.L)Thus the remaining string must be something derived from L, meaning we need to include all of the L productions and then all S productions; this gives state 3:
S → (.L) L → .L, S L → .S S → .(L) S → .x
S → S.$If a nonterminal followed the dot, would have to compute the closure of it as well.
Step | State | Action executed | Resulting stack (subscript: result state) |
---|---|---|---|
1 | 1 | Shift ( | 1(3 |
2 | 3 | Shift ( | 1(3(3 |
3 | 3 | Shift a (as x) | 1(3(3x2 |
4 | 2 | Reduce by 2. S → x | 1(3(3S |
5 | 3 | Goto 7 (state 3 on S) | 1(3(3S7 |
6 | 7 | Reduce by 3. L → S | 1(3(3L |
7 | 3 | Goto 5 (state 3 on L) | 1(3(3L5 |
8 | 5 | Shift ) | 1(3(3L5)6 |
9 | 6 | Reduce by 1. S → (L) | 1(3S |
10 | 3 | Goto 7 (state 3, on S) | 1(3S7 |
11 | 7 | Reduce by 3. L → S | 1(3L |
12 | 3 | Goto 5 (state 3, on L) | 1(3L5 |
13 | 5 | Shift ) | 1(3L5)6 |
14 | 6 | Reduce by 1. S → (L) | 1S |
15 | 1 | Goto 4 (state 1, on S) | 1S4 |
16 | 4 | Accept |
0) S' → S $ 3) E → V 1) S → V = E 4) V → x 2) S → E 5) V → * E
S → if E then S else S S → if E then S S → other
S → if E then S., else S → if E then S. else S, ?
nonterminal = sequence ;
assignment = identifier assign expression semicolon ;
3.30.grammar
P → L S → if id then S S → id := id S → if id then S else S S → while id do S L → S S → begin L end L → L ; S
shift/reduce conflict in state [stack: TIf TId TThen PStm *] on TElse in { [ PStm = TIf TId TThen PStm * TElse PStm ] (shift), [ PStm = TIf TId TThen PStm * ] followed by TElse (reduce) }
E → E + E E → E - E E → E * E E → E / E E → E && E E → E || E
E → E * E., + E → E. * E., ?
E → E + E., + E → E. + E., ?
x ** y ** z
%prec nonassoc equals, notequals; %prec left plus, minus; %prec left times, div; %prec right assign;
if ( x = 1 ) f(); else g();One could build this into the parser, but it's easier to just add code to check for such cases.