CS453 Colorado State University ========================================== Syntax-Directed Evaluation and Shift-Reduce Parsing ========================================== ------------- Plan for today Review main idea of syntax-directed evaluation and translation Recall syntax-directed evaluation in recursive descent, predictive parser Syntax-directed evaluation and translation in shift-reduce parser Syntax-directed code generation for PA3 ------------- Syntax-directed evaluation and translation (brief overview) - Do NOT create a parse tree explicitly. - As we parse evaluate sub expressions and pass values up the implicit parse tree. - When get to non-expression production, then we generate code to a file. [Have students point these out in PA3 grammar] ----------------------------------------- Syntax-directed evaluation of expressions (brief review) (slides 2 thru 4) -associate an action or rule with each production -often uses attributes associated with nodes. Can think of the nodes as being mapped to various attributes. Example: Assume each node in parse tree is mapped to an integer value. The book uses notation expr.t. We will use the JavaCUP syntax where RESULT is the value mapped to the lhs of the production and the variable associated with the token (token:var) holds the value mapped to the token. expr -> expr:e1 + expr:e2 {: RESULT = e1 + e2; :} expr -> expr:e1 * expr:e2 {: RESULT = e1 * e2; :} expr -> NUM:n {: RESULT = n; :} -> semantic actions are applied in depth-first post order procedure visit(node N) { for each child C of N, from left to right visit(C) execute semantic action ------------------------------- Syntax-directed evaluation, or interpretation, in recursive descent parser (slide 5) While parsing, store information in local variables and then use that information to do the interpretation. Implicit parse tree is "built" top down. Evaluation still occurs bottom up because doing interpretation after function calls to parse children. Order of parse corresponds to left-most derivation. [ Could have functions return a value. ] ------------------------------- Syntax-directed evaluation and translation in shift-reduce parser (slides 6) Shift-reduce parsing performs a reverse right-most derivation Shift-reduce parsing of some unambiguous grammars Shift-reduce parsing of some ambiguous expression grammars Shift-reduce parsing algorithm used by generated LR parser Shift-reduce parsing and syntax-directed evaluation and translation ------------------------------ Shift-reduce parsing (slide 7) form of bottom-up parsing - “builds” the parse tree from the leaves to the roots - performs a right-most derivation in reverse - a reduction is the reverse of a derivation step - the handle is the substring that matches a production rhs and is replaced with the nonterminal on the lhs shift-reduce parsing - grammar symbols held on the stack and token stream is in input buffer - possible actions Shift: consume the token from input and push onto stack Reduce: replace right-hand side of a production rule on the top of the stack with the left-hand side nonterminal for that rule Accept: indicate that parsing is complete Error: indicate there is a parsing error ------------------------------------------------- Shift-reduce parsing of some unambiguous grammars slides 8 and 9 For each of the below examples do the following: - first do the right-most derivation - then do the shift-reduce parse by following the right-most derivation in reverse (1) S’ -> E $ (2) E -> E + T (3) E -> T (4) T -> T * F (5) T -> F (6) F -> ( E ) (7) F -> NUM Stack Input Action $ 42 + 6 * 7 $ ------------------- [0] S -> ( S ) [1] S’ -> S EOF [2] S -> ID Stack Input Action $ ( ( a ) ) $ ------------------------------------------------- Shift-reduce parsing of some ambiguous grammars (slides 10 and 11) For each of the below examples do the following: - first do the right-most derivation - then do the shift-reduce parse by following the right-most derivation in reverse - note how precedence and associativity declarations can resolve shift-reduce conflicts (1) S’ -> E $ (2) E -> E + E (3) E -> E * E (4) E -> ( E ) (5) E -> NUM Stack Input Action $ 42 + 6 * 7 $ ------------------- (1) S’ -> E $ (2) E -> E + E (3) E -> ( byte ) E (4) E -> NUM Stack Input Action $ ( byte ) 3 + 4 $ Summary on precedence and associativity in JavaCUP Tokens and productions are given precedence. Tokens are given precedence level in precedence declarations. Productions are given precedence level of last token on right-hand side. When in shift-reduce conflict, shift if look ahead token has higher precedence than reduce production reduce if reduce production has higher precedence than the look ahead token Within the same precedence level associativity determines whether to shift or reduce. left associativity results in a reduce right associativity results in a shift Suggested Exercise: Do we need to declare a precedence or associativity for E -> ( E )? Try some examples and say why or why not? Input examples: ( 3 + 4 ) * 5 5 - ( 2 - 3 ) ----------------------- LR parse tables (slide 13) - LR(k) parser is a kind of shift-reduce parser - left-to-right parse - rightmost derivation - k-token look ahead - You can find another good example in the book and on wikipedia entry for LR parser. Doing examples is important to aid in understanding and study for the midterm and final. - rules for the parse table Look at state at top of stack and input symbol to find action in table shift(n): advance input, push state n on stack - Putting input on stack as well to help us humans keep track. As is described in the book, computers just need the state numbers. reduce(k): pop rhs of grammar rule k look up state on top of stack and lhs for goto n push lhs(k) and n onto stack accept: stop and success error: stop and fail - Parsing the string ((a)) using the LR parse table generate by by JavaCUP. - See slide for grammar and LR parse table. Stack Input Action $0 ((a))$ shift 3 $0(3 (a))$ shift 3 $0(3(3 a))$ shift 1 $0(3(3a1 ))$ reduce by [3] S -> ID, goto 4 $0(3(3S4 ))$ shift 5 $0(3(3S4)5 )$ reduce by [0] S -> ( S ), goto 4 $0(3S4 )$ shift 5 $0(3S4)5 $ reduce by [0] S -> ( S ), goto 2 $0S2 $ accept -------------------------------------------------------------- Syntax-directed expression evaluation and shift-reduce parsing The values associated with nonterminals can be stored on the stack. --------------------------------------- Syntax-directed code generation for PA3 - how do you make a variable like a file handle available throughout the parser? - for which production should the prologue and epilogue be printed? - for what other productions is code gen necessary? ------------------------ mstrout@cs.colostate.edu, 2/22/11