Compiler course
Chapter 5
Syntax Directed Translation
Outline
Introduction
Production
Semantic Rule
E->E1+T
E.code=E1.code||T.code||’+’
E -> E1+T {print ‘+’}
Syntax Directed Definitions
Example of S-attributed SDD
Production
Semantic Rules
L.val = E.val
E.val = E1.val + T.val
E.val = T.val
T.val = T1.val * F.val
T.val = F.val
F.val = E.val
F.val = digit.lexval
Example of mixed attributes
3) T’ -> ε
Production
Semantic Rules
T’.inh = F.val
T.val = T’.syn
T’1.inh = T’.inh*F.val
T’.syn = T’1.syn
T’.syn = T’.inh
F.val = F.val = digit.lexval
Evaluation orders for SDD’s
Ordering the evaluation of attributes
S-Attributed definitions
postorder(N) {
for (each child C of N, from the left) postorder(C);
evaluate the attributes associated with node N;
}
L-Attributed definitions
Application of Syntax Directed Translation
Production
Semantic Rules
E.node=new node(‘+’, E1.node,T.node)
E.node=new node(‘-’, E1.node,T.node)
E.node = T.node
T.node = E.node
T.node = new Leaf(id,id.entry)
T.node = new Leaf(num,num.val)
Syntax tree for L-attributed definition
+
Production
Semantic Rules
E.node=E’.syn
E’.inh=T.node
E1’.inh=new node(‘+’, E’.inh,T.node)
E’.syn=E1’.syn
E1’.inh=new node(‘+’, E’.inh,T.node)
E’.syn=E1’.syn
E’.syn = E’.inh
T.node = E.node
T.node=new Leaf(id,id.entry)
T.node = new Leaf(num,num.val)
Syntax directed translation schemes
Postfix translation schemes
Example of postfix SDT
Parse-Stack implementation of postfix SDT’s
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
SDT’s with actions inside productions
SDT’s with actions inside productions (cont)
L
E
+
E
{print(‘+’);}
T
F
digit
{print(4);}
T
T
F
*
digit
{print(5);}
F
digit
{print(3);}
{print(‘*’);}
SDT’s for L-Attributed definitions
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
S -> while ( {L1=new();L2=new();C.false=S.next;C.true=L2;}
C) {S1.next=L1;}
S1{S.code=label||L1||C.code||label||L2||S1.code;}
Outline
Introduction
Parser
Static
Checker
Intermediate Code Generator
Code Generator
Front end
Back end
Variants of syntax trees
+
+
*
*
-
b
c
a
d
SDD for creating DAG’s
Production
Semantic Rules
E.node= new Node(‘+’, E1.node,T.node)
E.node= new Node(‘-’, E1.node,T.node)
E.node = T.node
T.node = E.node
T.node = new Leaf(id, id.entry)
T.node = new Leaf(num, num.val)
Example:
Value-number method for constructing DAG’s
=
+
10
i
id
To entry for i
num
10
+
1
2
3
1
3
Three address code
+
+
*
*
-
b
c
a
d
t1 = b – c
t2 = a * t1
t3 = a + t2
t4 = t1 * d
t5 = t3 + t4
Forms of three address instructions
Example
L: t1 = i + 1
i = t1
t2 = i * 8
t3 = a[t2]
if t3 < v goto L
Symbolic labels
100: t1 = i + 1
101: i = t1
102: t2 = i * 8
103: t3 = a[t2]
104: if t3 < v goto 100
Position numbers
Data structures for three address codes
Example
t1 = minus c
t2 = b * t1
t3 = minus c
t4 = b * t3
t5 = t2 + t4
a = t5
Three address code
minus
*
minus
c
t3
*
+
=
c
t1
b
t2
t1
b
t4
t3
t2
t5
t4
t5
a
arg1
result
arg2
op
Quadruples
minus
*
minus
c
*
+
=
c
b
(0)
b
(2)
(1)
(3)
a
arg1
arg2
op
Triples
(4)
0
1
2
3
4
5
minus
*
minus
c
*
+
=
c
b
(0)
b
(2)
(1)
(3)
a
arg1
arg2
op
Indirect Triples
(4)
0
1
2
3
4
5
(0)
(1)
(2)
(3)
(4)
(5)
op
35
36
37
38
39
40
Type Expressions
Example: int[2][3]
array(2,array(3,integer))
Type Equivalence
Declarations
Storage Layout for Local Names
Storage Layout for Local Names
Sequences of Declarations
Fields in Records and Classes
Translation of Expressions and Statements
Three-address code for expressions
Incremental Translation
Addressing Array Elements
Semantic actions for array reference
Translation of Array References
Nonterminal L has three synthesized attributes:
Conversions between primitive types in Java
Introducing type conversions into expression evaluation
Abstract syntax tree for the function definition
fun length(x) =
if null(x) then 0 else length(tl(x)+1)
This is a polymorphic function
in ML language
Inferring a type for the function length
Algorithm for Unification
Unification algorithm
boolean unify (Node m, Node n) {
s = find(m); t = find(n);
if ( s = t ) return true;
else if ( nodes s and t represent the same basic type ) return true;
else if (s is an op-node with children s1 and s2 and
t is an op-node with children t1 and t2) {
union(s , t) ;
return unify(s1, t1) and unify(s2, t2);
}
else if s or t represents a variable {
union(s, t) ;
return true;
}
else return false;
}
Control Flow
boolean expressions are often used to:
Short-Circuit Code
Flow-of-Control Statements
Syntax-directed definition
Generating three-address code for booleans
translation of a simple if-statement
Backpatching
Backpatching for Boolean Expressions
Backpatching for Boolean Expressions
Flow-of-Control Statements
Translation of a switch-statement