syntax directed translation for top down parsing
play

Syntax-Directed Translation for Top-Down Parsing 1 Midterm next - PowerPoint PPT Presentation

Syntax-Directed Translation for Top-Down Parsing 1 Midterm next week during class online Covers everything up to and incl todays class Sample questions be posted on website Exam is multiple choice. 2 Last Time: Built LL(1) Predictive


  1. Syntax-Directed Translation for Top-Down Parsing 1

  2. Midterm next week – during class online Covers everything up to and incl today’s class Sample questions be posted on website Exam is multiple choice. 2

  3. Last Time: Built LL(1) Predictive Parser FIRST and FOLLOW sets define the parse table If the grammar is LL(1), the table is unambiguous • i.e., each cell has at most one entry If the grammar is not LL(1) we can attempt a transformation sequence: 1. Remove left recursion 2. Left-factoring Grammar transformations affect the structure of the parse tree. How does this affect syntax-directed translation (in particular, parse tree → AST)? 3

  4. Today Review parse-table construction – 2 examples Show how to do syntax-directed translation using an LL(1) parser 4

  5. FIRST(α) for α = Y 1 Y 2 … Y k FOLLOW(A) for X ⟶ α A β Add FIRST(Y 1 ) - {ε} If A is the start, add eof If ε is in FIRST(Y 1 to i-1 ): add FIRST(Y i ) – {ε} Add FIRST(β) – {ε} If ε is in all RHS symbols, add ε Add FOLLOW( X ) if ε in FIRST(β) or β empty Table[X][t] CFG for each production X ⟶ α S ⟶ B c | D B for each terminal t in FIRST( α ) B ⟶ a b | c S put α in Table[ X ][ t ] D ⟶ d | ε if ε is in FIRST( α ){ for each terminal t in FOLLOW(X){ Not LL(1) put α in Table[ X ][ t ] a b c d eof FIRST (S) = { a , c, d } FIRST (B) = { a , c } B c B c D B S FIRST (D) = { d , ε } D B FOLLOW (S) { eof, c } D B = FIRST (B c ) = { a , c } FOLLOW (B) = { c , eof } c S a b B FIRST (D B) = { d , a , c } { a, c } FOLLOW (D) = FIRST ( a b ) = { a } ε d ε D FIRST ( c S ) = { c } FIRST ( d ) = { d } FIRST (ε) = { ε } 5

  6. FIRST(α) for α = Y 1 Y 2 … Y k FOLLOW(A) for X ⟶ α A β Add FIRST(Y 1 ) - {ε} If A is the start, add eof If ε is in FIRST(Y 1 to i-1 ): add FIRST(Y i ) – {ε} Add FIRST(β) – {ε} If ε is in all RHS symbols, add ε Add FOLLOW( X ) if ε in FIRST(β) or β empty Table[X][t] CFG for each production X ⟶ α S → ( S ) | { S } | ε for each terminal t in FIRST( α ) put α in Table[ X ][ t ] if ε is in FIRST( α ){ for each terminal t in FOLLOW(X){ put α in Table[ X ][ t ] { { , ( , ε } FIRST ( S ) = FIRST ( ( S ) ) { ( } ( ) { } eof = FIRST ( { S } ) { { } = ε ε ε S ( S ) { S } FIRST ( ε ) { ε } = FOLLOW ( S ) { eof, ), } } = 6

  7. FIRST(α) for α = Y 1 Y 2 … Y k FOLLOW(A) for X ⟶ α A β Add FIRST(Y 1 ) - {ε} If A is the start, add eof If ε is in FIRST(Y 1 to i-1 ): add FIRST(Y i ) – {ε} Add FIRST(β) – {ε} If ε is in all RHS symbols, add ε Add FOLLOW( X ) if ε in FIRST(β) or β empty Table[X][t] CFG for each production X ⟶ α S → + S | ε for each terminal t in FIRST( α ) put α in Table[ X ][ t ] if ε is in FIRST( α ){ for each terminal t in FOLLOW(X){ put α in Table[ X ][ t ] { + , ε } FIRST ( S ) = FIRST ( + S ) { + } + eof = FIRST ( ε ) { ε } = ε S + S FOLLOW ( S ) { eof } = 7

  8. How’s that Compiler Looking? Scanner Scanner Tokens via RegEx table Parser Parser Parse Tree via Recursive Descent Semantic Anlaysis TODO: SDT on transformed CFG IR Codegen Optimizer MC Codegen 8

  9. Implementing SDT for LL(1) Parser So far, SDT shown as second (bottom-up) pass over parse tree The LL(1) parser never needed to explicitly build the parse tree (implicitly tracked via stack) Naïve approach: build the parse tree 9

  10. Semantic Stack Instead of building the parse tree, give parser second, semantic stack Translation goal: – Holds nonterminals’ translations Count the number of occurrences of • matched pairs of rounded parens: “ ( … )” SDT rules converted to actions on semantic stack • Ignore occurrences of matched pairs of square brackets: “ [ … ]” – Pop translations of RHS nonterms off – Push computed translation of LHS nonterm on SDT Rules SDT Actions CFG Expr ⟶ ε Expr.trans = 0 push 0 | ( Expr ) Expr.trans = Expr 2 .trans + 1 Expr 2 .trans = pop; push Expr 2 .trans + 1 | [ Expr ] Expr.trans = Expr 2 .trans Expr 2 .trans = pop; push Expr 2 .trans

  11. Action Numbers Need to define when to fire the SDT Action – Not immediately obvious since SDT is bottom-up Solution – Number actions and put them on the symbol stack! – Add action number symbols at end of the productions CFG SDT Actions Expr ⟶ ε #1 #1 push 0 | ( Expr ) #2 #2 Expr 2 .trans = pop; push Expr 2 .trans + 1 | [ Expr ] #3 #3 Expr 2 .trans = pop; push Expr 2 .trans

  12. Action Numbers: Example 1 CFG SDT Actions: Counting Max Parens Depth Expr ⟶ ε #1 #1 push 0 | ( Expr ) #2 #2 Expr 2 .trans = pop; push(Expr 2 .trans + 1) | [ Expr ] #3 #3 Expr 2 .trans = pop; push(Expr 2 .trans) [ ] ) EOF ( [ Expr ( Expr ) #2 [ Expr ] #3 ε #1 ε #1 ε #1 Expr #1 ] ( Expr #3 Root translation ) ( [ ] ) eof Expr #2 0 1 eof current current current current current Work Stack SemanticStack 12

  13. No-op SDT Actions CFG SDT Actions: Counting Max Parens Depth Expr ⟶ ε #1 #1 push 0 | ( Expr ) #2 #2 Expr 2 .trans = pop; push(Expr 2 .trans + 1) | [ Expr ] #3 #3 Expr 2 .trans = pop; push(Expr 2 .trans) Useless rule CFG SDT Actions: Counting Max Parens Depth Expr ⟶ ε #1 #1 push 0 | ( Expr ) #2 #2 Expr 2 .trans = pop; push(Expr 2 .trans + 1) | [ Expr ] 13

  14. A terminal symbol's value is available during the parse only when it is the Placing Action Numbers “current token.” We need to access the terminal symbol’s value before it is popped from the work stack Action numbers go after their corresponding • nonterminals, before their corresponding terminal Translations popped from action stack right-to-left • The predictive parser does a leftmost derivation, so the Translation goal: translation of Expr is performed first and pushed on the • Evaluate the expression semantic stack. The translation of Term is done later, so E.g., 5 + 3 * 2 produces 11 • its translation is pushed more recently than that of Expr CFG SDT Actions Expr ⟶ Expr + Term #1 #1 tTrans = pop ; eTrans = pop ; push(eTrans + tTrans) | Term #2 fTrans = pop; tTrans = pop ; push(tTrans * fTrans) #3 Term ⟶ Term * Factor #2 push( intlit .value) | Factor Factor ⟶ #3 intlit 14

  15. A terminal symbol's value is available during the parse only when it is the Placing Action Numbers “current token.” We need to access the terminal symbol’s value before it is popped from the work stack Action numbers go after their corresponding • nonterminals, before their corresponding terminal intlit Input: … intlit :17 … #3 Factor ⋮ current eof Work Stack Semantic Stack Problem: The push action can no longer access intlit .value; i.e., it cannot Let’s try putting the push 17 onto the semantic stack! action after intlit CFG SDT Actions . . . . . . #3 push( intlit .value) Factor ⟶ intlit #3 15

  16. A terminal symbol's value is available during the parse only when it is the Placing Action Numbers “current token.” We need to access the terminal symbol’s value before it is popped from the work stack Action numbers go after their corresponding • nonterminals, before their corresponding terminal #3 Input: … intlit :17 … intlit Factor ⋮ current 17 eof Work Stack Semantic Stack Correct! The push action can access intlit .value, and pushes 17 Let’s try putting the onto the semantic stack! action before intlit CFG SDT Actions . . . . . . #3 push( intlit .value) Factor ⟶ intlit #3 16

  17. Placing Action Numbers: Example Write SDT Actions and place action numbers to duct of a ValList (i.e., multiply all get the pr produc elements) SDT Actions CFG #1 LTrans = pop ; vTrans = pop ; push(LTrans * vTrans) List ⟶ Val List’ #1 List’ ⟶ Val List ’ #2 #2 LTrans = pop; vTrans = pop ; push(LTrans * vTrans) | ε #3 push(1) #3 #4 push( intlit .value) Val ⟶ #4 intlit 17

  18. Define the SDT using the original grammar (define • translation rules; convert to actions that push/pop using Action Numbers: Benefits the semantic stack; incorporate action numbers into the grammar rules). Then transform the grammar to be LL(1), treating the • Plans SDT actions using the work stack action numbers just like terminal symbols ! Robust to previously introduced grammar But treat all action numbers as ε when computing FIRST • and FOLLOW sets. (An action number is not actually a transformations! terminal symbol in the input stream of tokens.) Expr ⟶ Term Expr ’ CFG Expr’ ⟶ + Term #1 Expr ’ Expr ⟶ Expr + Term #1 | ε | Term Term ⟶ Factor Term’ Term ⟶ Term * Factor #2 Term’ ⟶ * Factor #2 Term’ | Factor | ε Factor ⟶ #3 intlit Factor ⟶ #3 intlit | ( Expr ) | ( Expr ) SDT Actions #1 tTrans = pop ; eTrans = pop ; push(eTrans + tTrans) #2 fTrans = pop; tTrans = pop ; push(tTrans * fTrans) 18 #3 push( intlit .value)

  19. Example: SDT on Transformed Grammar CFG SDT Actions Expr ⟶ Term Expr ’ #1 tTrans = pop ; eTrans = pop ; push(eTrans + tTrans) Expr ’ ⟶ + Term #1 Expr ’ #2 fTrans = pop; tTrans = pop ; push(tTrans * fTrans) | ε #3 push( intlit .value) Term ⟶ Factor Term’ Term’ ⟶ * Factor #2 Term’ | ε Factor ⟶ #3 intlit | ( Expr ) 19

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend