Announcement: Midterm Prep Midterm is Tuesday, 3/13 at 11 in three classrooms - Last name A-C Van Vleck B115 - Last name D-J Van Vleck B135 - Last name K-Z CS1240 List of topics Up to and including lecture on Tuesday s the 6th Length 1hr 10min No extra material allowed just bring a pen Sample midterm available online Recommended that you do this by Thursday We ll review it in class 1
Syntax Directed Transla2on for Top-Down Parsing 2
Last Time: Built LL(1) Predic[ve Parser FIRST and FOLLOW sets define the parse table If the grammar is LL(1), the table is unambiguous If the grammar is not LL(1) we can a`empt a transforma[on sequence: 1. Remove lec recursion 2. Lec-factoring 3
Today Review Parse Table Construc[on 2 examples Show how to do Syntax-Directed Transla[on using an LL(1) parser 4
FIRST(α) for α = Y 1 Y 2 Y k Add FIRST(Y 1 ) - {ε} If ε is in FIRST(Y 1 to i-1 ): add FIRST(Y i ) {ε} If ε is in all RHS symbols, add ε FOLLOW(A) for X α A β If A is the start, add eof Add FIRST(β) {ε} Add FOLLOW(X) if ε in FIRST(β) or β empty Table[X][t] for each production X α 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] S B D Not LL(1) B c D B a b c S d ε FIRST (S) = { a, c, d } FIRST (B) = { a, c } FIRST (D) = { d, ε } FIRST (B c) = { a, c } FIRST (D B) = { d, a, c } FIRST (a b) = { a } FIRST (c S) = { c } FIRST (d) = { d } FIRST (ε) = { ε } FOLLOW (S) = { eof, c } FOLLOW (B) = { c, eof } FOLLOW (D) = { a, c } S B D a b c d eof B c B c D B D B D B a b ε c S ε d 5
FIRST(α) for α = Y 1 Y 2 Y k Add FIRST(Y 1 ) - {ε} If ε is in FIRST(Y 1 to i-1 ): add FIRST(Y i ) {ε} If ε is in all RHS symbols, add ε FOLLOW(A) for X α A β If A is the start, add eof Add FIRST(β) {ε} Add FOLLOW(X) if ε in FIRST(β) or β empty Table[X][t] for each production X α 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] S ( S ) { S } ε FIRST (S) = { {, (, ε } FIRST ( ( S ) ) = { ( } FIRST ( { S } ) = { { } FIRST ( ε ) = { ε } FOLLOW ( S ) = { eof, ), } } S ( ) { } eof ( S ) ε { S } ε ε 6
FIRST(α) for α = Y 1 Y 2 Y k Add FIRST(Y 1 ) - {ε} If ε is in FIRST(Y 1 to i-1 ): add FIRST(Y i ) {ε} If ε is in all RHS symbols, add ε FOLLOW(A) for X α A β If A is the start, add eof Add FIRST(β) {ε} Add FOLLOW(X) if ε in FIRST(β) or β empty Table[X][t] for each production X α 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] S + S ε FIRST (S) = { +, ε } FIRST ( + S ) = { + } FIRST ( ε ) = { ε } FOLLOW ( S ) { eof } = S + eof + S ε 7
How s that Compiler Looking? Scanner Tokens via RegEx table Parser Parse Tree via Recursive Descent Seman2c Anlaysis IR Codegen TODO: SDT on transformed Op2mizer MC Codegen 8
Implemen[ng SDT for LL(1) Parser So far, SDT shown as second (bo`om-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 explicitly 9
Seman[c Stack Instead of building the parse tree, give parser second, seman&c stack Holds nonterminals transla[ons SDT rules converted to ac[ons on seman[c stack Pop transla[ons of RHS nonterms off Push computed transla[on of LHS nonterm on SDT Rules SDT AcJons Expr ε ( Expr ) [ Expr ] Expr.trans = 0 Expr.trans = Expr 2.trans + 1 Expr.trans = Expr 2.trans push 0 Expr 2.trans = pop; push Expr 2.trans + 1 Expr 2.trans = pop; push Expr 2.trans
Ac[on Numbers Need to define when to fire the SDT Ac[on Not immediately obvious since SDT is bo`om-up Solu[on Number ac[ons and put them on the symbol stack! Add ac[on number symbols at end of the produc[ons Expr ε #1 ( Expr ) [ Expr ] #3 #1 #3 SDT AcJons push 0 Expr 2.trans = pop; push Expr 2.trans + 1 Expr 2.trans = pop; push Expr 2.trans
Ac[on Numbers: Example 1 Expr ε #1 ( Expr ) [ Expr ] #3 #1 #3 SDT AcJons: CounJng Max Parens Depth push 0 Expr 2.trans = pop; push(expr 2.trans + 1) Expr 2.trans = pop; push(expr 2.trans) ( [ ] ) EOF [ Expr ( Expr ) [ Expr ] #3 ε #1 ε #1 ε #1 Expr #1 ]( Expr #3 ) Expr Root transla2on ( [ ] ) eof eof Work Stack 01 current current current current current Seman2cStack 12
No-op SDT Ac[ons Expr ε #1 ( Expr ) [ Expr ] #3 #1 #3 SDT AcJons: CounJng Max Parens Depth push 0 Expr 2.trans = pop; push(expr 2.trans + 1) Expr 2.trans = pop; push(expr 2.trans) Useless rule Expr ε #1 ( Expr ) [ Expr ] #1 SDT AcJons: CounJng Max Parens Depth push 0 Expr 2.trans = pop; push(expr 2.trans + 1) 13
Placing Ac[on Numbers Ac[on numbers go acer their corresponding nonterminals, before their corresponding terminal Transla[ons popped right to lec in ac[on Expr Expr + Term #1 Term Term Term * Factor Factor Factor #3 intlit SDT AcJons #1 ttrans = pop ; etrans = pop ; push(ttrans + etrans) ftrans = pop; ttrans = pop ; push(ftrans * ttrans) #3 push(intlit.value) 14
Placing Ac[on Numbers: Example Write SDT Ac[ons and place ac[on numbers to get the product of a ValList (i.e. mul[ply all elements) List Val List #1 List Val List ε #3 Val #4 intlit SDT AcJons #1 LTrans = pop ; vtrans = pop ; push(ltrans * vtrans) LTrans = pop; vtrans = pop ; push(ltrans * vtrans) #3 push(1) #4 push(intlit.value) 15
Ac[on Numbers: Benefits Plans SDT ac[ons using the work stack Robust to previously introduced grammar transforma[ons Expr Expr + Term #1 Term Term Term * Factor Factor Factor #3 intlit Expr Term Expr Expr + Term #1 Expr ε Term Factor Term Term * Factor Term ε Factor #3 intlit #1 #3 SDT AcJons ttrans = pop ; etrans = pop ; push(ttrans + etrans) ftrans = pop; ttrans = pop ; push(ftrans * ttrans) push(intlit.value) 16
Example: SDT on Transformed Grammar Expr Term Expr Expr + Term #1 Expr ε Term Factor Term Term * Factor Term ε Factor #3 intlit #1 #3 SDT AcJons ttrans = pop ; etrans = pop ; push(ttrans + etrans) ftrans = pop; ttrans = pop ; push(ftrans * ttrans) push(intlit.value) On board: 5 + 3 * 2 17
What about ASTs? Push and pop AST nodes on the stack Keep field references to nodes that we pop Expr Expr + Term #1 Term Term intlit #1 EvaluaJon SDT AcJons ttrans = pop ; etrans = pop ; push(etrans + ttrans) push(intlit.value) Transformed Expr Term Expr Expr + Term #1 Expr ε Term intlit #1 AST SDT AcJons ttrans = pop ; etrans = pop ; push(new PlusNode(tTrans, etrans)) push(new IntLitNode(intlit.value))
AST Example intlit + EOF Transformed AST SDT AcJons E T E #1 ttrans = pop ; E T E etrans = pop ; E + T #1 E E push(new PlusNode(tTrans, etrans)) ε T intlit push(new IntLitNode(intlit.value)) T intlit + T #1 E ε 1 + 2 + 3 eof PlusNode + current current current current current intlit T intlit #1 T E eof Work Stack Seman2c Stack PlusNode IntLitNode Value: 1 IntLitNode Value: 2 IntLitNode Value: 3 19
We now have an AST At this point, we have completed the frontend for (a) compiler Only recognize LL(1) LL(1) is not a great class of languages if (e1) stmt1 if (e2) stmt2 else stmt3 Grammar Snippet IfStmt -> if lparens Exp rparens Stmts if lparens Exp rparens Stmts else Stmts 20