A synthesized attribute is defined for a node v in terms of the attributes of the children of v. Any attribute that is not synthesized is called inherited.
Sometimes it is desirable to use only synthesized attributes in your parser. Is it always possible to do that, even if your semantics requires inherited attributes? If so, how can you deal with complex semantics while only using synthesized attributes in the parser. If not, what prevents you from using only synthesized attributes?
You can use only synthesized attributes in the parser by building syntax trees there, and passing those syntax trees to semantic processing routines. The semantic processing is free to make many passes over the syntax trees, even though the parser makes only one bottom-to-top traversal of the parse tree.
Exercise 6.6 of the text contains a grammar that describes binary trees where each node of the tree has an integer label. It discusses an ordering requirement that is the same one required by binary search trees. Solve that exercise.
Solved in class using synthesized attributes. Think about what you need to remember about each subtree. It suffices to remember the smallest value and largest value in the subtree, and whether the subtree obeys the ordering requirements. Attribute equations then follow easily.
You are given the following (ambiguous) grammar for expressions.
expr -> expr + expr expr -> expr * expr expr -> NUM expr -> VAR where NUM and VAR are tokens. The lexer provides an attribute NUM.val that is the (integer) value of a NUM token. It also provides an attribute VAR.name that is the name of a variable. You would like to translate these expressions into instructions for a stack machine. The stack machine has the following instructions. Push the value of the variable at offset k onto the stack
PUSH_INT k Push