130 likes | 177 Views
Learn about LL(1) parsing in compiler design, including analyzing first and follow sets, LL(1) table construction, left factoring, left recursion removal, and handling LL(k) grammars. Examples and detailed explanations provided.
E N D
LL(1) Parsing CPSC 388 Ellen Walker Hiram College
Adding Prediction • No lookahead: case statement based on first token (e.g. “exp” in book) • Adding lookahead: consider two sets • FIRST(S): All possible first tokens of S (can include ) • FOLLOW (S): All possible tokens that can follow S (can include $, for end of string)
Finding First(X) • If there is a rule X->x…, where x is a terminal, then x is in First(X) • If there is a rule X-> , or, if S can derive through a sequence of rules, then is in First(S) • If there is a rule X->A…, where A is a non-terminal, then everything in First(A) except is in First(S) • If there is a rule X->AB… and is in First(A), then everything in First(B) except is in First(X)
Finding Follow(X) • $ is in Follow(S), where S is the start non-terminal. • If there is a rule A->…Xx… , where x is a terminal, then x is in Follow(X) • If there is a rule A->…XB…, where B is a non-terminal, then everything in First(B) except is in Follow(X) • If there is a rule A-> …X, then everything in Follow(A) is in Follow(X) • If there is a rule A-> …XB… and First(B) is , then re-evaluate the rule as if B weren’t there
S->abSXbY | X-> cX | Y -> aY | First(S) = First(X) = First(Y) = Follow(S) = Follow(X) = Follow(Y) = First & Follow Example
Using First & Follow Sets • Use an explicit stack as in the CFL to PDA algorithm. • If the current character is in First (S), then it’s OK to pop S and push its rule beginning with this character • If the current character is in Follow (S) then it’s OK to pop S without pushing (i.e. use S-> e rule)
LL(1) Example • Grammar: S-> aSb | e • First(S): {a, e} • Follow(S): {b, $}
LL Parse Table • Table of Non-Terminals vs. Terminals • If S->rhs and a is in FIRST(S) and a is in FIRST(rhs) put S->rhs in M[S,a] • If S->e and a is in FOLLOW(S), put S-> e in M[S,a] • If there is only one entry in each cell, it is LL(1)
Left Factoring • Two rules start with the same RHS • Make a new rule to distinguish them • S-> if ( exp ) S • S-> if ( exp ) S else S becomes • S-> if ( exp ) S S’ • S’ -> else S | e
Left Recursion Removal • Rewrite rules to avoid left recursion S->Sx | y becomes S-> yS’ and S’ -> xS’ | e • (Note: x and y can be arbitrary strings)
Example: • E -> E + T | T • T -> T * F | F • F -> n | (E) n stands for “number” • Left-recursion removal? • LL(1) table?
LL(k) Grammars • Look at k terminals instead of 1 terminal • First(S) is all sequences of k terminals that can begin S • Follow(S) is all sequences of k terminals that can follow S • Col. headers of table are sequences of k terminals instead of single terminals • First & Follow computations get messy!