Module 4

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 55

AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

AUTOMATA THEORY
AND COMPILER
DESIGN- 21CS51

Dr. Sampada K S, Associate Professor


DEPT. OF CSE | RNSIT

DR. SAMPADA K S, CSE, RNSIT 1


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

MODULE 4
Push Down Automata: Definition of the Pushdown Automata, The Languages of a PDA.

Syntax Analysis Phase of Compilers: Part-2: Bottom-up Parsing, Introduction to LR Parsing: SLR,
More Powerful LR parsers

PART 1: INTRODUCTION TO PUSH DOWN AUTOMATA


Just as finite-state automata correspond to regular languages, the context-free languages (CFL) have
corresponding machines called pushdown automata (PDA).

Regular expressions are generators for regular languages and Finite Automata’s are recognizers for them.
Similarly for Context-free Languages, Context Free Grammars (CFG) are generators and Pushdown
Automata (PDA) are recognizers.

PDA is more powerful than FA. An FA cannot recognize the language a nbn, n 0, because FA does not
have any memory to remember the number of a’s it has already seen, for equating with number of b’s
found. PDA is NFA with an added memory. Stack functions as the required memory. So, a PDA is an
NFA with a stack. Figure 1 shows a diagrammatic representation of PDA. The Finite State Control (FSC)
reads inputs, one symbol at a time. Based on the input symbol, current state and the top symbol on the
stack, FSC does some state transitions and does some operations to the stack content. Stack could be kept
unchanged, or something could be pushed into the stack and could be popped out of the stack.

Input Tape

Finite State Control


stack

Figure 1: Push Down Automaton

Formal Definition:

DR. SAMPADA K S, CSE, RNSIT 2


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
A nondeterministic pushdown automaton or npda is a 7-tuple M = (Q, , , , q0, z, F), where
Q is a finite set of states,

 is a the input alphabet,


 is the stack alphabet,

 is a transition function, has the form


: Q X ( {}) X   finite subsets of Q X *

q0 Q is the initial state,


z   is the stack start symbol, and
F  Q is a set of final states.

Transition function: for any given state, input symbol and stack symbol, gives a new state and stack
symbol; i.e. it has the form: (P, a, t)  (Q, u)

Basically, if, a  , t   and P and Q are states. Means “read the symbol ‘a’ from the input, move from
state P to state Q, and replace the symbol ‘t’ on top of the stack with the symbol ‘u’ ”.

If u = t, then stack is unchanged.

If u = , then stack is popped

If u= wx, then t is replaced with x and w is pushed into the stack.

Example 1:

Construct PDA for the language L= {a nbn | a, b  Σ n  0}.

Start at state q0 and keep Z0 in the stack. The following transitions are possible:

1. If current state is q0, and symbol on input tape is at , and stack top is Z0, then move to q2 the final
state.
2. If current state is q0, and input tape symbol is a, and stack top Z0, then stay in q0 and push ‘a’ to the
stack.
3. If current state is q0, input tape symbol is ‘a’, and stack top is a, stay in q 0 and push ‘a’ to the stack.
4. If current state is q0, input tape symbol is b, stack top is a, move to state q 1 and pop the top symbol of
the stack.

DR. SAMPADA K S, CSE, RNSIT 3


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

5. If current state is q1, input tape symbol is b, stack top is a, stay in q 1 and pop the top symbol of the
stack
6. If current state is q1, input tape symbol is  and stack top is Z0, move to q2 the final state.
So we can define PDA as M = ({q0, q1, q2}, {a, b}, {a, b, Z0}, δ, q0, Z0, {q2}), where δ is defined by
following rules:

δ(q0, a, Z0) = {(q0, aZ0)}

δ(q0, a, a) = {(q0, aa)}

δ(q0, b, a) = {(q1, )}

δ(q1, b, a) = {(q1, )}

δ(q1, , Z0) = {(q2, )}

δ(q0, , Z0) = {(q2, )}

δ(q,x,Y) =  for all other possibilities

