Unit Iv CD
Unit Iv CD
of
AUTOMATA AND
COMPILER
DESIGN
(UNIT- 4)
By
MR. J. NAGA RAJU
Asst. Professor
Department of AI&DS
Outline
⚫ Syntax Directed Definitions
⚫ Evaluation Orders of SDD’s
⚫ Applications of Syntax Directed
Translation
⚫ Syntax Directed Translation
Schemes
Introduction
⚫ We can associate information with a
language construct by attaching
attributes to the grammar symbols.
⚫ A syntax directed definition specifies the
values of attributes by associating
semantic rules with the grammar
productions. Semantic Rule
Production
E->E1+T E.code=E1.code||T.code||’+’
•We may alternatively insert the semantic actions inside the grammar
E -> E1+T {print ‘+’}
Syntax Directed Definitions
⚫ A SDD is a context free grammar with
attributes and rules
⚫ Attributes are associated with grammar
symbols and rules with productions
⚫ Attributes may be of many kinds:
numbers, types, table references, strings,
etc.
⚫ Synthesized attributes
⚫ A synthesized attribute at node N is defined
only in
terms of attribute values of children of N and at
N it
⚫ Inherited attributes
⚫ An inherited attribute at node N is defined only
Example of S-attributed SDD
Production Semantic Rules
1) L -> E n L.val = E.val
2) E -> E1 + E.val = E1.val
T + T.val
3) E -> T E.val = T.val
4) T -> T1 * F T.val = T1.val
5) T -> F * F.val
6) F -> T.val = F.val
(E) F.val = E.val
7) F -> F.val =
digit digit.lexval
Example of mixed attributes
Production Semantic Rules
1) T -> FT’ T’.inh = F.val
T.val = T’.syn
2) T’ -> T’1.inh = T’.inh*F.val
*FT’1 T’.syn = T’1.syn
T’.syn = T’.inh
3) T’ -> ε F.val = F.val =
1) F -> digit digit.lexval
Application of Syntax Directed
Translation
1. Type checking and intermediate code
generation (chapter 6)
2. Construction of syntax trees
• Leaf nodes: Leaf(op,val)
• Interior node: Node(op,c1,c2,…,ck)
⚫ Example:
Production Semantic Rules
1) E -> E1 + E.node=new node(‘+’, E1.node,T.node)
T E.node=new node(‘-’, E1.node,T.node)
2) E -> E1 - T E.node = T.node
3) E -> T T.node = E.node
4) T -> T.node = new Leaf(id,id.entry)
(E)
5) T -> id
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’ -> + E1’.inh=new node(‘+’, E’.inh,T.node)
TE1’ E’.syn=E1’.syn
E1’.inh=new node(‘+’, E’.inh,T.node)
3) E’ -> -TE1’ E’.syn=E1’.syn
E’.syn = E’.inh
4) E’ ->
T.node = E.node
5) T -> (E)
6) T -> id T.node=new Leaf(id,id.entry)
7) T -> num
T.node = new Leaf(num,num.val)
Syntax directed translation
schemes
⚫ An SDT is a Context Free grammar with program
fragments
embedded within production bodies
⚫ Those program fragments are called semantic
actions
⚫ They can appear at any position within
production body
⚫ Any SDT can be implemented by first building a
parse tree and then performing the actions in a
left-to-right depth first order
⚫ Typically SDT’s are implemented during
parsing without building a parse tree
Postfix translation schemes
⚫ Simplest SDDs are those that we can parse the
grammar
bottom-up and the SDD is s-attributed
⚫ For such cases we can construct SDT where
each action is placed at the end of the
production and is executed along with the
reduction of the body to the head of that
production
⚫ SDT’s with all actions at the right ends of the
production bodies are called postfix SDT’s
Example of postfix SDT
1) L -> E n {print(E.val);}
2) E -> E1 + {E.val=E1.val+T.val;}
T {E.val = T.val;}
3) E -> T {T.val=T1.val*F.val;}
4) T -> T1 * F {T.val=F.val;}
5) T -> F {F.val=E.val;}
6) F -> {F.val=digit.lexval;}
(E)
7) F ->
digit
Parse-Stack implementation of
postfix SDT’s
⚫ In a shift-reduce parser we can easily
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
Exampl
e 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
⚫ 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
Y
perform “a” just before we 1) L -> E n
2) E -> {print(‘+’);} E1 + T
expand we cant do
⚫ Sometimes 3) E -> T
things as easily as 4) T -> {print(‘*’);} T1 * F
5) T -> F
explained above 6) F -> (E)
⚫ One example is when we 7) F -> digit {print(digit.lexval);}
SDT’s with actions inside
productions (cont) L
⚫ Any SDT can be
implemented as E
follows
1. Ignore the actions
{print(‘+’);}
and produce a E
parse tree
2. Examine each
+ F
interior node N T {print(4);}
{print(‘*’);}
and add actions as T *F digit
new children at the T {print(5);}
correct position F digit
3. Perform a postorder {print(3);}
traversal and digit
SDT’s 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 L1=new();
(C) S1 L2=new();
S1.next=L1;
C.false=S.n
ext;
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;}
Outline
⚫ Variants of Syntax
Trees
⚫ Three-address code
⚫ Types and
declarations
⚫ Translation of
expressions
⚫ Type checking
⚫ Control flow
⚫ Backpatching
Variants of syntax trees
⚫ It is sometimes beneficial to crate a DAG
instead of tree for Expressions.
⚫ This way we can easily show the common
sub- expressions and then use that
knowledge during code generation
⚫ Example: a+a*(b-c)+(b-c)*d
+ *
*
d
a -
b c
SDD for creating DAG’s
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)
Example:
1) p1=Leaf(id, entry-a) 8) p8=Leaf(id,entry-b)=p3
2) P2=Leaf(id, entry-a)=p1 9) p9=Leaf(id,entry-c)=p4
3) p3=Leaf(id, entry-b) 10) p10=Node(‘-’,p3,p4)=p5
4)p4=Leaf(id, entry-c) 5) 11) p11=Leaf(id,entry-d)
p5=Node(‘-’,p3,p4) 6) 12) p12=Node(‘*’,p5,p11)
p6=Node(‘*’,p1,p5) 7) 13)
p7=Node(‘+’,p1,p6) p13=Node(‘+’,p7,p12)
Value-number method for
constructing DAG’s
= id To entry for i
num 10
+ + 1 2
3 1 3
i 10
⚫ Algorithm
⚫ Search the array for a node M with label op,
left child l and right child r
⚫ If there is such a node, return the value
number M
⚫ If not create in the array a new node N with
label op, left child l, and right child r and
Three address code
⚫ In a three address code there is at most one
operator at the right side of an instruction
⚫ Example:
+
t1 = b – c
+ * t2 = a * t1
t3 = a + t2
* t4 = t1 * d
d
t5 = t3 + t4
a -
b c
Forms of three address
instructions
⚫ x = y op z
⚫ x = op y
⚫x=y
⚫ goto L
⚫ if x goto L and ifFalse x
goto L
⚫ if x relop y goto L
⚫ Procedure calls using:
⚫ param x
⚫ call p,n
⚫ y = call p,n
⚫ x = y[i] and x[i] = y
⚫ x = &y and x = *y and
*x =y
Exampl
e (a[i] < v);
⚫ do i = i+1; while
L: t1 = i + 1 100: t1 = i + 1
i = t1 101: i = t1
t2 = i * 8 102: t2 = i * 8
t3 = a[t2] 103: t3 = a[t2]
if t3 < v goto L 104: if t3 < v goto 100
e minus c
⚫ b * minus c + b * t3 = minus c
t4 = b * t3
t5 = t2 + t4
a = t5
⚫ Actions at the
end:
⚫
Fields in Records and Classes
⚫
⚫
Translation of Expressions and
Statements
⚫ We discussed how to find the types and
offset of variables
⚫ We have therefore necessary preparations
to discuss about translation to
intermediate code
⚫ We also discuss the type checking
Three-address code for expressions
Incremental Translation
Addressing Array Elements
⚫ Layouts for a two-dimensional
array:
Semantic actions for array reference
Translation of Array References
⚫
Flow-of-Control Statements
Syntax-directed definition
Generating three-address code for booleans
translation of a simple if-statement
⚫
⚫
Flow-of-Control Statements
Translation of a switch-statement