Académique Documents
Professionnel Documents
Culture Documents
X+E| X +E
T ( E ) | int Y T int Y (E)
Y *T
Y*T|
rhs of production to use
leftmost non-terminal
Prof. Aiken CS 143 Lecture 7 5 Prof. Aiken CS 143 Lecture 7 6
1
LL(1) Parsing Table Example (Cont.) LL(1) Parsing Tables. Errors
• Consider the [E, int] entry • Blank entries indicate error situations
– “When current non-terminal is E and next input is
int, use production E T X” • Consider the [E,*] entry
– This can generate an int in the first position – “There is no way to derive a string starting with *
from non-terminal E”
• Consider the [Y,+] entry
– “When current non-terminal is Y and current token
is +, get rid of Y”
– Y can be followed by + only if Y
• Method similar to recursive descent, except initialize stack = <S $> and next
– For the leftmost non-terminal S repeat
– We look at the next input token a case stack of
– And choose the production shown at [S,a]
<X, rest> : if T[X,*next] = Y1…Yn
then stack <Y1… Yn rest>;
• A stack records frontier of parse tree else error ();
– Non-terminals that have yet to be expanded
<t, rest> : if t == *next ++
– Terminals that have yet to matched against the input
– Top of stack = leftmost pending terminal or non-terminal
then stack <rest>;
else error ();
• Reject on reaching error state until stack == < >
• Accept on end of input & empty stack
Prof. Aiken CS 143 Lecture 7 9 Prof. Aiken CS 143 Lecture 7 10
2
Constructing Parsing Tables: The Intuition Computing First Sets
• If * t Algorithm sketch:
– can derive a t in the first position
– We say that t First() 1. First(t) = { t }
2. First(X)
• If A and * and S * A t • if X
– Useful if stack has A, input is t, and A cannot derive t • if X A1 … An and First(Ai) for 1 i n
– In this case only option is to get rid of A (by deriving ) 3. First() First(X) if X A1 … An
• Can work only if t can follow A in at least one derivation
– and First(Ai) for 1 i n
– We say t Follow(A)
3
Constructing LL(1) Parsing Tables Notes on LL(1) Parsing Tables
• Construct a parsing table T for CFG G • If any entry is multiply defined then G is not
LL(1)
• For each production A in G do: – If G is ambiguous
– For each terminal t First() do – If G is left recursive
• T[A, t] = – If G is not left-factored
– If First(), for each t Follow(A) do – And in other cases as well
• T[A, t] =
– If First() and $ Follow(A) do
• T[A, $] = • Most programming language CFGs are not LL(1)
• Bottom-up parsing is more general than top- • Bottom-up parsers don’t need left-factored
down parsing grammars
– And just as efficient
– Builds on ideas in top-down parsing • Revert to the “natural” grammar for our
example:
• Bottom-up is the preferred method ET+E|T
T int * T | int | (E)
• Concepts today, algorithms next time
• Consider the string: int * int + int
Prof. Aiken CS 143 Lecture 7 21 Prof. Aiken CS 143 Lecture 7 22
Bottom-up parsing reduces a string to the start • Read the productions in reverse
symbol by inverting productions: (from bottom to top)
• This is a rightmost derivation!
int * int + int T int
int * T + int T int * T int * int + int T int
T + int T int int * T + int T int * T
T+T ET T + int T int
T+E ET+E T+T ET
E T+E ET+E
E
Prof. Aiken CS 143 Lecture 7 23 Prof. Aiken CS 143 Lecture 7 24
4
Important Fact #1 A Bottom-up Parse
E
int * int + int
T+T
T T T
5
A Bottom-up Parse in Detail (5) A Bottom-up Parse in Detail (6)
T+T T+T
T+E
T T T+E
T T
E
int * int + int int * int + int
Important Fact #1 has an interesting • Idea: Split string into two substrings
consequence: – Right substring is as yet unexamined by parsing
– Let be a step of a bottom-up parse (a string of terminals)
– Assume the next reduction is by X – Left substring has terminals and non-terminals
– Then is a string of terminals
• The dividing point is marked by a |
Why? Because X is a step in a right- – The | is not part of the string
most derivation
• Initially, all input is unexamined |x1x2 . . . xn
6
Shift-Reduce Parsing Shift
Bottom-up parsing uses only two kinds of • Shift: Move | one place to the right
actions: – Shifts a terminal to the left string
Reduce
7
A Shift-Reduce Parse in Detail (2) A Shift-Reduce Parse in Detail (3)
|int * int + int |int * int + int
int | * int + int int | * int + int
int * | int + int
8
A Shift-Reduce Parse in Detail (8) A Shift-Reduce Parse in Detail (9)
|int * int + int |int * int + int
int | * int + int int | * int + int
int * | int + int int * | int + int
int * int | + int int * int | + int
T T
int * T | + int int * T | + int
T | + int T | + int
T + | int T T + | int T T
T + int | T + int |
int * int + int T+T| int * int + int
Prof. Aiken CS 143 Lecture 7 49 Prof. Aiken CS 143 Lecture 7 50
• Left string can be implemented by a stack • In a given state, more than one action (shift or
reduce) may lead to a valid parse
– Top of the stack is the |
• If it is legal to shift or reduce, there is a shift-
• Shift pushes a terminal on the stack reduce conflict