Graphical Notation of PDA:

To understand the behavior or PDA clearer, the transition diagram of PDA can be used. Transition
diagram of PDA is generalization of transition diagram of FA.

1. Node corresponds to states of PDA


2. Arrow labeled Start indicates start state
3. Doubly circled states are final states
4. Arc corresponds to transitions of PDA. If δ(q, a, X) = {(p, )…} is an arc labeled (a, X/) from state
q to state p means that an input tape head positioned at symbol a and stack top with X, moves
automaton to state q and replaces the stack top with .
The transition diagram for the above example PDA is given in Figure 2.

a, Z0/aZ0 b,a/ 
a,a/aa
DR. SAMPADA K S, CSE, RNSIT 4

b,a/  , Z0 / 
Start q0 q1 q2

, Z / 
AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

Instantaneous Description: Instantaneous Description or configuration of a PDA describes its execution


status at any time. Instantaneous Description is a represented by a triplet (q, w, u), where

1. q is the current state of the automaton,


2. w is the unread part of the input string, w  Σ*
3. u is the stack contents, written as a string, with the leftmost symbol at the top of the stack. So u  Γ*

Moves of A PDA:
Let the symbol "|-" indicates a move of the nPDA. There are two types of moves possible for a PDA.
Move by consuming input symbol
Suppose that (q1, a, x) = {(q2, y), ...}. Then the following move by consuming an input symbol is
possible:

(q1, aW, xZ) |- (q2, W, yZ),

where W indicates the rest of the input string following the a, and Z indicates the rest of the stack contents
underneath the x. This notation says that in moving from state q 1 to state q2, an input symbol ‘a’ is
consumed from the input string aW, and the symbol ‘x’ at the top (left) of the stack xZ is replaced with
symbol ‘y’, leaving yZ on the stack.

The above example PDA with a few example input strings, the moves are given below:

a) Moves for the input string aabb:

(q0, aabb, Z0) |- (q0, abb, aZ0) as per transition rule δ(q0, a, Z0) = {(q0, aZ0)}

|- (q0, bb, aaZ0) as per transition rule δ(q0, a, a) = {(q0, aa)}

|- (q1, b, aZ0) as per transition rule δ(q0, b, a) = {(q1, )}

DR. SAMPADA K S, CSE, RNSIT 5


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

|- (q1, , Z0) as per transition rule δ(q0, b, a) = {(q1, )}

|- (q2, ,) as per transition rule δ(q1, , Z0) = {(q2, )}

PDA reached a configuration of (q2, ,). The input tape is empty, stack is empty and PDA has reached a
final state. So the string is accepted.

b) Moves for the input string aaabb:

(q0, aaabb, Z0) |- (q0, aabb, aZ0) as per transition rule δ(q0, a, Z0) = {(q0, aZ0)}

|- (q0, abb, aaZ0) as per transition rule δ(q0, a, a) = {(q0, aa)}

|- (q0, bb, aaaZ0) as per transition rule δ(q0, a, a) = {(q0, aa)}

|- (q1, b, aaZ0) as per transition rule δ(q0, b, a) = {(q1, )}

|- (q1, , aZ0) as per transition rule δ(q0, b, a) = {(q1, )}

|- There is no defined move.

So the automaton stops and the string is not accepted.

c) Moves for the input string aabbb:

(q0, aabbb, Z0) |- (q0, abbb, aZ0) as per transition rule δ(q0, a, Z0) = {(q0, aZ0)}

|- (q0, bbb, aaZ0) as per transition rule δ(q0, a, a) = {(q0, aa)}

|- (q1, bb, aZ0) as per transition rule δ(q0, b, a) = {(q1, )}

|- (q1, b, Z0) as per transition rule δ(q0, b, a) = {(q1, )}

|- There is no defined move.

So the automaton stops and the string is not accepted.

1. - move

DR. SAMPADA K S, CSE, RNSIT 6


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

