1 / 21

LL(1) Parsing

LL(1) Parsing. Programming Language Concepts Lecture 7. Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida. Example. Build the LL(1) parse table for the following grammar. S → begin SL end {begin} → id := E; {id} SL → SL S {begin,id} → S {begin,id}

egil
Download Presentation

LL(1) Parsing

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. LL(1) Parsing Programming Language Concepts Lecture 7 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida

  2. Example • Build the LL(1) parse table for the following grammar. S →begin SL end {begin} → id := E; {id} SL → SL S {begin,id} →S {begin,id} E → E+T {(, id} → T {(, id} T → P*T {(, id} →P {(, id} P → (E) {(} → id {id} * * * * - not LL(1)

  3. Example (cont’d) • Lemma: Left recursion always produces a non-LL(1) grammar (e.g., SL, E above) • Proof: Consider A → A First () or Follow (A) →  First () Follow (A)

  4. Problems with our Grammar • SL is left recursive. • E is left recursive. • T → P * T both begin with the same→ P sequence of symbols (P).

  5. Solution to Problem 3 • Change: T → P * T { (, id } → P { (, id } • to: T → P X { (, id } X →* T { * } → { +, ; , ) } Follow(X) • Follow(T) due to T → P X • Follow(E)due to E → E+T , E → T = { +, ;, ) } due to E →E+T, S→id := E ; and P → (E) Disjoint!

  6. Solution to Problem 3 (cont’d) • In general, change A → 1 → 2 . . . → n to A → X X →1 . . . →n Hopefully all the’s begin with different symbols

  7. Solution to Problems 1 and 2 • We want (…((( T + T) + T) + T)…) • Instead, (T) (+T) (+T) … (+T) Change: E → E + T { (, id } → T { (, id } To: E → T Y { (, id } Y → + T Y { + } → { ; , ) } • Follow(Y) Follow(E) • = { ; , ) } No longer contains ‘+’, because we eliminated the production E → E + T

  8. Solution to Problems 1 and 2 (cont’d) • In general, Change:A → A1 A →  1 . . . . . . → An → m to:A → 1 X X → 1X . . . . . . →m X→nX →

  9. Solution to Problems 1 and 2 (cont’d) • In our example, Change:SL → SL S { begin, id } → S { begin, id } To:SL → S Z { begin, id } Z →S Z { begin, id } → { end }

  10. Modified Grammar S → begin SL end {begin} → id := E ; {id} SL → S Z {begin,id} Z →S Z {begin,id} → {end} E → T Y (,id} Y → + T Y {+} → {;,)} T → P X {(,id} X → * T {*} → {;,+,)} P → (E) {(} → id {id} Disjoint. Grammar is LL(1)

  11. Recursive Descent Parsing • Top-down parsing strategy, suitable for LL(1) grammars. • One procedure per nonterminal. • Contents of stack embedded in recursive call sequence. • Each procedure “commits” to one production, based on the next input symbol, and the select sets. • Good technique for hand-written parsers.

  12. For our Modified, LL(1) Grammar proc S; {S → begin SL end → id := E; } case Next_Token of T_begin : Read(T_begin); SL; Read (T_end); T_id : Read(T_id); Read (T_:=); E; Read (T_;); otherwise Error; end end; “Read (T_X)” verifies that the upcoming token is X, and consumes it. “Next_Token” is the upcoming token.

  13. For our Modified, LL(1) Grammar (cont’d) proc SL; {SL → SZ} S; Z; end; proc E; {E → TY} T; Y; end; Technically, should have insisted that Next Token be either T_begin or T_id, but S will do that anyway. Checking early would aid error recovery. // Ditto for T_( and T_id.

  14. For our Modified, LL(1) Grammar (cont’d) proc Z;{Z → SZ → } case Next Token of T_begin, T_id: S;Z; T_end: ; otherwise Error; end end;

  15. For our Modified, LL(1) Grammar (cont’d) proc Y; {Y → +TY → } if Next Token = T_+ then Read (T_+) T; Y; end; proc T; {T → PX} P; X end; Could have used a case statement Could have checked for T_( and T_id.

  16. For our Modified, LL(1) Grammar (cont’d) proc X;{X → *T → } if Next Token = T_* then Read (T_*); T; end;

  17. For our Modified, LL(1) Grammar (cont’d) proc P; {P →(E) → id } case Next Token of T_(: Read (T_(); E; Read (T_)); T_id: Read (T_id); otherwise Error; end end;

  18. LL(1) Parsing Programming Language Concepts Lecture 7 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida

More Related