90 likes | 208 Views
Predictive Parsing. Lecture 8. Predictive – LL(1) Parsing. Dragon section 4.4, Fischer chapter 5 Deterministic parsers for a subset of CFG languages. Similar to general parsers, but when TOS is a non-terminal parser looks at input to deterministically choose production.
E N D
Predictive Parsing Lecture 8
Predictive – LL(1) Parsing • Dragon section 4.4, Fischer chapter 5 • Deterministic parsers for a subset of CFG languages. • Similar to general parsers, but when TOS is a non-terminal parser looks at input to deterministically choose production. • Parsers run O(n) time • Only parses the class for grammars called LL(1) Scan Input Left-to-Right Left most non-terminal expanded Token look ahead
Example • S → (S) → [s] → λ • Input Stack Action 0 S ? • Choose the action by looking at next input character: ‘(‘ • Only first production S → (S) can produce a leading left parenthesis • May need more look ahead, e.g LL(2)S → (S) [S] ( ) [ ] Either production could reduce a ‘(‘ But, if the next char is ‘)’, then only the second one is possible
LL Grammars • Some languages are not LL(k) for any k • S → (S) | SS | ( ) • Don’t know to apply 1st or 2nd rule until we see )( CFG LL(2) LL(k) LL(1)
Testing for LL(1) • A grammar is LL(1) if its parse table has disjoint predictive sets for productions with a common LHS • A predictive set contains the terminal symbols that occur first in the strings produced by a production • Use sets to decide which production to apply • Grammar cannot have productions X → α and X → β such that α and β can begin with the same terminal. • Parser cannot decide to apply first or second rule by looking at input • Some non-LL(1) grammars can be “fixed” • Write a LL(1) grammar that produces the same set of strings
Left-Recursive Grammars • Left-recursive grammars are not LL(1) • X→Xα • e.g E → E + F | F • A finite recursive grammar must contain at least two productions • X → Xα | β • Terminals occurring first in the non-recursive production also occur first in recursive production. • Can remove immediate left-recursion • A → Aα | β • A → βA` • A` → αA`|λ Terminals and non-terminals that don’t begin with A Terminals and non-terminals Right-recursive
Example of Recursion Removal • E → E + F | F • E → F E` E`→ +F E` | λ • Cannot directly build parse trees from new grammar Old New E E E F F + E` E + F 4 2 F + E` F 3 3 F E` + 2 4 λ
Common Prefixes • Another common non-LL(1) grammar has two productions whose RHS have a common prefix • e.g S → (S) | () • Cannot choose production by looking at next token • Easy to remove with left-factoring • A → α B1 | α B2 • A → α A` • A`→ B1 | B2 • e.g S → (S` S` → S) | )
Double Example • S → (S) | SS | 0 • First, remove immediate left recursion • S → (S) S` | ()S` • S` → SS` | λ • Next, eliminate common prefix • S → (TT → S)S` | )S`S` → SS` | λ • Wouldn’t want to write this grammar originally