0% found this document useful (0 votes)
33 views19 pages

CD Unit 3 RV

The document discusses syntax directed translation (SDT) and intermediate code generation in compiler design. It describes SDT as combining a grammar with semantic rules to evaluate attributes. Productions are associated with semantic rules to evaluate attributes as the parse tree is traversed. Intermediate code lies between source and machine code. It allows changing just the code generation phase for different machines. Common intermediate representations include postfix notation, syntax trees, and 3-address code using quadruples or triples.

Uploaded by

Akash
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views19 pages

CD Unit 3 RV

The document discusses syntax directed translation (SDT) and intermediate code generation in compiler design. It describes SDT as combining a grammar with semantic rules to evaluate attributes. Productions are associated with semantic rules to evaluate attributes as the parse tree is traversed. Intermediate code lies between source and machine code. It allows changing just the code generation phase for different machines. Common intermediate representations include postfix notation, syntax trees, and 3-address code using quadruples or triples.

Uploaded by

Akash
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 19

COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-1)

Compiler Design: Syntax directed translation (SDT)


In syntax directed translation, along with the grammar we associate some informal
notations and these notations are called as semantic rules. So we can say that:

Grammar + semantic rule = SDT (syntax directed translation)


o In syntax directed translation, every non-terminal can get one or more than one attribute
or sometimes 0 attribute depending on the type of the attribute. The value of these
attributes is evaluated by the semantic rules associated with the production rule.
o In the semantic rule, attribute is VAL and an attribute may hold anything like a string, a
number, a memory location and a complex record
o In Syntax directed translation, whenever a construct encounters in the programming
language then it is translated according to the semantic rules define in that particular
programming language.

Example

Production Semantic Rules

E→E+T E.val := E.val + T.val

E→T E.val := T.val

T→T*F T.val := T.val + F.val

T→F T.val := F.val

F → (F) F.val := F.val

F → num F.val := num.lexval

E.val is one of the attributes of E.

num.lexval is the attribute returned by the lexical analyzer.

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

Syntax directed translation scheme


o The Syntax directed translation scheme is a context -free grammar.
o The syntax directed translation scheme is used to evaluate the order of semantic rules.
o In translation scheme, the semantic rules are embedded within the right side of the
productions.
o The position at which an action is to be executed is shown by enclosed between braces. It
is written within the right side of the production.

Example

Production Semantic Rules

S→E$ { printE.VAL }

E→E+E {E.VAL := E.VAL + E.VAL }

E→E*E {E.VAL := E.VAL * E.VAL }

E → (E) {E.VAL := E.VAL }

E→I {E.VAL := I.VAL }

I → I digit {I.VAL := 10 * I.VAL + LEXVAL }

I → digit { I.VAL:= LEXVAL}

Implementation of Syntax directed translation


Syntax direct translation is implemented by constructing a parse tree and performing the actions
in a left to right depth first order.
SDT is implementing by parse the input and produce a parse tree as a result.
Example

RAVIKANT NIRALA Page 2


COMPILER DESIGN (KCS-502)

Production Semantic Rules

S→E$ { printE.VAL }

E→E+E {E.VAL := E.VAL + E.VAL }

E→E*E {E.VAL := E.VAL * E.VAL }

E → (E) {E.VAL := E.VAL }

E→I {E.VAL := I.VAL }

I → I digit {I.VAL := 10 * I.VAL + LEXVAL }

I → digit { I.VAL:= LEXVAL}

Parse tree for SDT:

RAVIKANT NIRALA Page 3


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-2)

Compiler Design: Intermediate Code


Intermediate code lies between the high-level language and the machine language.

Fig: Position of intermediate code generator

o If the compiler directly translates source code into the machine code without generating
intermediate code then a full native compiler is required for each new machine.
o The intermediate code keeps the analysis portion same for all the compilers that's why it
doesn't need a full compiler for every unique machine.
o Intermediate code generator receives input from its predecessor phase and semantic
analyzer phase. It takes input in the form of an annotated syntax tree.
o Using the intermediate code, the second phase of the compiler synthesis phase is changed
according to the target machine.

Intermediate representation
Intermediate code can be represented in two ways:

1. High Level intermediate code:

