Professional Documents
Culture Documents
Parsing
Where We Are
S o urc e Lexical Analysis
Code
Syntax Analysis
Semantic Analysis
IR Generation
IR Optimization
Code Generation
Optimization Machine
Code
Different Types of Parsing
●
Top-Down Parsing
●
Beginning with the start symbol, try to guess
the productions to apply to end up at the
user's prog ram .
● Bottom-Up Parsing
●
Beginning with the user's program, try to
apply productions in reverse to convert the
progra m back into the start symbol.
Top-Down Parsing
E
T E
T
E →T
E →T + E
T → int E
T → (E)
T E
E T + T + E int + T + E …
T + E
T + T T + ( E) …
int + E
int + T int + ( E )
…
int + int …
Parsing as a S e a rc h …
E →T …
E →T + E int (T) …
T → int
T → (E) (E) …
T (T + E) …
E T + T + E int + T + E …
T + E
T + T T + ( E) …
int + E
int + T int + ( E )
…
int + int …
O u r First Top-Down Algorithm
●
Breadth-First Search
● Maintain a worklist of sentential forms,
initially just the start symbol S.
● While the worklist isn't empty:
●
Remove an element from the worklist.
●
If it matches the target string, you're done.
●
Otherwise, for each possible string that can be
derived in one step, add that string to the
worklist.
●
Can recover a parse tree by tracking what
productions we applied at each step.
Breadth-First S e a rc h Parsing
Worklist
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist
T T+ E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T T + E
T T+ E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T T+ E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + E
int (E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + E int (E )
int (E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T+ E int (E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int (E )
T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int (E )
T + E
int + E (E ) + E T+ T T+T+ E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int (E ) int + E (E ) + E T + T
T + T + E
T + E
int + E (E ) + E T+ T T+T+ E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int (E ) int + E (E ) + E T + T
T + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (E ) int + E (E ) + E T + T
T + T + E
int
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (E ) int + E (E ) + E T + T
T + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int + E (E ) + E T + T T + T + E
(E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int + E (E ) + E T + T T + T + E
(E )
(T) (T + E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int + E (E ) + E T + T T + T + E
(T + E ) (T)
(E )
(T) (T + E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist int + E (E ) + E T + T T + T + E
(T + E ) (T)
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (E ) + E T + T T + T + E (T)
(T + E )
int + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (E ) + E T + T T + T + E (T)
(T + E )
int + E
int + T int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (E ) + E T + T T + T + E (T)
int + T + E int + T (T + E )
int + E
int + T int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (E ) + E T + T T + T + E (T)
int + T + E int + T (T + E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T T + T + E (T) (T + E )
int + T + E int + T
(E ) + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T T + T + E (T) (T + E )
int + T + E int + T
(E ) + E
(T ) + E (T + E ) + E (E ) + T (E ) + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T T + T + E (T) (T + E )
(T + E ) + E (T ) + E int + T + E int + T
(E ) + T (E ) + T + E
(E ) + E
(T ) + E (T + E ) + E (E ) + T (E ) + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T T + T + E (T) (T + E )
(T + E ) + E (T ) + E int + T + E int + T
(E ) + T (E ) + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T + E (T) (T + E ) int + T
(E ) + T (T + E ) + E (T ) + E int + T + E
(E ) + T + E
T + T
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T + E (T) (T + E ) int + T
(E ) + T (T + E ) + E (T ) + E int + T + E
(E ) + T + E
T + T
int + T (E ) + T T + int T + (E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T + E (T) (T + E ) int + T
(E ) + T (T + E ) + E (T ) + E int + T + E
T + T
int + T (E ) + T T + int T + (E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist T + T + E (T) (T + E ) int + T
(E ) + T (T + E ) + E (T ) + E int + T + E
(E ) + T + E int + T (E ) + T T + int T + (E )
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (T) (T + E ) int + T int + T + E
int + T (E ) + T + E (E ) + T (T + E ) + E (T ) + E
(E ) + T T + int T + (E)
T + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (T) (T + E ) int + T int + T + E
int + T (E ) + T + E (E ) + T (T + E ) + E (T ) + E
T+ T + T + E T+ T+ T T + (E ) + E T + int + E
T + T + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (T) (T + E ) int + T int + T + E
int + T (E ) + T + E (E ) + T (T + E ) + E (T ) + E
T+ T + T + E T+T+ T T + (E ) + E T + int + E
E →T
E →T + E
T → int int + int
T → (E)
Breadth-First S e a rc h Parsing
Worklist (T) (T + E ) int + T int + T + E
int + T (E ) + T + E (E ) + T (T + E ) + E (T ) + E
T+ T + T + E T+T+ T T + (E ) + E T + int + E
E →T
E →T + E
T → int int + int
T → (E)
B F S is Slow
●
Enormous time and memory usage:
●
Lots of wasted effort:
– Generates a lot of sentential forms that couldn't
possibly match.
– B ut in g eneral, extremely hard to tell w hether a
sentential for m can m atch – that's the job of
parsing !
●
High branching factor:
– Each sentential form can expand in (potentially)
many ways for each nonterminal it contains.
Reduc ing Wasted Effort
●
Suppo se we're trying to match a string γ.
● S uppose we have a sentential form τ = αω,
w here α is a string of terminals and ω is a
string of terminals and nonterminals.
● If α isn't a prefix of γ, then no string
derived from τ can ever match γ.
● If we can fin d a way to try to g et a prefix of
term inals at the front of our sen tential
forms, then we can start pru nin g out
im possible options.
Reduc in g the Branching Factor
●
If a string has many nonterminals in it,
the branching factor can be high.
●
Sum of the number of productions of each
nonterminal involved.
● If we can restrict which productions we
apply, we can keep the branching factor
lower.
Leftmost Derivations
●
Recall: A leftmost derivation is one where we
always expand the leftmost symbol first.
● Updated algorithm:
● Do a bread th-first se a r c h, only considering
leftmost derivations.
– Dramatically drops branching factor.
– Increases likelihood that we get a prefix of nonterminals.
●
Prune sentential forms that can't possibly match.
– Avoids wasted effort.
Leftmost B F S
Worklist E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
T T+ E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist T T + E
T T+ E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist T T+ E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist T + E
int (E )
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist T + E
int (E )
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist T+ E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
T + E
int + E (E) + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
T + E
int + E (E) + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + E
T + E
int + E (E) + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
int + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
int + E
int + T int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T int + T + E
int + E
int + T int ++ T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T + E
int + T
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T + E
int + T
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T + E
int + T
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T + E int + int
int + T
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + T + E int + int
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + int
int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + int
int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + int
int + T + E
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist int + int
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
int + int
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
Worklist
int + int
E →T
E →T + E
T → int int + int
T → (E)
Leftmost B F S
●
Substantial improvement over na ïve
algorithm.
●
Will always find a valid parse of a
program if one exists.
●
C a n easily be m odified to find if a
p rogra m can't be pa rse d.
● But, there are still problems.
Leftmost B F S H a s Problems
Worklist
A → Aa | Ab |
c
Leftmost B F S H a s Problems
Worklist
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist A
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist
Aa Ab c
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist
Aa Ab c
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aa Ab
Aa Ab c
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aa Ab
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aa Ab
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aa Ab
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Ab
Aa
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Ab
Aa
Aaa A ba ca
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Ab
Aa
Aaa A ba ca
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Ab Aaa Aba
Aa
Aaa A ba ca
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Ab A aa A ba
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aaa Aba
Ab
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aaa Aba
Ab
Aab A bb cb
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aaa Aba
Ab
Aab A bb cb
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist Aaa Aba Aab Abb
Ab
Aab A bb cb
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist A aa A ba A ab A bb
A → Aa | Ab |
c
caaaaaaaaaa
Leftmost B F S H a s Problems
Worklist A aa A ba A ab A bb
A → Aa | Ab |
c
caaaaaaaaaa
Problems with Leftmost B F S
●
Grammars like this can make parsing
take exponential time.
●
Also uses exponential memory.
● What if we search the graph with a
different algorithm?
Leftmost D F S
●
Idea: Use depth-first search.
● Advantages:
●
Lower memory usage: Only considers one
branch at a time.
●
High performance: On many grammars, runs
very quickly.
●
Ea sy to im p lem en t: C a n be w ritten as a set
of m utually recursive func tions.
Leftmost D F S
E →T
E →T + E
T → int
T → (E)
Leftmost D F S
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
int
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
int
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
(E)
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
(E)
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T + E
E →T
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T + E
E →T
int + E
E →T + E
T → int
T → (E)
int + int
Leftmost D F S
E
T + E
E →T
int + E
E →T + E
int + T
T → int
T → (E)
int + int
Leftmost D F S
E
T + E
E →T
int + E
E →T + E
int + T
T → int
T → (E) int + int
int + int
Leftmost D F S
E
T + E
E →T
int + E
E →T + E
int + T
T → int
T → (E) int + int
int + int
Problems with Leftmost D F S
A
Aa
A → Aa | c Aaa
Aaaa
Aaaaa
c
Left Recursion
●
A nonterminal A is said to be left-
recursive iff
A ⇒* Aω
for some string ω .
●
Leftmost DFS may fail on left-recursive
gramm ars .
● Fortunately, in many cases it is possible to
eliminate left recursion.
S u m m a r y of Leftmost B F S / D F S
●
Leftmost BFS works on ●
Leftmost DFS works on
all grammars. grammars without left
recursion.
●
Worst-case runtime is ●
Worst-case runtime is
exponential. exponential.
●
Worst-case memory ●
Worst-case memory
usage is exponential. usage is linear.
●
Rarely used in ● Often used in a limited
practice. form as recursive
descent.
Predictive Parsing
Predictive Parsing
●
The leftmost DFS/BFS algorithms are
backtracking algorithms.
●
Guess which production to use, then back up
if it doesn't work.
● Try to match a prefix by sheer dumb luck.
●
There is another class of parsing
algorithms called predictive algorithms.
●
Based on remaining input, predict ( w i t h o u t
b a c k t r a c k i n g ) which production to use.
Tradeoffs in Prediction
●
Predictive parsers are f a s t .
●
Many predictive algorithms can be made to
run in linear time.
●
O ften can be table-driven for extra
pe rform anc e .
●
Predictive parsers are w e a k .
●
Not all grammars can be accepted by
predictive parsers.
● Trade e x p r e s s i v e n e s s for
speed.
Exploiting Lookahead
●
Given just the start symbol, how do you
know which productions to use to get to
the input program?
● Idea: Use lookahead tokens.
● When trying to decide w hich
production to use , look at
som e num ber of tokens of the
input to help m ake the
de c ision.
Implementing Predictive Parsing
●
Predictive parsing is only possible if we can
predict which production to use given some
number of lookahead tokens.
● Increasing the number of lookahead tokens
increases the number of grammars we can
parse, but complicates the parser.
●
Decreasing the number of lookahead tokens
decreases the number of grammars we can
parse, but simplifies the parser.
Predictive Parsing
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
E→T
E→T +
ET→
int
T → (E)
int ( ) + *
E int (E Op E)
Op + *
LL(1) Parsing
(int + (int * int))
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
LL(1) Parsing
E (int + (int * int))
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
LL(1) Parsing
E (int + (int * int))
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
TThhee $$ symsymbol
bol isis t the
he eenndd- - oof f- - ininppuut t
int ( ) + * ma
mar rke
ker r aanndd isis uusseedd by
by t the
he ppaar rsseer r
E 1 2 t too ddeet teecct t wwhen
hen wwee have
have r reeaacche hedd
Op 3 4 t the
he eenndd oof f t thehe ininppuut t. . I It t isis nnoot t
aa ppaar rt t oof f t the
he ggr raamma
mmar r. .
LL(1) Parsing
E$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
TThhee f firi rs st t sym
s y mbol
b o l ooff oo uu rr gg uu ee ss ss iiss aa
int ( ) + * nnoonnt teerrmina
minal l. . We We t thehenn look look aat t oouurr
E 1 2 ppaarrsin
singg t taabbl lee t too sseeee wha
what t
Op 3 4 pprroodduuccttion
ion ttoo uuse se. .
TThis
h is isis ccaalle
lledd aa pprreeddicict t ststeepp. .
LL(1) Parsing
E$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
TThhee f firirsst
t sym
symbol
bol oof f oouur r gguueessss isis
int ( ) + * now
now aa t teer rmina
minal l symb
symbool l. . We We t thu huss
E 1 2 ma
mat tcchh i it t aaggaainst
inst t the
he f fi ir rsst t symb
symbool l
oof f t the
he sstt r ring
ing t too ppaar rssee. .
Op 3 4
TThis
his isis ccaalle
lledd aa mmat
atcchh ststeepp. .
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E)
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → +
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → * + E )$ + (int * int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → * + E )$ + (int * int))$
E )$ (int * int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → * + E )$ + (int * int))$
E )$ (int * int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → * + E )$ + (int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → * + E )$ + (int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2
Op 3 4
LL(1) Parsing
E$ (int + (int * int))$
(E Op E)$ (int + (int * int))$
(1) E → int E Op E)$ int + (int * int))$
(2 ) E → (E Op E) int Op E)$ int + (int * int))$
(3 ) Op → + Op E)$ + (int * int))$
(4 ) Op → * + E )$ + (int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2
Op 3 4
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op 3 4
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
int))$ int))$
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
int))$ int))$
))$ ))$
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
int))$ int))$
))$ ))$
)$ )$
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int E Op E)$ int +(int * int))$
(2 ) E → (E Op E) int Op E)$ int +(int * int))$
(3 ) Op → + Op E)$ +(int * int))$
(4 ) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E ))$ (int * int))$
int ( ) + * E Op E))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
int))$ int))$
))$ ))$
)$ )$
$ $
LL(1) Parsing
E$ (int +(int * int))$
(E Op E)$ (int +(int * int))$
(1) E → int
E Op E)$ int +(int * int))$
(2) E → (E Op E) int Op E)$ int +(int * int))$
(3) Op → + Op E)$ +(int * int))$
(4) Op → * + E )$ +(int * int))$
E )$ (int * int))$
(E Op E))$ (int * int))$
int ( ) + *
E Op E ))$ int * int))$
E 1 2 int Op E))$ int
int* *int))$
int))$
Op E))$ * int))$
Op 3 4 * E ))$ * int))$
E ))$ int))$
int))$ int))$
))$ ))$
)$ )$
$ $
LL(1) Error Detection
(1) E → int int + int$
(2) E → (E Op E)
(3) Op → +
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection
(1) E → int E$ int + int$
(2) E → (E Op E)
(3) Op → +
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection
(1) E → int E$ int + int$
(2) E → (E Op E)
(3) Op → +
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection
(1) E → int E$ int + int$
(2) E → (E Op E) int $ int + int$
(3) Op → +
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection
(1) E → int E$ int + int$
(2) E → (E Op E) int $ int + int$
(3) Op → + $ + int$
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection
(1) E → int E$ int + int$
(2) E → (E Op E) int $ int + int$
(3) Op → + $ + int$
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection
(1) E → int E$ int + int$
(2) E → (E Op E) int $ int + int$
(3) Op → + $ + int$
(4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int (int (int))$
( 2) E → (E Op E)
( 3) Op → +
( 4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E)
( 3) Op → +
( 4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E)
( 3) Op → +
( 4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → +
( 4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → + E Op E)$ int (int))$
( 4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → + E Op E)$ int (int))$
( 4) Op → *
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → + E Op E)$ int (int))$
( 4) Op → * int Op E)$ int (int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → + E Op E)$ int (int))$
( 4) Op → * int Op E)$ int (int))$
Op E)$ (int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → + E Op E)$ int (int))$
( 4) Op → * int Op E)$ int (int))$
Op E)$ (int))$
int ( ) + *
E 1 2
Op 3 4
LL(1) Error Detection, Part II
(1) E → int E$ (int (int))$
( 2) E → (E Op E) (E Op E)$ (int (int))$
( 3) Op → + E Op E)$ int (int))$
( 4) Op → * int Op E)$ int (int))$
Op E)$ (int))$
int ( ) + *
E 1 2
Op 3 4
The LL(1) Algorithm
●
Supp ose a gramm ar has star t sym bol S and LL(1)
parsing table T. We want to parse string ω
●
Initialize a stack containing S$.
● Repeat until the stack is empty:
●
Let the next character of ω be t.
● If the top of the stack is a terminal r:
– If r and t don't match, report an error.
– Otherwise consume the character t and pop r from the
stack.
●
Otherwise, the top of the stack is a nonterminal A:
– If T[A, t] is undefined, report an error.
– Replace the top of the stack with T[ A, t].
A Simple LL(1) G ra m m a r
TERM → id
| constant
A Simple LL(1) G ra m m a r
TERM → id (9)
| constant (10)
TERM
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id ( 9)
| constant ( 10)
TERM
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id ( 9)
| constant ( 10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id (9)
| constant (10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id (9)
| constant (10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id ( 9)
| constant ( 10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id ( 9)
| constant ( 10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then STMT ( 1)
| while EXPR do STMT ( 2)
| EXPR ; ( 3)
TERM → id (9)
| constant (10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then STMT ( 1)
| while EXPR do STMT ( 2)
| EXPR ; ( 3)
TERM → id (9)
| constant (10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT (2)
| EXPR ; ( 3)
TERM → id (9)
| constant (10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT (2)
| EXPR ; ( 3)
TERM → id (9)
| constant (10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT (2)
| EXPR ; ( 3)
TERM → id ( 9)
| constant ( 10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then (1)
STM T
| while EXPR do STMT (2)
| EXPR ; ( 3)
TERM → id ( 9)
| constant ( 10)
TERM 9 10
Constructing LL(1) Parse Tables
STMT → if EXPR then STMT (1)
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id (9)
| constant (10)
TERM 9 10
Can we find an algorithm for
constructing LL(1) parse
tables?
Filling in Table Entries
●
Intuition: The next character should
uniquely identify a production, so we
should pick a production that ultimately
starts with that character.
● T[A, t] should be a production A → ω iff
ω derives something starting with t.
● More rigorously:
T[A, t] = Bω iff A → ω and ω ⇒* tω'
In what follows, assume that our grammar
does not contain any ε-productions.
TERM → id
| constant
Iterative F I R S T Computations
TERM → id
| constant
Iterative F I R S T Computations
TERM → id
| constant
Iterative F I R S T Computations
TERM → id
| constant
Iterative F I R S T Computations
TERM → id
| constant
Iterative F I R S T Computations
TERM → id
| constant
Iterative F I R S T Computations
TERM → id (9)
| constant (10)
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT (1)
| while EXPR do STMT ( 2)
| EXPR ; (3)
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT (1) STMT EXPR TERM
| while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT ( 1) STMT EXPR TERM
| while EXPR do STMT (2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT ( 1) STMT EXPR TERM
| while EXPR do STMT (2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT (1) STMT EXPR TERM
| while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT (1) STMT EXPR TERM
| while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT (2)
| EXPR ; ( 3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT (2)
| EXPR ; ( 3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT (2)
| EXPR ; ( 3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id ( 4)
| zero? TERM (5) not --
| not EXPR (6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id ( 4)
| zero? TERM (5) not --
| not EXPR (6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id ( 4)
| zero? TERM (5) not --
| not EXPR (6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR (6) ++ id
| ++ id (7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR (6) ++ id
| ++ id (7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM (5) not --
| not EXPR ( 6) ++ id
| ++ id (7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM (5) not --
| not EXPR ( 6) ++ id
| ++ id (7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR (6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR (6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id (7) -- id constant
| -- id ( 8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id (7) -- id constant
| -- id ( 8) constant
TERM → id (9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id ( 9)
| constant (10)
TERM
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id ( 9)
| constant (10)
TERM 9
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant ( 10 )
TERM 9
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then (1) STMT EXPR TERM
STMT | while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant ( 10 )
TERM 9 10
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT (1) STMT EXPR TERM
| while EXPR do STMT ( 2)
| EXPR ; (3) if zero?
id
while not
zero? ++ constant
EXPR → TERM -> id (4)
| zero? TERM ( 5) not --
| not EXPR ( 6) ++ id
| ++ id ( 7) -- id constant
| -- id (8) constant
TERM → id (9)
| constant (10)
TERM 9 10
From F I R S T S e t s to LL(1) Tables
STMT → if EXPR then STMT (1) STMT EXPR TERM
| while EXPR do STMT (2)
| EXPR ; (3) if zero?
id
while not
zero? constant
EXPR → TERM -> id (4 ) ++
| zero? TERM (5 ) not --
| not EXPR (6 ) ++ id
| ++ id (7 ) --
| -- id constant
(8 ) id
TERM → id constant
| constant (9)
(10)
TERM 9 10
ε-Free LL(1) Parse Tables
●
The following algorithm constructs an LL(1)
parse table for a gram m ar with no
ε-produc tions.
● Compute the FIRST sets for all in
nonterminals
the grammar.
● For e a ch production A → tω, set T[A, t] = tω.
● For e a ch production A → Bω, set T[A, t] = Bω
for each t ∈ FIRST(B ).
Expanding our Grammar
STMT → if EXPR then STMT (1) id → id;
| while EXPR do STMT ( 2)
| EXPR ; (3) while not zero? id do --id;
TERM → id (9)
| constant (10)
Expanding our Grammar
STMT → if EXPR then STMT (1) id → id;
| while EXPR do STMT ( 2)
| EXPR ; (3) while not zero? id do --id;
TERM → id (9)
| constant (10)
TERM → id (9)
| constant (10)
Hi
E nd
LL(1) Tables with ε
Msg → Hi End Msg Hi End
Hi → hello | heya | yo
hello hello world
End → world! | ε
heya heya ε
yo yo
Hi
E nd
LL(1) Tables with ε
Msg → Hi End Msg Hi End
Hi → hello | heya | yo
hello hello world
End → world! | ε
heya heya ε
yo yo
Hi hello heya yo
E nd
LL(1) Tables with ε
Msg → Hi End Msg Hi End
Hi → hello | heya | yo
End → world! | ε
hello hello world
heya heya ε
yo yo
Hi hello heya yo
E nd
LL(1) Tables with ε
Msg → Hi End Msg Hi End
Hi → hello | heya | yo
End → world! | ε
hello hello world
heya heya ε
yo yo
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg → Hi End Msg Hi End
Hi → hello | heya | yo
hello hello world
End → world! | ε
heya heya ε
yo yo
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
End $ $
Hi hello heya yo
E nd world!
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
End $ $
Hi hello heya yo
E nd world!
ε is Complicated
●
When constructing LL(1) tables with ε-
productions, we need to have an extra
column for $.
Msg → Hi End
Hi → hello | heya |
End → yo world! | ε
ε is Complicated
●
When constructing LL(1) tables with ε-
productions, we need to have an extra
column for $.
Msg → Hi End
Hi → hello | heya |
End → yo world! | ε
Hi hello heya yo
End world!
ε is Complicated
●
When constructing LL(1) tables with ε-
productions, we need to have an extra
column for $.
Msg → Hi End
Hi → hello | heya |
End → yo world! | ε
Hi hello heya yo
End world! ε
LL(1) Tables with ε
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
End $ $
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
End $ $
Hi hello heya yo
End world! ε
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
End $ $
Hi hello heya yo
End world! ε
LL(1) Tables with ε
Msg $ hello $
Hi End $ hello $
hello E n d $ hello $
End $ $
$ $
Hi hello heya yo
End world! ε
It G e t s Trickier
Num → Sign Digits
Sign → + |- |ε
Digits → Digit More
M ore → Digits | ε
Digit → 0 |1 |…|9
It G e t s Trickier
Num → Sign Digits
Sign → + |- |ε
Digits → Digit More
M ore → Digits | ε
Digit → 0 |1 |…|9
+ - # $
Num
Sign
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
M ore → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num
Sign
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num
Sign
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε
+ - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε
+ - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit M ore
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit M ore
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
M ore → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |… |9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
M ore → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |… |9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
M ore → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε
+ - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + -
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε
+ - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + - ε
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit M ore
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + - ε
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + - ε
Digits Digits More
M o re Digits
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
More → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…| 1 6 ε 2 7 2 7 2 7
9 2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + - ε
Digits Digits More
M o re Digits ε
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
M ore → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |… |9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + - ε
Digits Digits More
M o re Digits ε
Digit #
It G e t s Trickier
Num → Sign Digits Num Sign Digit Digits M o re
Sign → + |- |ε + - 0 5 0 5 0 5
Digits → Digit More
M ore → Digits | ε 0 5 - 1 6 1 6 1 6
Digit → 0 |1 |…|9 1 6 ε 2 7 2 7 2 7
2 7 3 8 3 8 3 8
3 8 4 9 4 9 4 9
4 9 ε
+ - # $
Num Sign Digits Sign Digits Sign Digits
Sign + - ε
Digits Digits More
M o re Digits ε
Digit #
FO L LOW Sets
●
With ε-productions in the grammar, we may have to
“look past” th e cu rrent nonterm inal to w hat can com e
after it.
●
The FOLLOW set represents the set of terminals that
might come after a given nonterminal.
● Formally:
FO LLO W (A ) = { t |S ⇒* αAtω for some α, ω }