1 / 62

Chapter 5 Grammars and Parsers

Chapter 5 Grammars and Parsers. Prof Chung. Outlines. The LL(1) Predict Function The LL(1) Parse Table Building Recursive Descent Parsers from LL(1) Tables An LL(1) Parser Driver LL(1) Action Symbols Making Grammars LL(1) The If-Then-Else Problem in LL(1) Parsing.

Download Presentation

Chapter 5 Grammars and Parsers

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. Chapter 5 Grammars and Parsers Prof Chung.

  2. Outlines • The LL(1) Predict Function • The LL(1) Parse Table • Building Recursive Descent Parsers from LL(1) Tables • An LL(1) Parser Driver • LL(1) Action Symbols • Making Grammars LL(1) • The If-Then-Else Problem in LL(1) Parsing

  3. The LL(1) Predict Function • Given the productions • A1 • A2 • … • An • During a (leftmost) derivation • … A …  … 1 … or • … 2 … or • … n … • Deciding which production to match • Using lookahead symbols

  4. More Detail Operation at Next Page… The LL(1) Predict Function (1) • The limitation of LL(1) • LL(1) contains exactly those grammarsthat have disjoint predict sets for productions that share a common left-hand side Single Symbol Lookahead Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm)

  5. More Detail Operation at Next Page… The LL(1) Predict Function (2) • An LL(1) parse table T : Vnx Vt P  {Error} • The definition of T T[A][t] = AX1Xmif t  Prediction (AX1Xm); T[A][t] = Error otherwise

  6. More Detail Operation at Next Page… The LL(1) Parse Table (1)

  7. The LL(1) Parse Table (2) More Detail Operation at Next Page… 7

  8. More Detail Operation at Next Page… The LL(1) Parse Table (3)

  9. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 1 9

  10. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 2 2 2 10

  11. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 3 3 3 11

  12. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 4 12

  13. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 5 13

  14. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 6 14

  15. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 7 15

  16. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 8 16

  17. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 9 17

  18. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 10 18

  19. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 11 11 11 19

  20. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 12 20

  21. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 13 21

  22. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 14 22

  23. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 15 15 23

  24. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 16 16 16 24

  25. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 17 25

  26. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 18 26

  27. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 19 27

  28. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 20 28

  29. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 21 29

  30. Predict (AX1 …Xm )= If ∈ First (X1…Xm) ( First (X1…Xm) -  ) ∪Follow (A) else First (X1…Xm) 22 30

  31. The LL(1) Parse Table (3)

  32. Building Recursive Descent Parsers from LL(1) Tables (1) • Similar the implementation of a scanner • Build in • The parsing decisions recorded in LL(1) tables can be hardwired into the parsing procedures used by recursive descent parsers • Table-driven

  33. Building Recursive Descent Parsers from LL(1) Tables (2) • The form of parsing procedure: • non_term() [Function Code] • It is the name of the nonterminal the parsing procedure handles. • case TERMINAL_LIST • …… • default • statement () [Function Code] • An algorithm that automatically creates parsing procedures • case ID • case READ • case WRITE • default

  34. Building Recursive Descent Parsers from LL(1) Tables (3) • Describing grammars • Data Structure [Function Code] • Setup Describing grammars Data Structure. • gen_actions() [Function Code][Example] • Takes the grammar symbols and generates the actions necessary to match them in a recursive descent parse • make_parsing_proc() [Function Code] • Generae recursive descent parsing procedure for A. • for each production where A is the LHS • for each terminal in the grammar

  35. An LL(1) Parser Driver (1) • Rather than using the LL(1) table to build parsing procedures • it is possible to use the table in conjunction with a driver program to form an LL(1) parser • Smaller and fasterthan a corresponding recursive descent parser • Changing a grammar and building a new parser is easy • LL(1) driver [Function Code] • computed and substitutedfor the old tables

  36. LL(1) Action Symbols (1) • During parsing, the appearance of an action symbolin a production will serve to initiate the corresponding semantic action – a call to the corresponding semantic routine. • The semantic routine calls pass no explicit parameters • LL(1) driver Action Symbols [Function Code] • Necessary parameters are transmitted through a semantic stack • Semantic stackparse stack[Compare. @ Next page] • Semantic stack is a stack of semantic records • Action symbols are pushed to the parse stack

  37. LL(1) Action Symbols (2) • Compare • Parse Stack • In recursive descent parsers, the parse stack is “hidden” in the procedure call stack of the running compiler. • Semantic Stack • “Parse Stack” extended. • The semantic stack can be hidden that way as well, by having each parsing routine return a semantic record.

  38. Making Grammars LL(1) • Not all grammars are LL(1). • LR • LR(1) • SLR(1) • Some non-LL(1) grammars can be made LL(1) by simple modifications.

  39. Making Grammars LL(1) ID 2,5 <stmt> 39 When a grammar is not LL(1) ? This is called a Conflict, which means we do not knowwhich production to use when <stmt> is on stack top and ID is the next input token.

  40. Making Grammars LL(1) • Major LL(1) prediction conflicts • Common prefixes • Left recursion • Common prefixes • <stmt>  if <exp> then <stmt> • <stmt>  if <exp> then <stmt> else <stmt> • Solution: factoring transform • See Next Page.

  41. Making Grammars LL(1) void factor (grammar *G) { while (G has 2 or more productions with the same LHS and a common prefix) { Let S = { Aαβ, …, Aαξ } be the set of productions with the same left-hand side, A, and a common prefix, α; Create a new nonterminal, N; Replace S with the production set SET_OF (AαN, Nβ, …, Nξ); } } <stmt>  if <exp> then <stmt list> <if suffix> <if suffix>  end if; <if suffix>  else <stmt list> end if;

  42. Making Grammars LL(1) • Grammars with left-recursive production can never be LL(1) A  A  • Why? • A will be the top stack symbol, and hence the same production would be predicted forever

  43. ANT N … N  T T T  AA A … A Making Grammars LL(1) • Solution: void remove_left_recursion (grammar *G) { while ( G contains a left-recursive nonterminal) { Let S = {AA ,A , …, Aζ} be the set of production with the same left-hand side, A, where A is left-recursive. cerate two new nonterminals, T and N; Replace S with the production set SET_OF (AN T, Nβ, …, Nξ, T  T, Tλ); } }

  44. ID 2,3 <stmt> Making Grammars LL(1) • Other transformation may be needed • No common prefixes, no left recursion • <stmt>  <label> <unlabeled stmt> • <label>  ID : • <label>  • <unlabeled stmt>  ID := <exp> ;

  45. Making Grammars LL(1) • Example Grammar: • <stmt>  ID <suffix> • <suffix>  : <unlabeled stmt> • <suffix>  := <exp> ; • <unlabeled stmt>  ID := <exp> ;

  46. Making Grammars LL(1) • In Ada, we may declare arrays as • A: array(I .. J, BOOLEAN) • A straightforward grammar for array bound • <array bound>  <expr> .. <expr> • <array bound>  ID • Solution • <array bound>  <expr> <bound tail> • <bound tail>  .. <expr> • <bound tail>  

  47. Making Grammars LL(1) • Greibach Normal Form • Every production is of the form Aa • a is a terminal and  is a string (possible empty) of symbols • Every context-free language L without  can be generated by a grammar in Greibach Normal Form • Factoring of common prefixes is easy • Given a grammar G, we can • G  GNF  No common prefixes, no left recursion (butstill may notbe LL(1))

  48. The If-Then-Else Problem in LL(1) Parsing • “Dangling else” problem in Algo60, Pascal, and C • else clause is optional • BL={[i]j | ij 0} [  if <expr> then <stmt> ]  else <stmt> • BL is not LL(1) and in fact not LL(k) for any k

  49. S S [ S CL [ S CL [ S CL ] [ S CL     ] The If-Then-Else Problem in LL(1) Parsing • First try • G1: S  [ S CL S   CL  ] CL   • G1 is ambiguous: E.g., [[]

  50. S [ S1 [ S1 ]  The If-Then-Else Problem in LL(1) Parsing • Second try • G2: S  [S S  S1 S1  [S1] S1   • G2 is not ambiguous: E.g., [[] • The problem is [ First([S) and [  First(S1) [[  First2([S) and [[  First2 (S1) • G2 is not LL(1), nor is it LL(k) for any k.

More Related