Syntax Directed Translation
Syntax Directed Translation
Department of IT
NIT Srinagar
Outline
Syntax Directed Definitions
Evaluation Orders of SDDs
Applications of Syntax Directed Translation
Syntax Directed Translation Schemes
Introduction
postorder(N) {
for (each child C of N, from the left) postorder(C);
evaluate the attributes associated with node N;
}
S-Attributed definitions can be implemented during
bottom-up parsing without the need to explicitly
create parse trees
L-Attributed definitions
A SDD is L-Attributed if the edges in dependency graph
goes from Left to Right but not from Right to Left.
More precisely, each attribute must be either
Synthesized
Inherited, but if there us a production A->X1X2Xn and
there is an inherited attribute Xi.a computed by a rule
associated with this production, then the rule may only
use:
Inherited attributes associated with the head A
Either inherited or synthesized attributes associated with the
occurrences of symbols X1,X2,,Xi-1 located to the left of Xi
Inherited or synthesized attributes associated with this
occurrence of Xi itself, but in such a way that there is no cycle in
the graph
Application of Syntax
Directed Translation
Type checking and intermediate code
generation (chapter 6)
Construction of syntax trees
Leaf nodes: Leaf(op,val)
Interior node: Node(op,c1,c2,,ck)
Example:
Production Semantic Rules
1) E -> E1 + T E.node=new node(+, E1.node,T.node)
2) E -> E1 - T E.node=new node(-, E1.node,T.node)
3) E -> T E.node = T.node
4) T -> (E) T.node = E.node
5) T -> id T.node = new Leaf(id,id.entry)
6) T -> num T.node = new Leaf(num,num.val)
Syntax tree for L-
attributed definition
Production Semantic Rules
1) E -> TE E.node=E.syn +
E.inh=T.node
2) E -> + TE1 E1.inh=new node(+, E.inh,T.node)
E.syn=E1.syn
3) E -> -TE1 E1.inh=new node(+, E.inh,T.node)
E.syn=E1.syn
4) E -> E.syn = E.inh
1) L -> E n {print(E.val);}
2) E -> E1 + T {E.val=E1.val+T.val;}
3) E -> T {E.val = T.val;}
4) T -> T1 * F {T.val=T1.val*F.val;}
5) T -> F {T.val=F.val;}
6) F -> (E) {F.val=E.val;}
7) F -> digit {F.val=digit.lexval;}
Parse-Stack
implementation of postfix
In a shift-reduce parser we can easily
SDTs
implement semantic action using the parser
stack
For each nonterminal (or state) on the stack we
can associate a record holding its attributes
Then in a reduction step we can execute the
semantic action at the end of a production to
evaluate the attribute(s) of the non-terminal at
the leftside of the production
And put the value on the stack in replace of the
rightside of production
Example
L -> E n {print(stack[top-1].val);
top=top-1;}
E -> E1 + T {stack[top-2].val=stack[top-2].val+stack.val;
top=top-2;}
E -> T
T -> T1 * F {stack[top-2].val=stack[top-2].val+stack.val;
top=top-2;}
T -> F
F -> (E) {stack[top-2].val=stack[top-1].val
top=top-2;}
F -> digit
SDTs with actions inside
productions
For a production B->X {a} Y
If the parse is bottom-up then we perform action a as soon
as this occurrence of X appears on the top of the parser stack
If the parser is top down we perform a just before we
expand Y
Sometimes we cant do things as easily as explained above
One example is when we are parsing this SDT with a
bottom-up parser
1) L -> E n
2) E -> {print(+);} E1 + T
3) E -> T
4) T -> {print(*);} T1 * F
5) T -> F
6) F -> (E)
7) F -> digit {print(digit.lexval);}
SDTs with actions inside
productions (cont) L
Any SDT can be
implemented as follows E
1. Ignore the actions and
produce a parse tree {print(+);}
E + T
2. Examine each interior
node N and add actions
T F
as new children at the
correct position {print(*);}
{print(4);}
T *F digit
3. Perform a postorder
traversal and execute {print(5);}
actions when their F digit
nodes are visited {print(3);}
digit
SDTs for L-Attributed
definitions
We can convert an L-attributed SDD into an
SDT using following two rules:
Embed the action that computes the inherited
attributes for a nonterminal A immediately
before that occurrence of A. if several
inherited attributes of A are dpendent on one
another in an acyclic fashion, order them so
that those needed first are computed first
Place the action of a synthesized attribute for
the head of a production at the end of the
body of the production
Example
S -> while (C) S1 L1=new();
L2=new();
S1.next=L1;
C.false=S.next;
C.true=L2;
S.code=label||L1||C.code||
label||L2||S1.code