Suppose that (q1, , x) = {(q2, y), ...}. Then the following move without consuming an input symbol is
possible:

(q1, aW, xZ) |- (q2, aW, yZ),

This notation says that in moving from state q1 to state q2, an input symbol ‘a’ is not consumed from the
input string aW, and the symbol ‘x’ at the top (left) of the stack xZ is replaced with symbol ‘y’, leaving
yZ on the stack. In this move, the tape head position will not move forward. This move is usually used to
represent non-determinism.

The relation |-* is the reflexive-transitive closure of |- used to represent zero or more moves of PDA. For
the above example, (q0, aabb, Z0) |-* (q2, ,).

Example 2: Design a PDA to accept the set of all strings of 0’s and 1’s such that no prefix has more 1’s
than 0’s.

Solution: The transition diagram could be given as figure 3.

Figure 3: Transition diagram


M = ({a, b, c, d}, {0,1}, {0,1,Z}, , a, Z, {d}), where  is given by:

 (a, 0, Z) ={(b, 0Z)}

 (b, 0, 0) ={(b, 00)}


 (b, 1, 0) ={(c, )}

 (c, 0, 0) ={(b, 00)}

 (c, 1, 0) ={(c, )}

 (b, , 0) ={(d, 0)}

DR. SAMPADA K S, CSE, RNSIT 7


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

 (b, , Z) ={(d, Z)}

 (c, 0, Z) ={(b, 0Z)}

 (c, , 0) ={(d, 0)}

 (c, , Z) ={(d, Z)}

For all other moves, PDA stops.

Moves for the input string 0010110 is given by:

(a, 0010110, Z) |- (b, 010110, 0Z) |- (b,10110, 00Z) |- (c, 0110, 0Z) |- (b, 110, 00Z) |-

(c, 10, 0Z) |- (c, 0, Z) |- (b, , 0Z) |- (d, , 0Z).

So the input string is accepted by the PDA.

Moves for 011

(a,011,Z) |- (b,11,0Z) |- (c,1,Z) |-no move, so PDA stops

Exercises:

Construct PDA:

1. For the language L = {wcwR | w  {a, b}*, c  Σ }


2. Accepting the set of all strings over {a, b} with equal number of a’s and b’s. Show the moves for
abbaba
3. For the language L = {anb2n | a, b  Σ, n  0}
4. Accepting the language of balanced parentheses, (consider any type of parentheses)

DR. SAMPADA K S, CSE, RNSIT 8


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

Languages of PDA
1. Languages of PDA
There are 2 ways of accepting an input string PDA
a. Accept by Final state
After consuming the input, PDA enters a final state. The content of the stack is irrelevant.
b. Accept by empty stack
After consuming the input, stack of the PDA will be empty. The current state could be final or
non-final state.
Both methods are equivalent. It is possible to covert a PDA accept by final state to another PDA accept
by empty stack and also the vice versa. Usually the languages that a PDA accept by final state and PDA
by empty stack are different. For example the language {L = anbm | n  m}, the appropriate PDA could
be by final state. After consuming the input, the stack may not be empty.

Accept by Final state:

Let P = (Q, Σ, Γ, δ, q0, Z0, F) be a PDA. Then L(P), the language accepted by P by the final state is

{w | (q0, w, Z0) |-* (q, , )}, where q  F and   Γ*

Example: L = {wwR | w is in (0 + 1)*}, the language for even length palindrome. Acceptable input
strings are like 00, 1111, 0110, 101101, and 110011. In the string 0110, the difficulty is how to decide the
middle of the input string? The 3rd 1 can be part of w or can be part of w R. The PDA could be
constructed as below.

M = ({q0, q1, q2}, {0, 1}, {0, 1,Z0}, δ, q0, Z0, q2), where δ is defined by:

δ(q0, 0, Z0) = {(q0, 0Z0)}

δ(q0, 1, Z0) = {(q0, 1Z0)}

δ(q0, 0, 0) = {(q0, 00)}

δ(q0, 1, 1) = {(q0, 11)}