High level intermediate code can be represented as source code. To enhance performance of
source code, we can easily apply code modification. But to optimize the target machine, it is less
preferred.

2. Low Level intermediate code

Low level intermediate code is close to the target machine, which makes it suitable for register
and memory allocation etc. it is used for machine-dependent optimizations.

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

Postfix Notation
o Postfix notation is the useful form of intermediate code if the given language is
expressions.
o Postfix notation is also called as 'suffix notation' and 'reverse polish'.
o Postfix notation is a linear representation of a syntax tree.
o In the postfix notation, any expression can be written unambiguously without
parentheses.
o The ordinary (infix) way of writing the sum of x and y is with operator in the middle: x +
y. But in the postfix notation, we place the operator at the right end as xy+.
o In postfix notation, the operator follows the operand.

Parse tree and Syntax tree

When you create a parse tree then it contains more details than actually needed. So, it is very
difficult to compiler to parse the parse tree. Take the following parse tree as an example:

o In the parse tree, most of the leaf nodes are single child to their parent nodes.
o In the syntax tree, we can eliminate this extra information.
o Syntax tree is a variant of parse tree. In the syntax tree, interior nodes are operators and
leaves are operands.
o Syntax tree is usually used when represent a program in a tree structure.

RAVIKANT NIRALA Page 2


COMPILER DESIGN (KCS-502)

A sentence id + id * id would have the following syntax tree:

Abstract syntax tree can be represented as:

Abstract syntax trees are important data structures in a compiler. It contains the least unnecessary
information.

Abstract syntax trees are more compact than a parse tree and can be easily used by a
compiler.

RAVIKANT NIRALA Page 3


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-3)

Compiler Design: Intermediate Code

Three address code


o Three-address code is an intermediate code. It is used by the optimizing compilers.
o In three-address code, the given expression is broken down into several separate
instructions. These instructions can easily translate into assembly language.
o Each Three address code instruction has at most three operands. It is a combination of
assignment and a binary operator.

Example

Given Expression:

a := (-c * b) + (-c * d)

Three-address code is as follows:

t1 := -c
t2 := b*t1
t3 := -c
t4 := d * t3
t5 := t2 + t4
a := t5

t is used as registers in the target program.

The three address code can be represented in two forms: quadruples and triples.

Quadruples
The quadruples have four fields to implement the three address code. The field of quadruples
contains the name of the operator, the first source operand, the second source operand and the
result respectively.

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

Fig: Quadruples field

Example

a := -b * (c + d)

Three-address code is as follows:

t1 := -b
t2 := c + d
t3 := t1 * t2
a := t3

These statements are represented by quadruples as follows:

Operator Source 1 Source 2 Destination

(0) uminus b - t1

(1) + c d t2

(2) * t1 t2 t3

(3) := t3 - a

RAVIKANT NIRALA Page 2


COMPILER DESIGN (KCS-502)

Triples
The triples have three fields to implement the three address code. The field of triples contains the
name of the operator, the first source operand and the second source operand.

In triples, the results of respective sub-expressions are denoted by the position of expression.
Triple is equivalent to DAG while representing expressions.

Fig: Triples field

Example:

a := -b * (c + d)

Three address code is as follows:

t1 := -b
t2 := c + d
t3 := t1 * t2
a := t3
These statements are represented by triples as follows:

Operator Source 1 Source 2

(0) uminus b -

(1) + c d

(2) * (0) (1)

(3) := (2) -

RAVIKANT NIRALA Page 3


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-4)

Compiler Design: Assignment Statements &


Boolean Expression

Assignment Statements
In the syntax directed translation, assignment statement is mainly deals with expressions.
The expression can be of type real, integer, array and records.

Consider the grammar


S → id := E
E → E1 + E2
E → E1 * E2
E → (E1)
E → id

The translation scheme of above grammar is given below:

Production rule Semantic actions

S → id :=E {p = look_up(id.name);
If p ≠ nil then
Emit (p = E.place)
Else
Error;
}

E → E1 + E2 {E.place = newtemp();
Emit (E.place = E1.place '+' E2.place)
}

E → E1 * E2 {E.place = newtemp();
Emit (E.place = E1.place '*' E2.place)
}

E → (E1) {E.place = E1.place}

