What is the difference between a synthesized attribute and an inherited attribute? Define each of those terms.
You are given the following (ambiguous) grammar for expressions.
expr -> expr + expr expr -> expr * expr expr -> NUM expr -> VARwhere 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_INT k | Push integer k onto the stack |
PUSH_VAR k | Push the value of the variable at offset k onto the stack|
ADD | Pop the top two numbers from the stack and push their sum |
MULT | Pop the top two numbers from the stack and push their product |
Write semantic actions to be performed at each production that will generate code to compute a given expression and leave its value on the top of the stack. Do not worry that the grammar is ambiguous. That is a parsing problem, not a semantic one.
This is the same as the preceding exercise, but instead of performing actions to generate the code, you would like to create the code sequence as an attribute of an expression nonterminal. Suppose that, in addition to get_var_offset(v), the following functions are available. single(I) produces, as its value, a sequence that represents the single-part instruction I. doub(I,k) produces a code sequence for a two-part instruction. Operator + can be used to compute the concatenation of two code sequences.
Exercise 8.14 of the text. Assume that a Boolean expression can be passed inherited attributes E.true and E.false telling it where to jump to if the expression is true. Generate label instructions as in the text.
If your parser works by building syntax trees instead of directly writing translations, how can it handle the C for loop in a simpler way than is done in solving exercise 8.14 of the text?
How can attributes be used to perform type inference in a language such as Pascal?
Dataflow analysis is used to determine
Why is register allocation one of the more important aspects of optimization?
What is the definition of a basic block?
How does a type checker determine type information about a program when types are polymorphic, and can include type variables?