δ(q0, 0, 1) = {(q0, 01)}

δ(q0, 1, 0) = {(q0, 10)}

DR. SAMPADA K S, CSE, RNSIT 9


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
δ(q0, , Z0) = {(q1, Z0)}

δ(q0, , 0) = {(q1, 0)}

δ(q0, , 1) = {(q1, 1)}

δ(q1, 0, 0) = {(q1, )}

δ(q1, 1, 1) = {(q1, )}

δ(q1, , Z0) = {(q2, Z0)}

(q0, wwR, Z0) |-* (q0, wR, wRZ0) |- (q1, wR, wRZ0) |-* (q1, , Z0) |- (q2, , Z0)

The transition diagram for the PDA is given in figure 1.


0,0/ 
0, Z0/0Z0 1,1/ 
1, Z0/1Z0
0,0/00
1,1/11 ,0/0
0,1/ 01 ,1/1
1,0/ 10 , Z0/ Z0
q0 q1 q2
, Z0 / Z0

Figure 1: Transition Diagram for L = {wwR}

The moves of the PDA for the input string 101101 are given figure 2.

DR. SAMPADA K S, CSE, RNSIT 10


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

Figure 2: moves of PDA for string 101101

Accept by empty stack:

Let PDA P = (Q, Σ, Γ, δ, q0, Z0). We define the language accepted by empty stack by

N(P) = {w | (q0, w, Z0) |-* (q, , )}, where q  Q

Example: Construct PDA to accept by empty stack for the language L = {ww R | w is in (0 + 1)*}

Instead of the transition δ(q1, , Z0) = {(q2, Z0)} give δ(q1, , Z0) = {(q2, )} to get accept by empty
stack. The set of accepting states are irrelevant. This example also shows that L(P) = N(P)
j
Example: Construct PDA to accept by empty stack for the language L={0i1 | 0  i  j}

The transition diagram for the PDA is given in Figure 3.

DR. SAMPADA K S, CSE, RNSIT 11


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

0, 0/00
1, Z0/Z0
0, Z0/0Z0 1, 0/
1,Z0/Z0 1, Z0/Z0
1, 0/ , Z0/Z0 ,Z0/
s p q r
, Z0/Z0
j
Figure 3: transition diagram of 0i1 | 0  i  j

2. Conversion between the two forms:


a. From Empty Stack to Final State:

Theorem: If L = N(PN) for some PDA PN= (Q, Σ, Γ , δN, q0, Z0), then there is a PDA PF such that L =
L(PF)

PN
Proof: , X0/Z0X0
p0 q0

, X0/
(add this transition from all states of PN to
new state Pf)
Pf
Figure 4: PF simulates PN
The method of conversion is given in figure 4.

We use a new symbol X0, which must be not symbol of Γ to denote the stack start symbol for P F. Also
add a new start state p0 and final state pf for PF. Let PF = (Q{p0, pf}, Σ, Γ{X0}, δF, p0, X0, {Pf}),
where δF is defined by

δF(p0, , X0) = {(q0, Z0 X0)} to push X0 to the bottom of the stack

δF(q, a, y) = δN(q, a, y) a  Σ or a =  and y  Γ, same for both PN and PF.

δF(q, , X0) = {(Pf, )} to accept the string by moving to final state.

The moves of PF to accept a string w can be written like:

(p0, w, X0) |-PF (p0, w, Z0X0) |-*PF (q, , X0) |- (Pf , ,  )

DR. SAMPADA K S, CSE, RNSIT 12


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

b. From Final State to Empty Stack:

Theorem: If L = L(PF) for some PDA P F= (Q, Σ, Γ, δF, q0, Z0, F), then there is a PDA PN such that L =
N(PN)

PF
Proof: , X0/Z0X0
p0 q0
, /
, /

p , /

Figure 5: PN simulates PF

The method of conversion is given in figure 5.