E → id {p = look_up(id.name);
If p ≠ nil then
Emit (p = E.place)
Else
Error;
}

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

o The p returns the entry for id.name in the symbol table.


o The Emit function is used for appending the three address code to the output file.
Otherwise it will report an error.
o The newtemp() is a function used to generate new temporary variables.
o E.place holds the value of E.

Boolean Expressions
Boolean expressions have two primary purposes. They are used for computing the logical
values. They are also used as conditional expression using if-then-else or while-do.
Consider the grammar
E → E OR E
E → E AND E
E → NOT E
E → (E)
E → TRUE
E → FALSE
The AND and OR are left associated. NOT has the higher precedence then AND and lastly
OR.

Production rule Semantic actions

E → E1 OR E2 {E.place = newtemp();
Emit (E.place ':=' E1.place 'OR' E2.place)
}

E → E1 + E2 {E.place = newtemp();
Emit (E.place ':=' E1.place 'AND' E2.place)
}

E → NOT E1 {E.place = newtemp();


Emit (E.place ':=' 'NOT' E1.place)
}

E → (E1) {E.place = E1.place}

E → TRUE {E.place := newtemp();


Emit (E.place ':=' '1')
}

E → FALSE {E.place := newtemp();


Emit (E.place ':=' '0')
}

RAVIKANT NIRALA Page 2


COMPILER DESIGN (KCS-502)

The EMIT function is used to generate the three address code and the newtemp( ) function
is used to generate the temporary variables.

Here is the example which generates the three address code using the above translation
scheme:
p>q AND r<s OR u>v
100: if p>q goto 103
101: t1:=0
102: goto 104
103: t1:=1
104: if r<s goto 107
105: t2:=0
106: goto 108
107: t2:=1
108: if u>v goto 111
109: t3:=0
110: goto 112
111: t3:= 1
112: t4:= t1 AND t2
113: t5:= t4 OR t3

RAVIKANT NIRALA Page 3


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-5)

Compiler Design: Flow altering Statements

Flow Control altering Statements


We now consider the translation of Boolean expressions into three-address code in the context of
statements such as those generated by the following grammar:

In these productions, non terminal B represents a Boolean expression and non-terminal S


represents a statement.

The above grammar can be understood as:

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

Infix to Postfix Translation


Suppose a Grammar is given with corresponding semantic rules and semantic action:

Grammar Semantic Rule Semantic Action

E-> E+T {E.val=E.val+T.val} {printf(“+”);}

E->T { E.val=T.val } {}

T->T * F { T.val=T.val * F.val } {printf(“*”);}

T->F { T.val=F.val } {}

F-> num { F.val=num.lval } {printf(num.lval);}

So, corresponding SDT for input 2+3*4 gives postfix expression:

RAVIKANT NIRALA Page 2


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-6)

Compiler Design: Array references in arithmetic

As we know that Two different kind of Arrays


1. 1-D Array
2. 2-D Array

1-D Array
Pictorial Representation:

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

2-D Array
Pictorial Representation:

RAVIKANT NIRALA Page 2


COMPILER DESIGN (KCS-502)

RAVIKANT NIRALA Page 3


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-7)

Three Address Code: Procedures Call & Declaration

Procedures Call & Declaration


Suppose a precedures call is given:
P(X1, X2, X3, … , Xn)
Then define : param X1
param X2
param X3
------
param Xn
Then Call: call P, N

Example:-
void main()
{
int x=5, y=6;
swap(x,y);
}
void swap( int x, int y)
{
t1= x;
x=y;
y=t1;
}

Three Address Code:

1 call main
2 x=5
3 y=6
4 param x
5 param y
6 call swap, 2
7 t1= x;
8 x=y;
9 y=t1;
10 stop

RAVIKANT NIRALA Page 1


COMPILER DESIGN (KCS-502)

UNIT-3 (Lecture-8)

Three Address Code: Case Statements

Case Statements
Example:-
switch(ch)
{
case 1: z=x+y; break;
case 2: z=x-y; break;
default: z=x*y;
}

Three Address Code:

1 if ch==1 goto 5
2 if ch==2 goto 7
3 z= x*y
4 goto 9
5 z= x+y
6 goto 9
7 z= x-y
8 goto 9
9 stop

RAVIKANT NIRALA Page 1

You might also like