Professional Documents
Culture Documents
Chapter V: Syntax Directed Translation
Chapter V: Syntax Directed Translation
Parsing an input to do nothing about it is useless. In fact, an input is parsed so that some code is
generated, an information is displayed, etc. These different actions are done by the semantic actions
associated to the different rules of the grammar.
To execute these actions the parsing table may or may not be constructed first. Indeed, the best solution
performance-wise is to execute the actions while producing the parse tree.
Syntax directed definitions
A syntax directed definition is a generalization of the CFG in which each grammar symbol has an
associated set of attributes (synthesized and inherited). An attribute can represent anything we choose (
a string, a number, a type, a memory location, etc.).
The value of a synthesized attribute is computed from the values of attributes at the children of that
node in the parse tree. The value of an inherited attribute is computed from the values of attributes at
the siblings and parent of that node in the parse tree.
Semantic rules calculate the values of attributes hence set-up dependencies between attributes that will
be represented by a graph. The dependency graph enables to find an evaluation order for the semantic
rules.
A parse tree showing the values of the attributes is called an annotated or decorated parse tree.
In the above example, everything is calculated from leaves to root; all attributes are synthesized.
Thus all the attributes can be calculated in a single pass.
1
L1.s = 0
L2.s = -L2.l
L1 Æ L2 B L1.l = L2.l + 1
L2.s = L1.s + 1
B.s = L1.s
L1.v = L2.v + B.v
L ÆB L.v = B.v
L.l = 1
B.s = L.s
B Æ0 B.v = 0
B Æ1 B.v = 1 * 2B.s
Exercise: Draw the decorated parse tree for input 1011.01
Formal definition
In a syntax directed definition, each grammar production A --> α has associated with it a set of
semantic rules of the form:
b := f (c1, c2, .... ck) where f is a function and b, c1, ... ck are attributes of A and the symbols at the
right side of the production.
We say that:
b is synthesized attribute of A if c1, c2, ...ck are attributes belonging to the grammar symbols of the
production and,
b is inherited attribute of one of the grammar symbols on the right side of the production if c1, c2, ...ck
are attributes belonging to the grammar symbols of the production and,
In either case, we say that attribute b depends on attributes c1, c2, ...........ck.
2
Exercice 4: Attributed grammar that associates to an identifier its type
Evaluation order
The attributes should be evaluated in a given order because they depend on one another. The
dependency of the attributes is represented by a dependency graph.
b(j) -----D()----> a (i) if and only if there exists a semantic action such as a (i) := f (... b (j) ...)
Evaluation Order
A topological sort of a directed acyclic graph is any ordering m1, m2, m3, ... mk of the nodes of the
graph such that edges go from nodes earlier in the ordering to later nodes. i.e. if mi ( mj is an edge from
mi to mj then mi appears before mj in the ordering.
3
Several methods have been proposed for evaluating semantic rules:
1. Parse rule based methods: for each input, the compiler finds an evaluation order. These
methods fail only if the dependency graph for that particular parse tree has a cycle.
2. Rule based methods: the order in which the attributes associated with a production are evaluated
is predetermined at compiler-construction time. For this method, the dependency graph need not
be constructed.
3. Oblivious methods: The evaluation order is chosen without considering the semantic rules. This
restricts the class of syntax directed definition that can be used.
Some classes of non-circular attributed grammars
S-Attributed grammars
We say that an attributed grammar is S-Attributed when all of its attributes are synthesized; i.e. it
doesn't have inherited attributes. Synthesized attributes can be evaluated by a bottom-up parser as the
input is being parsed. A new stack will be maintained to store the values of the attributes as in the
following example.
Example:
E Æ E1 + E2 { E.v = E1.v + E2.v }
Val(newTop) = Val(oldTop) + Val(oldTop – 2)
$$ = $1 + $3 (in Yacc)
We assume that the synthesized attributes are evaluated just before each reduction. Before the
reduction, attributes of E is in Val(Top) and attributes of E1 and E2 are in Val (Top – 1) and Val(Top -
2) respectively. After the reduction, E is put at the top of the State stack and its attribute values are put
at the top of Val.
The semantic actions that reference the attributes of the grammar will in fact be translated by the
Compiler generator (such as Yacc) into codes that reference the value stack.
L-Attributed grammars
It is difficult to execute the tasks of the compiler just by synthesized attributes. The L-attributed (L
stands for left) class of grammar allows a limited kind of inherited attributes.
Definition: A grammar is L-Attributed if and only if for each rule X0 --> X1 X2 ... Xj ... XN, all
inherited attributes of Xj depend only on:
1. Attributes of X1, ... X j- 1
2. Inherited attributes of X0
Example:
4
A ÆLM { L.h = f1 (A.h)
M.h = f2 (L.s)
A.s = f3 (M.s) }
This production does not contradict the rules of L-attributed grammars. Therefore, the corresponding
grammar may be L-attributed if all of the other productions follow the rule of L-attributed grammars.
Example:
A ÆQR { R.h = f4 (A.h)
Q.h = f5 (R.s)
A.s = f6 (Q.s) }
The grammar containing this production is not L-Attributed since Q.h depends on R.s which
contradicts with the rule of L-attributed grammars.