To avoid P F accidentally empting its stack, initially change the stack start content from Z 0 to Z0X0. Also
add a new start state p0 and final state p for PN. Let PN = (Q{p0, p}, Σ, Γ{X0}, δN, p0, X0), where
δN is defined by:

δN(p0, , X0) = {(q0, Z0X0)} to change the stack content initially

δN(q , a, y) = δF(q , a, y), a  Σ or a =  and y  Γ, same for both

δN(q , , y) = {(p , )}, q  F, y  Γ or y = X0 , same for both

δN(p , , y) = {(p, )}, y  Γ or y = X0, to pop the remaining stack contents. .

The moves of PN to accept a string w can be written like:

(p0, w, X0) |-PN (q0, w, Z0X0) |-*PN (q, , X0) |- (p, ,  )

Example:

Construct PDA to accept by final state the language of all strings of 0’s and 1’s such that number of 1’s is
less than number of 0’s. Also convert the PDA to accept by empty stack.
Solution:

DR. SAMPADA K S, CSE, RNSIT 13


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

PDA by final state is given byM = ({q0, q1}, {0, 1}, {0, 1,Z}, δ, q0, Z, {q1}), where δ is given by:

δ(q0, 0, Z) = {(q0, 0Z)}

δ(q0, 1, Z) = {(q0, 1Z)}

δ(q0, 0, 0) = {(q0, 00)}

δ(q0, 0,1) = {(q0, )}

δ(q0, 1, 1) = {(q0, 11)}

δ(q0, 1,0) = {(q0, )}

δ(q0, ,Z) = {(q1, Z)}

δ(q0, ,0) = {(q1, 0)}

For all other moves, PDA stops.

PDA by empty stack is given by M = ({q0, q1, q2}, {0, 1}, {0, 1, Z}, δ’, q0, Z), where δ’ is the union of δ and
the transitions given below:
δ(q1, ,Z) = {(q2, )}

δ(q1, ,0) = {(q2, )}

δ(q2, ,0) = {(q2, )}

δ(q2, ,Z) = {(q2, )}

Exercises:

Design nPDA to accept the language:

1. {aibjck | i, j, k  0 and i = j or i = k}
2. {aibjci+j | i, j  0}
3. {aibi+jcj | i  0, j  1}

DR. SAMPADA K S, CSE, RNSIT 14


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 15


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 16


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 17


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 18


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 19


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 20


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 21


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 22


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 23


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 24


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 25


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 26


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 27


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 28


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 29


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 30


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 31


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 32


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 33


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 34


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 35


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

PART 2: Syntax Analysis Phase of Compilers: Part-2:


Bottom-Up Parsing
1 Reductions
2 Handle Pruning
3 Shift-Reduce Parsing
4 Conflicts During Shift-Reduce Parsing
A bottom-up parse corresponds to the construction of a parse tree for an input string beginning at the
leaves (the bottom) and working up towards the root (the top). It is convenient to describe parsing as the
process of building parse trees, although a front end may in fact carry out a translation directly without
building an explicit tree. The sequence of tree snapshots in Fig. 4.25 illustrates

bottom-up parse of the token stream id * id, with respect to the expression grammar
This section introduces a general style of bottom-up parsing known as shift-reduce parsing.

1. Reductions
We can think of bottom-up parsing as the process of "reducing" a string w to the start symbol of the
grammar. At each reduction step, a specific substring matching the body of a production is replaced by
the nonterminal at the head of that production.
The key decisions during bottom-up parsing are about when to reduce and about what production to
apply, as the parse proceeds.
Example 4.37 : The snapshots in Fig. 4.25 illustrate a sequence of reductions; the grammar is the
expression grammar (4.1). The reductions will be discussed in terms of the sequence of strings
id * id, F * i d , T * i d , T*F, T, E

