Download Understanding Attribute Grammars: A Mechanism for Specifying Static Semantics - Prof. Jon and more Exams Programming Languages in PDF only on Docsity! c 2007 by Spencer Rugaber FORMALIZING STATIC SEMANTICS ATTRIBUTE GRAMMARS (KNUTH) • Attribute grammars are a mechanism that extends BNF in order to specify context sensitive properties of the strings in a language and some of their semantics, such as declarations and type checking – Each grammar symbol has an associated set of attributes (named, typed values) – Productions have functions added to them to assign values to the attributes – The parse tree is walked, evaluating the rules at each node c 2007 by Spencer Rugaber ATTRIBUTES • Attributes are typed variables associated with grammar symbols (terminals and nonterminals) − For example, attributes can store symbol table information to facilitate semantic checking − Attributes can also hold Boolean state information to help control the parsing process itself • In principle, an attribute could just copy the input text associated with its node in the AST and pass it up the tree. The root node could then do all of the processing − Hence, attribute grammars are powerful enough to do anything any other compilation technique can do • An algorithm exists to test for the circularity of attribute dependencies in an attribute grammar c 2007 by Spencer Rugaber GRAMMAR FOR PARSING BOOLEAN NUMBERS 1. B ::= '0' 2. B ::= '1' 3. L ::= B 4. L 1 ::= L 2 B 5. N ::= L 6. N ::= L 1 '.' L 2 Using this grammar, what would a parse tree look like for the following input? "1101.01" Ignore the subscripts; they are there to distinguish the two occurrences of L within rules c 2007 by Spencer Rugaber PARSE TREE N L L BB 10. L B 1 L B 0 L L BB 11 6 3 212122 3 4 4 4 4 Numbers in ovals denote the grammar rule used to reduce the children of the numbered node c 2007 by Spencer Rugaber EVALUATION • To demonstrate attribute grammars, we will show one that can compute the value of a Boolean number – Input is a character string such as '1101.01' – Output is a number such as 13.25 • As with all semantic evaluation schemes, we will build the meaning of a large thing from the meaning of its pieces: – Individual lexemes – Nonterminal phrases c 2007 by Spencer Rugaber ATTRIBUTES scaleSL valueVL lengthLL valueVN scaleSB valueVB DescriptionAttributeNon-terminal Each row in the table defines a different attribute, even if the name is overloaded c 2007 by Spencer Rugaber KINDS OF ATTRIBUTES • Attributes are either synthesized or inherited, but not both –Synthesized attributes derive their values from the values of child nodes in the parse tree. That is, the attribute's non-terminal is on the left-hand side of a rule, and the function for that rule gives it a value • Syntax rule: Ax ::= By Cz Semantic rule: x = f(y, z) – Inherited attributes derive their values from their parents in the parse tree. The attribute's non-terminal is on the right-hand-side of a c 2007 by Spencer Rugaber DEFINING RULES • The next step defines the evaluation rules • Each attribute of each symbol in each production may have an associated rule • Evaluation occurs by walking the parse tree and executing the rules • Moreover, during evaluation the parse tree may be walked multiple times c 2007 by Spencer Rugaber LISTS • The value of the V(L) is derived from V(B) in the natural way • There are two rules to consider 3. L ::= B 4. L1 ::= L2 B • In the case of rule 3, the value of V(L) is exactly V(B); i.e. V(L) = V(B); • In the case of rule 4, we must distinguish the two occurrences of the symbol L • The corresponding rule is – V(L1) = V(L2) + V(B); c 2007 by Spencer Rugaber NUMBERS • The value of V(N) depends in a natural way on the values of the V attributes of the lists that comprise it • There are two rules 5. N ::= L 6. N ::= L1 '.' L2 • The corresponding rules are, respectively – V(N) = V(L); – V(N) = V(L1) + V(L2); c 2007 by Spencer Rugaber NUMBERS • The value rules are summarized in the following table V(N) = V(L 1 ) + V(L 2 );N ::= L1 '.' L26 V(N) = V(L);N ::= L5 V(L 1 ) = V(L 2 ) + V(B);L1 ::= L2 B4 V(L) = V(B);L ::= B3 V(B) = 2S(B);B ::= '1'2 V(B) = 0;B ::= '0'1 SemanticsSyntaxRule # • Note that all of V(B), V(L) and V(N) are synthesized attributes • The actual evaluation process for V proceeds bottom up on the parse tree, as depicted in the next slide c 2007 by Spencer Rugaber PROPAGATING L UPWARD N L L BB 10 L B 1 L B 0 L L BB 11 4 33 4 4 L(L) = 4 L(L) = 3 . L(L) = 2 L(L) = 1 L(L) = 2 L(L) = 1 4 c 2007 by Spencer Rugaber SCALE • Because scale depends on length, it must be computed after the evaluation of L is finished • That is, an upward evaluation pass is made on the parse tree to compute L. Then L(L) is used to compute S on a downward pass • This make S an inherited attribute c 2007 by Spencer Rugaber SCALE RULES S(L 1 ) = 0; S(L 2 ) = -L(L 2 ) N ::= L 1 '.' L 2 6 S(L) = 0N ::= L5 S(B) = S(L 1 ); S(L 2 ) = S(L 1 ) + 1; L 1 ::= L 2 B4 S(B) = S(L);L ::= B3 SemanticsSyntaxRule # • Here are the rules for S – Note that S(L) differs in sign depending on whether L is to the left or to the right of the binary point • The downward pass over the parse tree can be seen in the next slide c 2007 by Spencer Rugaber SUMMARY - 2 • The grammar uses of the following evaluation rules V(N) = V(L1) + V(L2); S(L1) = 0; S(L2) = -L(L2); N ::= L 1 '.' L 2 6 V(N) = V(L); S(L) = 0; N ::= L5 V(L1) = V(L2) + V(B); S(B) = S(L1); S(L2) = S(L1) + 1; L(L1) = L(L2) + 1; L 1 ::= L 2 B4 V(L) = V(B); S(B) = S(L); L(L) = 1; L ::= B3 V(B) = 2S(B);B ::= '1'2 V(B) = 0;B ::= '0'1 SemanticsSyntaxRule # c 2007 by Spencer Rugaber SUMMARY - 3 • The evaluation process comprised three passes over the parse tree – An upward pass to compute the lengths of the two bits strings – A downward pass to compute the scale attributes – A final upward pass to compute the value • It is possible to evaluate the string in fewer passes. Can you see how? c 2007 by Spencer Rugaber STATE OF THE PRACTICE • Attribute grammars are a mature technology that has been folded into some, but not all, parser generator tools – Yacc, for example, is not attribute based, but it does provide a mechanism for accessing the results of child nodes in the parse tree when performing a reduction