Content
- Shift-Reduce Parsing
- LR Parsing
- Table-Driven
- LR(0)
- Table Construction
- SLR(1)
- Table Construction
- LR(1)
- Table Construction
- LALR(1)
- Table Construction
- LR Parsing
Shift-Reduce Parsing
Handle: term to be replaced by non-terminal
LR Parsing
- Scanned from left to right (L)
- Rightmost derivation (R)
- Superset of
LL(1)
Table-Driven
Action[s,a]
: when state s
on top of stack, a
is next input token, what to do?Goto[s,X]
: when state s
on top of stack, a reduction to non-terminal X
, what's the new state?
If Action[st,a]
is reduce Y -> X1...Xk
, pop k
states off, leaving su
on top. Push new state Goto[su,Y]
onto stack. Input token unchanged.
LR(0)
Table Construction
- Let
F = {I0,I1,...,In}
be the collection of configurating sets for grammarG
Action[]
- If
A -> u•
inIi
&&A != S'
,Action[i,a] = reduce A -> u
for all input - If
S' -> S
inIi
,Action[i,$] = accept
- If
A -> u•av
inIi
&&successor(Ii,a) = Ij
,Action[i,a] = shift j
- If
Goto[]
- If
successor(Ii,A) = Ij
,Goto[i,A] = j
- If
- Else error
- Initial state
S' -> •S
Limitations
- Conflicts
- Shift-reduce conflict
A -> u•av
andB -> w•
cannot be in the same set
- Reduce-reduce conflict
- Only one
A -> u•
in the same set
- Only one
- Shift-reduce conflict
- Not many grammars meet the requirements
A -> •ε
: shift-reduce conflictT -> id[E]
:T -> id•
&T -> id•[E]
shift-reduce conflict
- Only consider what it has seen so far (no lookahead)
SLR(1)
Simple version of LR(1)
. Every SLR(1)
grammar is a LR(1)
grammar. Takes the least space.
- 1 symbol lookahead (1):
Follow()
- Avoid conflicts
- Shift-reduce conflict
A -> u•av
andB -> w•
cannot be in the same set ifa
inFollow(B)
- Reduce-reduce conflict
A -> u•
andB -> w•
in the same set only ifFollow(A) ∩ Follow(B) = ∅
- Shift-reduce conflict
Table Construction
- Let
F = {I0,I1,...,In}
be the collection of configurating sets for grammarG
Action[]
- If
A -> u•
inIi
&&A != S'
,Action[i,a] = reduce A -> u
for all a in Follow(A) - If
S' -> S
inIi
,Action[i,$] = accept
- If
A -> u•av
inIi
&&successor(Ii,a) = Ij
,Action[i,a] = shift j
- If
Goto[]
- If
successor(Ii,A) = Ij
,Goto[i,A] = j
- If
- Else error
- Initial state
S' -> •S
LR(1)
Canonical version of LR(1)
. Want's a smaller (more precise) set of lookahead symbols. Takes the most space.
- Expected lookahead symbols: a subset of
Follow()
- Only meaningful for reduction items
- Avoid conflicts happening from different contexts
- Shift-reduce conflict
A -> u•av, b
andB -> w•, a
cannot be in the same set
- Reduce-reduce conflict
A -> u•, a
andB -> w•, a
cannot be in the same set
- Shift-reduce conflict
- Splits states based on lookahead sets -> more states
- Worst case: the power set of
Follow()
containing all terminals
- Worst case: the power set of
Table Construction
- For transition
A -> u•av
toA -> ua•v
, propagate expected lookaheads - For
B -> •C
to be added as closure ofA -> u•Bv
which has expected lookaheadst,s,...
, addFirst(vt) ∪ First(vs) ∪ ...
to the expected lookaheads
I4
: parsing the firstX
;I7
: parsing the secondX
LALR(1)
Tradeoff version between SLR(1)
and LR(1)
. Number of states same as for SLR(1)
and LR(0)
. Subset of LR(1)
; superset of SLR(1)
.
- Reduce number of states from
LR(1)
A -> a, s1
andA -> a, s2
, combined intoA -> a, s3
wheres3 = s1 ∪ s2
- May have come conflicts unresolved
Conflicts
- Shift-reduce conflict won't exist unless it exists in
LR(1)
If reduce-reduce conflict, not
LALR(1)
C -> e, c B -> e, d merged with C -> e, d B -> e, c
- Shift-reduce conflict won't exist unless it exists in
Table Construction
- Brute force: merge sets of
LR(1)
- Step-by-step: merge as you go