DR. SAMPADA K S, CSE, RNSIT 36


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
The strings in this sequence are formed from the roots of all the subtrees in the snapshots. The sequence
starts with the input string id*id . The first reduction produces F*id by reducing the leftmost id to F,
Using the production F ->• id. The second reduction produces T * id by reducing F to T.
Now, we have a choice between reducing the string T, which is the body of E -> T, and the string
consisting of the second id, which is the body of F -)• id. Rather than reduce T to E, the second id is
reduced to T, resulting in the string T * F. This string then reduces to T. The parse completes with the
reduction of T to the start symbol E. •
By definition, a reduction is the reverse of a step in a derivation (recall that in a derivation, a
nonterminal in a sentential form is replaced by the body of one of its productions). The goal of bottom-
up parsing is therefore to construct a derivation in reverse. The following derivation corresponds to the
parse in Fig. 4.25:
E => T =>• T * F T * id => F * id i d * id
This derivation is in fact a rightmost derivation.

2. Handle Pruning
Bottom-up parsing during a left-to-right scan of the input constructs a rightmost derivation in reverse.
Informally, a "handle" is a substring that matches the body of a production, and whose reduction
represents one step along the reverse of a rightmost derivation.
For example, adding subscripts to the tokens id for clarity, the handles during the parse of idi * i d 2
according to the expression grammar (4.1) are as in Fig. 4.26. Although T is the body of the production
E -» T, the symbol T is not a handle i n the sentential form T * id 2 . I f T were indeed replaced b y E ,
we would get the string E * i d 2 , which cannot be derived from the start symbol E. Thus, the leftmost
substring that matches the body of some production need not be a handle.

DR. SAMPADA K S, CSE, RNSIT 37


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
Notice that the string w to the right of the handle must contain only terminal symbols. For convenience,
we refer to the body b rather than A -> b as a handle. Note we say "a handle" rather than "the handle,"
because the grammar could be ambiguous, with more than one rightmost derivation of abw. If a
grammar is unambiguous, then every right-sentential form of the grammar has exactly one handle.
A rightmost derivation in reverse can be obtained by "handle pruning." That is, we start with a string of
terminals w to be parsed. If ID is a sentence

3. Shift-Reduce Parsing
Shift-reduce parsing is a form of bottom-up parsing in which a stack holds grammar symbols and an
input buffer holds the rest of the string to be parsed.
As we shall see, the handle always appears at the top of the stack just before it is identified as the
handle.
We use $ to mark the bottom of the stack and also the right end of the input. Conventionally, when
discussing bottom-up parsing, we show the top of the stack on the right, rather than on the left as we did
for top-down parsing.

DR. SAMPADA K S, CSE, RNSIT 38


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
Initially, the stack is empty, and the string w is on the input, as follows:

