Syntax Analysis 2
Syntax Analysis 2
Syntax Analysis
Part II
2
Bottom-Up Parsing
• LR methods (Left-to-right, Rightmost
derivation)
– SLR, Canonical LR, LALR
• Other special cases:
– Shift-reduce parsing
– Operator-precedence parsing
3
Shift-Reduce Parsing
Grammar:
S→aABe
A→Abc|b
B→d
w=a b b c d e
4
Shift-Reduce Parsing
Grammar: Reducing a sentence: Shift-reduce corresponds
S→aABe abbcde to a rightmost derivation:
A→Abc|b aAbcde S rm a A B e
B→d aAde rm a A d e
aABe rm a A b c d e
These match S rm a b b c d e
production’s
right-hand sides
S
A A A
A A A B A B
a b b c d e a b b c d e a b b c d e a b b c d e
5
Handles
A handle is a substring of grammar symbols in a
right-sentential form that matches a right-hand side
of a production
Grammar: abbcde
S→aABe aAbcde
A→Abc|b aAde Handle
B→d aABe
S
abbcde
aAbcde NOT a handle, because
aAAe further reductions will fail
…? (result is not a sentential form)
6
Stack Implementation of
Shift-Reduce Parsing
Stack Input Action
$ id+id*id$ shift
$id +id*id$ reduce E → id How to
Grammar: $E +id*id$ shift
$E+ id*id$ shift
resolve
E→E+E conflicts?
$E+id *id$ reduce E → id
E→E*E $E+E *id$ shift (or reduce?)
E→(E) $E+E* id$ shift
E → id $E+E*id $ reduce E → id
$E+E*E $ reduce E → E * E
$E+E $ reduce E → E + E
Found handles $E $ accept
to reduce
7
Conflicts
• Shift-reduce and reduce-reduce conflicts are
caused by
– The limitations of the LR parsing method (even
when the grammar is unambiguous)
– Ambiguity of the grammar
8
Shift-Reduce Parsing:
Shift-Reduce Conflicts
Stack Input Action
$… …$ …
$…if E then S else…$ shift or reduce?
Ambiguous grammar:
S → if E then S
| if E then S else S
| other
Resolve in favor
of shift, so else
matches closest if
9
Shift-Reduce Parsing:
Reduce-Reduce Conflicts
Stack Input Action
$ aa$ shift
$a a$ reduce A → a or B → a ?
Grammar:
C→AB
A→a
B→a
Resolve in favor
of reducing A → a,
otherwise we’re stuck!
10
Model of an LR Parser
input a1 a2 … ai … an $
stack
LR Parsing Program
sm (driver) output
Xm
sm-1
Xm-1 action goto Constructed with
… LR(0) method,
shift DFA SLR method,
s0 reduce LR(1) method, or
accept LALR method
error
18
LR Parsing (Driver)
Configuration ( = LR parser state):
(s0 X1 s1 X2 s2 … Xm sm, ai ai+1 … an $)
stack input
If action[sm,ai] = shift s then push ai, push s, and advance input:
(s0 X1 s1 X2 s2 … Xm sm ai s, ai+1 … an $)
Example LR Shift-Reduce
Parsing
Stack Input Action
$0 id*id+id$ shift 5
$ 0 id 5 *id+id$ reduce 6 goto 3
Grammar: $0F3 *id+id$ reduce 4 goto 2
1. E → E + T $0T2 *id+id$ shift 7
$0T2*7 id+id$ shift 5
2. E → T $ 0 T 2 * 7 id 5 +id$ reduce 6 goto 10
3. T → T * F $ 0 T 2 * 7 F 10 +id$ reduce 3 goto 2
4. T → F $0T2 +id$ reduce 2 goto 1
5. F → ( E ) $0E1 +id$ shift 6
6. F → id $0E1+6 id$ shift 5
$ 0 E 1 + 6 id 5 $ reduce 6 goto 3
$0E1+6F3 $ reduce 4 goto 9
$0E1+6T9 $ reduce 1 goto 1
$0E1 $ accept
23
SLR Grammars
• SLR (Simple LR): SLR is a simple
extension of LR(0) shift-reduce parsing
• SLR eliminates some conflicts by
populating the parsing table with reductions
A→ on symbols in FOLLOW(A)
Shift on +
State I2:
State I0:
S → •E goto(I0,id) E → id•+ E goto(I3,+)
S→E
E → id•
E → id + E E → •id + E
E → id E → •id FOLLOW(E)={$}
thus reduce on $
24
SLR Parsing
• An LR(0) state is a set of LR(0) items
• An LR(0) item is a production with a • (dot) in the
right-hand side
• Build the LR(0) DFA by
– Closure operation to construct LR(0) items
– Goto operation to determine transitions
• Construct the SLR parsing table from the DFA
• LR parser program uses the SLR parsing table to
determine shift/reduce operations
26
LR(1) Grammars
• SLR too simple
• LR(1) parsing uses lookahead to avoid
unnecessary conflicts in parsing table
• LR(1) item = LR(0) item + lookahead
LR(0) item: LR(1) item:
[A→•] [A→•, a]
42
1. S → L = R
2. S → R S → L•=R
lookahead=$
R → L•
3. L → * R
4. L → id
action[2,=]=s6 action[2,$]=r5
5. R → L
Should not reduce on =, because no
right-sentential form begins with R=
43
LR(1) Items
• An LR(1) item
[A→•, a]
contains a lookahead terminal a, meaning
already on top of the stack, expect to parse a
• For items of the form
[A→•, a]
the lookahead a is used to reduce A→ only if the
next lookahead of the input is a
• For items of the form
[A→•, a]
with the lookahead has no effect
44
Grammar: 3 r3
1. S’ → S 4 s5 s4 8 7
2. S → L = R 5 r5 r5
3. S → R 6 s12 s11 10 9
4. L → * R 7 r4 r4
5. L → id 8 r6 r6
6. R → L 9 r2
10 r6
11 s12 s11 10 13
12 r5
13 r4
58
LALR Parsing
• LR(1) parsing tables have many states
• LALR parsing (Look-Ahead LR) merges two or
more LR(1) state into one state to reduce table size
• Less powerful than LR(1)
– Will not introduce shift-reduce conflicts, because shifts
do not use lookaheads
– May introduce reduce-reduce conflicts, but seldom do
so for grammars of programming languages
59
id * = $ S L R
0 s5 s4 1 2 3
Grammar: 1 acc
1. S’ → S 2 s6 r6
2. S → L = R 3 r3
3. S → R 4 s5 s4 9 7
4. L → * R 5 r5 r5
5. L → id 6 s5 s4 9 8
6. R → L 7 r4 r4
8 r2
9 r6 r6
63
LR(1)
LALR
LL(1) SLR
LR(0)
65
stack input
$0 id*id+id$
S’ → E
E→E+E … …
E→E*E $0E1*3E5 +id$ reduce E → E * E
E → id
67