Lecture 8
Lecture 8
An Introductory Example
Bottom-up parsers don’t need left-
factored grammars
1
The Idea
Bottom-up parsing reduces a string to the
start symbol by inverting productions:
Observation
Read productions from bottom-up parse
in reverse (i.e., from bottom to top)
This is a rightmost derivation!
int * int + int T → int
int * T + int T → int * T
T + int T → int
T+T E→T
T+E E→T+E
E
2
A Bottom-up Parse
E
int * int + int
int * T + int
T E
T + int
T+T
T T
T+E
E
int * int + int
A bottom-up parser traces a rightmost
derivation in reverse!
3
Trivial Bottom-Up Parsing
Algorithm
Let I = input string
repeat
pick a non-empty substring β of I
where X→ β is a production
if no such β, backtrack
replace one β by X in I
until I = “S” (the start symbol) or
all possibilities are exhausted
Questions
Does this algorithm terminate?
4
Where Do Reductions Happen
Important Fact #1 has an interesting
consequence:
Let αβω be a step of a bottom-up parse
Assume the next reduction is by X→ β
Then ω is a string of terminals
Notation
Idea: Split string into two substrings
Right substring is as yet unexamined by parsing
(a string of terminals)
Left substring has terminals and non-terminals
5
Shift-Reduce Parsing
Bottom-up parsing uses two kinds of
actions:
Shift
Reduce
Shift
Shift: Move | one place to the right
Shifts a terminal to the left string
ABC|xyz ⇒ ABCx|yz
6
Reduce
Apply an inverse production at the right
end of the left string
If A → xy is a production, then
Cbxy|ijk ⇒ CbA|ijk
7
The Example with Shift-
Reduce Parsing
|int * int + int shift
int | * int + int shift
int * | int + int shift
int * int | + int reduce T → int
int * T | + int reduce T → int * T
T | + int shift
T + | int shift
T + int | reduce T → int
T+T| reduce E→T
T+E| reduce E→T+E
E|
8
The Stack
Left string can be implemented by a stack
Top of the stack is the |
9
Conflicts
Generic shift-reduce strategy:
If there is a handle on top of the stack, reduce
Otherwise, shift
Source of Conflicts
Ambiguous grammars always cause
conflicts
10
Conflict Example
Consider our favorite ambiguous
grammar:
E → E+E
| E*E
| (E)
| int
11
Another Shift-Reduce Parse
| int * int + int shift
... ...
E * E | + int shift
E * E + | int shift
E * E + int | reduce E → int
E*E+E| reduce E → E + E
E*E| reduce E → E * E
E|
Example Notes
In the second step E * E | + int we can either
shift or reduce by E → E * E
12
Precedence Declarations
Revisited
Precedence declarations cause shift-reduce
parsers to resolve conflicts in certain ways
Precedence Declarations
Revisited (Cont.)
The term “precedence declaration” is
misleading
13