Ch4b
Ch4b
Syntax Analysis
Part II
Chapter 4
Bottom-Up Parsing
• LR methods (Left-to-right, Rightmost
derivation)
– SLR, Canonical LR, LALR
• Other special cases:
– Shift-reduce parsing
– Operator-precedence parsing
3
Operator-Precedence Parsing
• Special case of shift-reduce parsing
• We will not further discuss (you can skip
textbook section 4.6)
4
Shift-Reduce Parsing
Grammar: Reducing a sentence: Shift-reduce corresponds
S → a A B e a b b c d e to a rightmost derivation:
A → A b c | b a A b c d e S ⇒rm a A B e
B → d
a A d e ⇒rm a A d e
a A B e ⇒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: a b b c d e
S → a A B e a A b c d e
A → A b c | b a A d e Handle
B → d
a A B e
S
a b b c d e
a A b c d e NOT a handle, because
a A A e further reductions will fail
… ?
(result is not a sentential form)
6
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 → A B
A → a
B → a
Resolve in favor
of reduce 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(1) 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 Parsing
Stack
Input
Action
$ 0 id*id+id$ shift 5
$ 0 id 5 *id+id$ reduce 6 goto 3
Grammar: $ 0 F 3 *id+id$ reduce 4 goto 2
$ 0 T 2 *id+id$ shift 7
1. E → E + T
$ 0 T 2 * 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 $ 0 T 2 +id$ reduce 2 goto 1
5. F → ( E ) $ 0 E 1 +id$ shift 6
$ 0 E 1 + 6 id$ shift 5
6. F → id
$ 0 E 1 + 6 id 5 $ reduce 6 goto 3
$ 0 E 1 + 6 F 3 $ reduce 4 goto 9
$ 0 E 1 + 6 T 9 $ reduce 1 goto 1
$ 0 E 1
$
accept
21
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 $
22
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
24
Suppose I =
{ [E’ → • E] Then goto(I,E)
[E → • E + T] = closure({[E’ → E •, E → E • + T]})
[E → • T] =
{ [E’ → E •]
[T → • T * F] [E → E • + T] }
[T → • F]
[F → • ( E )]
[F → • id] }
Grammar:
E → E + T | T
T → T * F | F
F → ( E )
F → id
31
goto(I0,a)
State I3: State I5:
A → a•
B → a•
33
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]
36
1.
S → L = R
lookahead=$
2.
S → R S → L•=R
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=
37
LR(1) Items
• An LR(1) item
[A→α•β, a]
contains a lookahead terminal a, meaning α
already on top of the stack, expect to see βa
• For items of the form
[A→α•, a]
the lookahead a is used to reduce A→α only if the
next input is a
• For items of the form
[A→α•β, a]
with β≠ε the lookahead has no effect
38
I1:
[S’ → S•,
$] I8:
[R → L•,
=/$]
I2:
[S → L•=R,
$] goto(I0,=)=I6 I9:
[S → L=R•,
$]
[R → L•,
$]
I10:
[R → L•,
$]
I3:
[S → R•,
$]
I11:
[L → *•R,
$] goto(I11,R)=I13
I4:
[L → *•R,
=/$] goto(I4,R)=I7 [R → •L,
$] goto(I11,L)=I10
[R → •L,
=/$] goto(I4,L)=I8 [L → •*R,
$] goto(I11,*)=I11
[L → •*R,
=/$] goto(I4,*)=I4 [L → •id,
$] goto(I11,id)=I12
[L → •id,
=/$] goto(I4,id)=I5
I12:
[L → id•,
$]
I5:
[L → id•,
=/$]
I13:
[L → *R•,
$]
43
LALR(1) Grammars
• LR(1) parsing tables have many states
• LALR(1) parsing (Look-Ahead LR) combines two
or more LR(1) sets into one 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
46
I1:
[S’ → S•,
$] I8:
[S → L=R•,
$]
I2:
[S → L•=R,
$] goto(I0,=)=I6 I9:
[R → L•,
=/$]
[R → L•,
$]
Shorthand
I3:
[S → R•,
$]
for two items
I4:
[L → *•R,
=/$] goto(I4,R)=I7 [R → L•,
=]
[R → •L,
=/$] goto(I4,L)=I9 [R → L•,
$]
[L → •*R,
=/$] goto(I4,*)=I4
[L → •id,
=/$] goto(I4,id)=I5
I5:
[L → id•,
=/$]
49
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
50
LR(1)
LALR(1)
LL(1)
SLR
LR(0)
52
stack
input
$ 0
id*id+id$
S’ → E
E → E + E …
…
E → E * E $ 0 E 1 * 3 E 5
+id$
reduce E → E * E
E → id
≈
≈
≈
54