Académique Documents
Professionnel Documents
Culture Documents
Bottom Up Parser
By
Debi Prasad Behera,
Lecturer, Dept of CSEA,
Silicon Institute of Technology, Bhubaneswar
Bottom-Up Parsing
A bottom-up parser creates the parse tree of the given input starting
from leaves towards the root.
A bottom-up parser tries to find the right-most derivation of the given
input in the reverse order.
S ... (the right-most derivation of )
(the bottom-up parser finds the right-most derivation in the reverse order)
Shift-Reduce Parsing
A shift-reduce parser tries to reduce the given input string into the starting symbol.
a string
reduced to
At each reduction step, a substring of the input matching to the right side of a
production rule is replaced by the non-terminal at the left side of that production rule.
If the substring is chosen correctly, the right most derivation of that string is created in
the reverse order.
Rightmost Derivation:
Shift-Reduce Parser finds:
*
S
rm
rm
rm
... S
reduction
S rm
aABb
aaAbb
rm aAbb rm
rm aaabb
Right Sentential Forms
How do we know which substring to be replaced at each reduction step?
4
Handle
Informally, a handle of a string is a substring that matches the right side
of a production rule.
But not every substring matches the right side of a production rule is handle
S rm
A
rm
If the grammar is unambiguous, then every right-sentential form of the
grammar has exactly one handle.
We will see that is a string of terminals.
5
Handle Pruning
A right-most derivation in reverse can be obtained by handle-pruning.
S=0
rm 1
rm 2
rm ...
rm n-1
rm n=
input string
Start from n, find a handle Ann in n,
and replace n in by An to get n-1.
Then find a handle An-1n-1 in n-1,
replace n-1 in by An-1 to get n-2.
Repeat this, until we reach S.
and
A Shift-Reduce Parser
E E+T | T
T T*F | F
F (E) | id
Input
Action
$
$id
$F
$T
$E
$E+
$E+id
$E+F
$E+T
$E+T*
$E+T*id
$E+T*F
$E+T
$E
id+id*id$shift
+id*id$
+id*id$
+id*id$
+id*id$
id*id$
*id$
*id$
*id$
id$
$
$
$
$
reduce by F id
reduce by T F
reduce by E T
shift
shift
reduce by F id
reduce by T F
shift
shift
reduce by F id
reduce by T T*F
reduce by E E+T
accept
Parse Tree
E 8
E 3
T 7
T 2
T 5
F 1
F 4
id
id
F6
id
right-most
derivation
k lookhead
Shift-Reduce Parsers
1. Operator-Precedence Parser
2. LR-Parsers
SLR
11
Operator-Precedence Parser
Operator grammar
small, but an important class of grammars
we may have an efficient operator precedence parser (a shift-reduce
parser) for an operator grammar.
In an operator grammar, no production rule can have:
at the right side
two adjacent non-terminals at the right side.
Ex:
EAB
Aa
Bb
not operator grammar
EEOE
Eid
O+|*|/
not operator grammar
EE+E |
E*E |
E/E | id
operator grammar
12
Precedence Relations
In operator-precedence parsing, we define three disjoint precedence
relations between certain pairs of terminals.
a <. b
a = b
a .> b
13
14
id
id
>
>
>
<.
>
<.
>
<.
>
>
>
<.
<.
<.
Then the input string id+id*id with the precedence relations inserted
will be:
$ <. id .> + <. id .> * <. id .> $
15
E id
E id
E id
E E*E
E E+E
$ id + id * id $
$ E + id * id $
$ E + E * id $
$ E + E * .E $
$E+E$
$E$
16
The input string is w$, the initial stack is $ and a table holds precedence relations between
certain terminals
Algorithm:
set p to point to the first symbol of w$ ;
repeat forever
if ( $ is on top of the stack and p points to $ ) then return
else {
let a be the topmost terminal symbol on the stack and let b be the symbol pointed to by p;
if ( a <. b or a = b ) then {
/* SHIFT */
push b onto the stack;
advance p to the next input symbol;
}
else if ( a .> b ) then /* REDUCE */
repeat pop stack
until ( the top of stack terminal is related by <. to the terminal most recently popped );
else error();
}
17
action
$
$id
$
$+
$+id
$+
$+*
$+*id
$+*
$+
$
$ <. id
id .> +
shift
shift
id .> *
shift
shift
id .> $
* .> $
+ .> $
accept
id+id*id$
+id*id$
+id*id$
id*id$
*id$
*id$
id$
$
$
$
$
shift
reduce E id
reduce E id
reduce E id
reduce E E*E
reduce E E+E
18
1.
2.
3.
4.
Also, let
(=)
( <. (
( <. id
$ <. (
$ <. id
(<. O,
O .> ),
id .> )
id .> $
) .> O,
they
they are right-
O <.
) .> $
) .> )
19
Operator-Precedence Relations
+
id
>
>
<.
<.
<.
<.
<.
>
>
>
>
<.
<.
<.
<.
<.
>
>
>
>
>
>
<.
<.
<.
>
>
>
>
>
>
<.
<.
<.
>
>
>
>
>
>
<.
<.
<.
>
>
id
>
>
>
>
>
>
<.
<.
<.
<.
<.
>
>
>
>
>
<.
<.
<.
<.
<.
>
<.
<.
>
=
.
<.
>
<.
20
Then, we make
O <. unary-minus
unary-minus .> O
unary-minus <. O
21
Operator-Precedance Grammars
Let G be an -free operator grammar(No -Production).For each
terminal symbols a and b, the following conditions are satisfies.
1. ab, if a production in RHS of the form ab, where is either or a single
non Terminal. Ex SiCtSeS implies i t and t e.
2.
22
Last terminal
*, +, ), id
*, +, (, id
*, (, id
*, ), id
(, id
), id
id $
> <.
>
> <.
> <.
>
>
>
>
>
id .>
>
>
>
>
<.
23
24
Precedence Functions
Compilers using operator precedence parsers do not need to store the
table of precedence relations.
The table can be encoded by two precedence functions f and g that map
terminal symbols to integers.
For symbols a and b.
f(a) < g(b)
whenever a <. b
f(a) = g(b)
whenever a = b
f(a) > g(b)
whenever a .> b
25
26
27
LR Parsers
The most powerful shift-reduce parsing (yet efficient) is:
LR(k) parsing.
left to right
scanning
right-most
derivation
k lookhead
(k is omitted it is 1)
28
LR Parsers
LR-Parsers
covers wide range of grammars.
SLR simple LR parser
LR most general LR parser
LALR intermediate LR parser (look-head LR parser)
SLR, LR and LALR work same (they used the same algorithm),
only their parsing tables are different.
29
LR Parsing Algorithm
input a1
... ai
... an
stack
Sm
Xm
LR Parsing Algorithm
Sm-1
output
Xm-1
.
Action Table
.
S1
X1
S0
s
t
a
t
e
s
terminals and $
four different
actions
Goto Table
s
t
a
t
e
s
non-terminal
each item is
a state number
30
Rest of Input
Actions of A LR-Parser
1. shift s -- shifts the next input symbol and the state s onto the stack
( So X1 S1 ... Xm Sm, ai ai+1 ... an $ ) ( So X1 S1 ... Xm Sm ai s, ai+1 ... an $ )
32
Reduce Action
pop 2|| (=r) items from the stack; let us assume that = Y1Y2...Yr
then push A and s where s=goto[sm-r,A]
( So X1 S1 ... Xm-r Sm-r Y1 Sm-r ...Yr Sm, ai ai+1 ... an $ )
( So X1 S1 ... Xm-r Sm-r A s, ai ... an $ )
In fact, Y1Y2...Yr is a handle.
X1 ... Xm-r A ai ... an $ X1 ... Xm Y1...Yr ai ai+1 ... an $
33
E E+T
ET
T T*F
TF
F (E)
F id
state
id
s5
Goto Table
)
s4
s6
r2
s7
r2
r2
r4
r4
r4
r4
s4
r6
acc
s5
r6
r6
s5
s4
s5
s4
r6
10
s6
s11
r1
s7
r1
r1
10
r3
r3
r3
r3
11
r5
r5
r5
r5
34
input
id*id+id$
*id+id$
*id+id$
*id+id$
id+id$
+id$
+id$
+id$
+id$
id$
$
$
$
$
action
shift 5
reduce by Fid
reduce by TF
shift 7
shift 5
reduce by Fid
reduce by TT*F
reduce by ET
shift 6
shift 5
reduce by Fid
reduce by TF
reduce by EE+T
accept
output
Fid
TF
Fid
TT*F
ET
Fid
TF
EE+T
35
..
Sets of LR(0) items will be the states of action and goto table of the SLR
parser.
A collection of sets of LR(0) items (the canonical LR(0) collection) is
the basis for constructing SLR parsers.
Augmented Grammar:
G is G with a new production rule SS where S is the new starting
symbol.
36
..
37
closure({E E}) =
{ E E
E E+T
E T
T T*F
T F
F (E)
F id }
.
.
.
.
.
.
.
kernel items
38
Goto Operation
If I is a set of LR(0) items and X is a grammar symbol (terminal or nonterminal),
then goto(I,X) is defined as follows:
If A X in I
then every item in closure({A X }) will be in goto(I,X).
Example:
.. .. .
. .. .
.. .
.. .. . .
.
I ={ E E, E E+T, E T,
T T*F, T F,
F (E), F id }
goto(I,E) = { E E , E E +T }
goto(I,T) = { E T , T T *F }
goto(I,F) = {T F }
goto(I,() = { F ( E), E E+T, E
F (E), F id }
goto(I,id) = { F id }
T, T
T*F, T
F,
39
C is { closure({S S}) }
repeat the followings until no more set of LR(0) items can be added to C.
for each I in C and each grammar symbol X
if goto(I,X) is not empty and not in C
add goto(I,X) to C
40
I9: E E+T.
E .E+T
E E.+T
T .T*F
T T.*F
E .T
T .F
T .T*F
I2: E T.
F .(E)
I10: T T*F.
T .F
T T.*F
F .id
F .(E)
F .id
I3: T F. I7: T T*.F
F .(E)
I4: F (.E)
E .E+T
E .T
T .T*F
T .F
F .(E)
F .id
I11: F (E).
F .id
I8: F (E.)
E E.+T
I5: F id.
41
I1
I6
T
F
(
id
I2
I7
I3
id Iid
4
I5
T
F
(
I8
to I2
to I3
to I4
to I7
F
(
id
I9
to I3
to I4
to I5
)
+
I10
to I4
to I5
I11
to I6
42
43
id
s5
Goto Table
)
s4
s6
r2
s7
r2
r2
r4
r4
r4
r4
s4
r6
acc
s5
r6
r6
s5
s4
s5
s4
r6
10
s6
s11
r1
s7
r1
r1
10
r3
r3
r3
r3
11
r5
r5
r5
r5
44
SLR(1) Grammar
An LR parser using SLR(1) parsing tables for a grammar G is called as
the SLR(1) parser for G.
If a grammar G has an SLR(1) parsing table, it is called SLR(1)
grammar (or SLR grammar in short).
Every SLR grammar is unambiguous, but every unambiguous grammar
is not a SLR grammar.
45
46
Conflict Example
S L=R
I0: S .S
SR
L *R
S .L=R
S .R
L id
RL
L .*R
L .id
R .L
I1:S S.
I2:S L.=R
R .L
L .*R
R L.
L .id
I9: S L=R.
I3:S R.
I4:L *.R
Problem
FOLLOW(R)={=,$}
R .L
L .*R
L .id
shift 6
reduce by R L
shift/reduce conflict
I6:S L=.R
I7:L *R.
I8:R L.
I5:L id.
47
Conflict Example2
S AaAb
I0: S .S
S BbBa
A
B
Problem
FOLLOW(A)={a,b}
FOLLOW(B)={a,b}
a
reduce by A
reduce by B
reduce/reduce conflict
S .AaAb
S .BbBa
A.
B.
reduce by A
reduce by B
reduce/reduce conflict
b
48
SAaAbAabab
SBbBaBbaba
Aab ab
AaAb Aa b
Bba ba
BbBa Bb a
49
LR(1) Item
To avoid some of invalid reductions, the states need to carry more
information.
Extra information is put into a state by including a terminal symbol as a
second component in an item.
A LR(1) item is:
A ,a
50
.
...
A .,a
51
52
goto operation
If I is a set of LR(1) items and X is a grammar symbol
(terminal or non-terminal), then goto(I,X) is defined as
follows:
If A .X,a in I
then every item in closure({A X.,a}) will be
in goto(I,X).
53
54
.
...
A .,a
can be written as
A ,a1/a2/.../an
55
I0: S .S ,$
S BbBa
A
S .AaAb ,$
S .BbBa ,$
A . ,a
B . ,b
I4: S Aa.Ab ,$
I6: S AaA.b ,$
I1: S S. ,$
S
A
B
I2: S A.aAb ,$
I3: S B.bBa ,$
a
b
to I4
to I5
I8: S AaAb. ,$
A . ,b
I5: S Bb.Ba ,$
I7: S BbB.a ,$
I9: S BbBa. ,$
B . ,a
56
I0:S .S,$
I6:S L=.R,$
R .L,$
L .*R,$
L .id,$
I7:L *R.,$/=
I8: R L.,$/=
S .L=R,$
S .R,$
L .*R,$/=
L .id,$/=
R .L,$
R
L
*
id
I1:S S.,$
S
*
L I2:S L.=R,$
R L.,$
R
I3:S R.,$
to I6
id
I4:L *.R,$/=
R .L,$/=
L .*R,$/=
L .id,$/=
to I7
L
*
to I8
I5:L id.,$/=
I9:S L=R.,$
to I9
to I10
to I11
to I12
I12:L id.,$
to I4
to I5
I13:L *R.,$
I10:R L.,$
I11:L *.R,$
R .L,$
L .*R,$
L .id,$
id
I4 and I11
R
L
*
id
to I13
to I10
to I11
to I12
I5 and I12
I7 and I13
I8 and I10
57
2. Create
the parsing action table as follows
If any conflicting actions generated by these rules, the grammar is not LR(1).
.
.
id
s5
s4
1
s6
10
r5
s5
s4
r4
s12
r4
s11
r3
r3
r5
r5
r1
10
r5
11
r2
5
6
acc
2
4
s12
s11
r4
13
r3
12
no shift/reduce or
no reduce/reduce conflict
13
59
60
shrink # of states
LALR Parser
61
..
..
The core of a set of LR(1) items is the set of its first component.
Ex:
S L =R,$
S L =R
Core
R L ,$
RL
We will find the states (sets of LR(1) items) in a canonical LR(1) parser with same
cores. Then we will merge them as a single state.
.
.
I1:L id ,=
I2:L id ,$
A new state:
.
.
I12: L id ,=
L id ,$
We will do this for all states of a canonical LR(1) parser to get the states of the LALR
parser.
In fact, the number of the states of the LALR parser for a grammar will be equal to the
number of states of the SLR parser for that grammar.
62
Shift/Reduce Conflict
We say that we cannot introduce a shift/reduce conflict during the
shrink process for the creation of the states of a LALR parser.
Assume that we can introduce a shift/reduce conflict. In this case, a
state of LALR parser must have:
A ,a
and
B a,b
.
.
.
.
This means that a state of the canonical LR(1) parser must have:
A ,a
and
B a,c
But, this state has also a shift/reduce conflict. i.e. The original canonical
LR(1) parser has a conflict.
(Reason for this, the shift operation does not depend on lookaheads)
64
Reduce/Reduce Conflict
But, we may introduce a reduce/reduce conflict during the shrink
process for the creation of the states of a LALR parser.
.
.
I1 : A ,a
B ,b
.
.
I2: A ,b
B ,c
.
.
I12: A ,a/b
B ,b/c
reduce/reduce conflict
65
.
..
.
.
.
I0:S
S
S
L
L
R
I6:S L= R,$
R L,$
L *R,$
L id,$
I713:L *R ,$/=
I810: R L ,$/=
.
.
.
.
.
.
R
L
*
id
S,$
L=R,$
R,$
*R,$/=
id,$/=
L,$
to I9
to I810
to I411
to I512
.
..
.
I1:S S ,$
S
*
I :S L =R,$
L2
R L ,$
R
I3:S R ,$
id
.
.
.
.
.
I411:L * R,$/=
R L,$/=
L *R,$/=
to I6
L id,$/=
I9:S L=R ,$
to I713
L
*
to I810
id
I512:L id ,$/=
to I411
to I512
Same Cores
I4 and I11
I5 and I12
I7 and I13
I8 and I10
66
id
s5
s4
1
s6
10
r5
s5
s4
r4
s12
r4
s11
r3
r3
r5
r5
r2
5
6
acc
2
4
no shift/reduce or
no reduce/reduce conflict
r1
67
Ex.
E E+T | T
E E+E | E*E | (E) | id
T T*F | F
F (E) | id
68
..E+E
E
..E*E
(E)
.id
..
.
I1: E E
E E +E
E E *E
..E+E
E)
..E*E
(E)
.id
I 2: E (
E
E
E
E
id
id
I3: E id
.
..
..
I : E E *.E
E .E+E
E .E*E
E .(E)
E .id
I4: E E + E
E E+E
E E*E
*
E (E)
E id
E
(
id
..
.
I6: E (E )
E E +E
E E *E
I2
I3
(
id
.
..
I7: E E+E + I
4
E E +E *
I5
E E *E
E
I2
I3
)
+
* I4
I5
.
..
I8: E E*E + I
4
E E +E *
I5
E E *E
I9: E (E)
69
I1
I4
I7
I1
I5
I7
s3
1
2
Action
+
*
s2
s4
s5
s3
acc
s2
r4
Goto
E
r4
6
r4
r4
s3
s2
s3
s2
s4
s5
s9
r1
s5
r1
r1
r2
r2
r2
r2
r3
r3
r3
r3
72
The parser stacks the nonterminal A and the state goto[s,A], and it
resumes the normal parsing.
This nonterminal A is normally is a basic programming block (there can
be more than one choice for A).
stmt, expr, block, ...
74
75