1 / 8

LL(k) Grammar and Context-Free Languages

Learn about LL(k) grammars, deterministic context-free languages, and the relationship between LL(k) grammars and context-free languages. Understand left factoring and removing left recursion in grammar transformations.

ahayden
Download Presentation

LL(k) Grammar and Context-Free Languages

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Section 12.3 Context-Free Parsing We know (via a theorem) that the context-free languages are exactly those languages that are accepted by PDAs. When a context-free language can be recognized by a deterministic final-state PDA, it is called a deterministic context-free language. An LL(k) grammar has the property that a parser can be constructed to scan an input string from left to right and build a leftmost derivation by examining next k input symbols to determine the unique production for each derivation step. If a language has an LL(k) grammar, it is called an LL(k) language. LL(k) languages are deterministic context-free languages, but there are deterministic context-free languages that are not LL(k). (See text for an example on page 789.) Example. Consider the language {anb | nN}. It has the LL(1) grammar S aS | b. A parser can examine one input letter to decide whether to use S aS or S b for the next derivation step. (2) It has the LL(2) grammar S aaS | ab | b. A parser can examine two input letters to determine whether to use S aaS or S ab for the next derivation step. Notice that the grammar is not LL(1). (3) Quiz. Find an LL(3) grammar that is not LL(2). Solution. S aaaS | aab | ab | b.

  2. Example/Quiz. Why is the following grammar for {anbn + k | n, k N} an-LL(1) grammar? S AB A  aAb | L B  bB | L. Answer: Any derivation starts with S AB. The next derivation step uses one of the productions A  aAb orA  L, depending on whether the scanned input letter is a or not. The argument is the same for B-productions. S aSb | T T  bT | L. Example. The following grammar for {anbn + k | n, kN} is not LL(k) for every k. It is not LL(1): Let the input be ab. The first letter a tells us to start with S aSb. The letter a in aSb matches the first input letter, so we lookahead to the second input letter b. This tells us we must use S T to get S aSb aTb. The lookahead remains at b, so we can’t determine whether it is the last b of the input string. So we don’t know whether to choose T bT or T L for the next step. Thus the grammar is not LL(1). It is not LL(2): Let the input be aabb. The first two input letters aa, tell us S aSb. The letter a in aSb matches the first input, so we lookahead to the next two-letter substring ab. We must use S aSb to get S aSb  aaSbb. Now the lookahead becomes bb, so we must use S T to get S aSb  aaSbb aaTbb. The lookahead remains at bb, so we can’t determine whether these are the last two b’s of the input string. So we don’t know whether to choose T bT or T L for the next step. Thus the grammar is not LL(2). Quiz (on your time): Find a general argument to show the grammar is not LL(k).

  3. Example. The language {an + kbn | k, nN} is not deterministic context-free. So it has no LL(k) grammar for every k. Proof: Any PDA for the language must keep a count of the a’s with the stack so that when the b’s come along the stack can be popped with each b. But there might still be a’s on the stack (e.g., when k > 0), so there must be a nondeterministic state transition to a final state from the popping state. i.e., We need two instructions like, (i, b, a, pop, i) and (i, L, a, pop, final). Note: The previous two examples show that {ambn | m ≤ n} is LL(1) but {ambn | m ≥ n} is not LL(k) for any k. Grammar Transformations Left factoring: Sometimes we can “left-factor” an LL(k) grammar to obtain an equivalent LL(n) grammar where n < k. Example. The grammar S aaS | ab | b is LL(2) but not LL(1). But we can factor out the common prefix a from productions S aaS | ab to obtain SaT TaS | b. This gives the new grammar: SaT | b TaS | b. Quiz: Find an LL(k) grammar where k is as small as possible that is equivalent to the following grammar. SabS | abcT | ab T cT | c. Solution: The given grammar is LL(3) and it can be left-factored to become an LL(1) grammar as follows: SabR RS | cT | L TcU UT | L.

  4. Removing left recursion: A left-recursive grammar is one which has a derivation of the form • A +Ax • for some nonterminal A and sentential form x. • Left-recursive grammars are not LL(k) for any k. • Example. The language {ban | n  N} has a grammar S Sa | b, which is left-recursive. It is • not LL(k) for any k. Consider the following cases: • LL(1) case: If the input string is ba, the lookahead is b. So we don’t know whether there are • any a’s to the right of b. Therefore we don’t know which production to start the derivation. • LL(2) case: If the input string is baa, the lookahead is ba. So the derivation starts with S  • Sa. But the a in Sa denotes the a at the right end of the derived string. So the input string • could be ba or baa. Therefore we don’t know which production to choose next. • LL(k) case: If the input string is ba…a with ka’s, the lookahead is ba…a with k – 1 a’s. So • the derivation after k –1 steps is S  Sa  Saa  …  Sa…a. Now, the input string could • be ba…a (length k) or ba…a (length k + 1). Therefore we don’t know which production to • choose next. • Sometimes we can obtain an LL(k) grammar by removing left recursion. • Algorithm Idea for direct left recursion: Transform: A Aw | Au | Av | a | b. To: A aB | bB B wB | uB | vB | L. Example/Quiz. Remove left recursion. S Sa | b. Solution. S bT T  aT | L. It is LL(1).

  5. Example/Quiz. Remove left recursion. S Saa | aab | aac. Solution: S aabT | aacT T  aaT | L. It is LL(3). Quiz: Rewrite the previous solution as LL(1). Solution: S aaU U  bT | cT T  aaT | L. Example (Removing indirect left recursion). Consider the following grammar. S Ab | a A  Sa | b. The grammar is left-recursive because of the indirect left recursion S  Ab  Sab. To remove the indirect left recursion, replace A in S Ab by the right side of A  Sa | b to obtain S Sab | bb. The grammar becomes S Sab | bb | a. Remove the left recursion: S bbT | aT T  abT | L. Quiz: Remove left recursion from the grammar: S Ab | a A  SAa | b. Solution: Replace A in S Ab | a by the right side of A  SAa | b to obtain S SAab | bb | a A  SAa | b. Now remove the direct left recursion: S bbT | aT T  AabT | L A  SAa | b.

  6. Top-Down Parsing of LL Languages LL(k) grammars have top-down parsing algorithms because a leftmost derivation can be constructed by starting at the start symbol and proceeding to the desired string. Example/Quiz. Consider the following LL(1) grammar. S aSC | b C  cC | d. The string aabcdd has the following leftmost derivation, where each step is uniquely determined by the current lookahead symbol. S  aSC  aaSCC  aabCC  aabcCC  aabcdC  aabcdd. Recursive Descent LL(1) Parsing A procedure is associated with each nonterminal. We’ll use the following procedure for LL(1) grammars to match a symbol with the lookahead symbol. match(x): if lookahead = xthen lookahead := next input symbol else error fi. Example. For the preceding example here are two possible recursive descent procedures: S: if lookahead = athen match(a); S; Celse match(b) fi. C: if lookahead = cthen matct(c); Celse match(d) fi. Quiz. Write recursive descent procedures for the following LL(1) grammar. S aaM M  bT | cT T aaT | L. Solution: S: match(a); match(a); M. M: if lookahead = b then match(b); T else match(c); T fi T: if lookahead = a then match(a); match(a); T fi

  7. Table-Driven LL(1) Parsing We’ll give an example showing how to use a table to parse a string. The details on how to construct such a table are a subject in compiler texts. Example. Consider the following LL(1) grammar and its corresponding parse table. Grammar: S aSb | L . Table: Parse of the string aabb: StackInputAction $ Sa a b b $ pop, p(b), p(S), p(a) $ b S aa a b b $ pop, consume $ b Sa b b $ pop, p(b), p(S), p(a) $ b b S aa b b $ pop, consume $ b b Sb b $ pop $ b b b b $ pop, consume $ bb $ pop, consume $ $ accept.

  8. Palindromes over {a, b} Context-free Deterministic C-F LL(k) Regular {an | n  N}  {anbn | n  N} (Text 789) {anbn | n  N} LL(k) Facts and Notes In 1969 Kurki-Suoni showed that the LL(k) languages form an infinite hierarchy: For each k there is an LL(k + 1) language that is not LL(k). Example. The language defined by the following grammar is LL(k + 1) but has no LL(k) grammar, where a…a stands for a k-length string of a’s. S  aSA | L A  a…abS | c. Example/Quiz. Why is the following grammar LL(2) but not LL(1)? S  aSA | L A  abS | c. Answer: Consider the string aab. A derivation must start with S  aSA. Now the lookahead is at the second a in aab, but there are two choices to pick from: S  aSA and S  L. So the grammar is not LL(1). But two lookahead letters allow the derivation to see the substring ab or ac, so that S  aSA can be chosen for the next step. The Picture:

More Related