During a left-to-right scan of the input string, the parser shifts zero or more input symbols onto the stack,
until it is ready to reduce a string /3 of grammar symbols on top of the stack. It then reduces (3 to the
head of the appropriate production. The parser repeats this cycle until it has detected an error or until the
stack contains the start symbol and the input is empty:

Upon entering this configuration, the parser halts and announces successful completion of parsing.
Figure 4.28 steps through the actions a shift-reduce parser might take in parsing the input string idi *icl2
according to the expression grammar (4.1).

While the primary operations are shift and reduce, there are actually four possible actions a shift-reduce
parser can make: (1) shift, (2) reduce, (3) accept, and (4) error.
1. Shift. Shift the next input symbol onto the top of the stack.
2. Reduce. The right end of the string to be reduced must be at the top of the stack. Locate the left end
of the string within the stack and decide with what nonterminal to replace the string.
3. Accept. Announce successful completion of parsing.
4. Error. Discover a syntax error and call an error recovery routine.

DR. SAMPADA K S, CSE, RNSIT 39


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
The use of a stack in shift-reduce parsing is justified by an important fact: the handle will always
eventually appear on top of the stack, never inside. This fact can be shown by considering the possible
forms of two successive steps in any rightmost derivation. Figure 4.29 illustrates the two possible cases.
In case (1), A is replaced by (3By, and then the rightmost nonterminal B in the body (3By is replaced by
7. In case (2), A is again expanded first, but this time the body is a string y of terminals only. The next
rightmost nonterminal B will be somewhere to the left of y.
In other words:

Consider case (1) in reverse, where a shift-reduce parser has just reached the configuration

The parser reduces the handle 7 to B to reach the configuration

The parser can now shift the string y onto the stack by a sequence of zero or more shift moves to reach
the configuration

DR. SAMPADA K S, CSE, RNSIT 40


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
with the handle bBy on top of the stack, and it gets reduced to A. Now consider case (2). In
configuration

In both cases, after making a reduction the parser had to shift zero or more symbols to get the next
handle onto the stack. It never had to go into the stack to find the handle.

DR. SAMPADA K S, CSE, RNSIT 41


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

Conflicts During Shift-Reduce Parsing


There are context-free grammars for which shift-reduce parsing cannot be used. Every shift-reduce
parser for such a grammar can reach a configuration in which the parser, knowing the entire stack
contents and the next input symbol, cannot decide whether to shift or to reduce (a shift/reduce
conflict), or cannot decide which of several reductions to make (a reduce/reduce conflict). We
now give some examples of syntactic constructs that give rise to such grammars.
Example 4.3.8 : An ambiguous grammar can never be LR. For example, consider the dangling-else
grammar (4.14) of Section 4.3:

we cannot tell whether if expr t h e n stmt is the handle, no matter what appears below it on the stack.
Here there is a shift/reduce conflict. Depending on what follows the else on the input, it might be
correct to reduce if expr t h e n stmt to stmt, or it might be correct to shift else and then to look for
another stmt to complete the alternative if expr t h e n stmt else stmt.

DR. SAMPADA K S, CSE, RNSIT 42


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
Note that shift-reduce parsing can be adapted to parse certain ambiguous grammars, such as the if-
then-else grammar above. If we resolve the shift/reduce conflict on else in favor of shifting, the parser
will behave as we expect, associating each else with the previous unmatched then . We discuss parsers
for such ambiguous grammars in Section 4.8.
Another common setting for conflicts occurs when we know we have a han-dle, but the stack contents
and the next input symbol are insufficient to de-termine which production should be used in a reduction.
The next example illustrates this situation.
Example 4.39 : Suppose we have a lexical analyzer that returns the token name id for all names,
regardless of their type. Suppose also that our language invokes procedures by giving their names, with
parameters surrounded by parentheses, and that arrays are referenced by the same syntax. Since the
translation of indices in array references and parameters in procedure calls are different, we want to use
different productions to generate lists of actual parameters and indices. Our grammar might therefore
have (among others) productions such as those in Fig. 4.30.
A statement beginning with p ( i , j ) would appear as the token stream id(id, id) to the parser.
After shifting the first three tokens onto the stack, a shift-reduce parser would be in configuration

It is evident that the id on top of the stack must be reduced, but by which production? The correct choice
is production (5) if p is a procedure, but pro-duction (7) if p is an array. The stack does not tell which;
information in the symbol table obtained from the declaration of p must be used.
One solution is to change the token id in production (1) to procid and to use a more sophisticated lexical
analyzer that returns the token name procid when it recognizes a lexeme that is the name of a procedure.
Doing so would require the lexical analyzer to consult the symbol table before returning a token.

DR. SAMPADA K S, CSE, RNSIT 43


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51
If we made this modification, then on processing p ( i , j ) the parser would be either in the
configuration

or in the configuration above. In the former case, we choose reduction by production (5); in the latter
case by production (7). Notice how the symbol third from the top of the stack determines the reduction
to be made, even though it is not involved in the reduction. Shift-reduce parsing can utilize information
far down in the stack to guide the parse.

DR. SAMPADA K S, CSE, RNSIT 44


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 45


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 46


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 47


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 48


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 49


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 50


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 51


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 52


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 53


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 54


AUTOMATA THEORY AND COMPILER DESIGN – 21CS51

DR. SAMPADA K S, CSE, RNSIT 55

You might also like