0% found this document useful (0 votes)
49 views

CH 5 - Intermediate Code Generation

The document discusses intermediate code generation in compilers. It covers: 1. The compiler converts source code to intermediate representation after analysis and before code optimization. Intermediate code is machine-independent to facilitate retargeting and optimizations. 2. Intermediate code can be represented as an abstract syntax tree, postfix notation, or three-address code consisting of statements with single operations. 3. Three-address code is generated using syntax-directed translation. Temporary variables and labels are used. Declarations reserve memory and enter symbols in the symbol table with addresses and types.

Uploaded by

ethiopia tonetor
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)
49 views

CH 5 - Intermediate Code Generation

The document discusses intermediate code generation in compilers. It covers: 1. The compiler converts source code to intermediate representation after analysis and before code optimization. Intermediate code is machine-independent to facilitate retargeting and optimizations. 2. Intermediate code can be represented as an abstract syntax tree, postfix notation, or three-address code consisting of statements with single operations. 3. Three-address code is generated using syntax-directed translation. Temporary variables and labels are used. Declarations reserve memory and enter symbols in the symbol table with addresses and types.

Uploaded by

ethiopia tonetor
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/ 16

Intermediate Code Generation

1
Intermediate Code Generation
• The compiler converts the source program
into an intermediate representation at the
end of the analysis phase

• The use of machine independent


Intermediate Code helps to:
– Facilitate retargetting the compiler to another
platform
– Apply machine independent code optimization
2
Intermediate Languages
• The intermediate code may be represented
using any one of the following:
– Abstract Syntax Tree
parse tree without syntactic sugar
– Postfix notation
Read more about Abstract tree & Postfix notation
– Three Address Code
The 3 @ code is a sequence of statements of the form
x := y op z or x := op z
where x, y, and z are either names, constants or compiler
generated temporaries. Op is an operator such as integer to
floating point arithmetic operator or logical operator on boolean
data.

3
Three Address Code
• Important notes about statements in three
address code statements:
– No predefined arithmetic (or any) operator is
permitted.
– Only one operation is allowed in a statement
Ex. w = x+ y * z
becomes
t1 = y * z
w = x + t1
• 3 @ code statements can have labels and
statements for flow control (ex. goto) 4
Types of 3 @ Statements
• Assignment (binary operation)
– x := z op w
• Assignment (unary operation)
– x := op y
• Copy
– x := y
• Unconditional Jump
– Goto L
• Conditional Jump
– if x relop y goto L 5
Types of Statements (cont'd)
• Function call
– Parameter specification
• param x1
– Calling the function
• call P, N { P : function & N : no. of parameters }
• Indexed Arguments
– x := y[I] { x = value at address y+I }
– y[I] := x { value at address y+I = x }

6
Types of Statements (cont'd)
• Address and Pointer Assignments
– x := &y { x = address of y }
– x := *y { x = the value at address y }
– *x := y { value at address x = y }

7
Syntax Directed Translation into
Three Address Code
• The 3 @ code is generated either as an attribute
of the parse tree or by writing the statements in
a file as soon as they are generated.

• When the 3 @ code is generated, it is often


necessary to use temporary variables and
temporary names.

• For this purpose, the following functions are


given:
8
Syntax Directed Translation into
Three Address Code (cont'd)
• NewTemp() :
each time it is called, gives distinct names that can be
used for temporary variables.

• NewLabel() :
each time it is called gives distinct names that
can be used for label names.

• In addition, we use the function gen to create


three address code statements from a number of
strings.

9
3 @ Code Generation
(Assignment & Expression)
S → id := E S.code := E. code || gen(id.lexeme,”:=”, E.place)
E1 → E2 + E3 E1.place := newTemp();
E1.code := E2.code || E3.code || gen(E1.place, “:=”, E2.place, “+”,
E3.place)
E1 → E2 * E3
E1 → - E2 E1.place := newTemp();
E1.code := E2.code || gen(E1.place, “:=”, “-”, E2.place)
E1 → (E2) E1.code := E2.code
E1.place := E2.place
E → id E.place := id.lexeme
E1 → E2 < E3 E1.place = newTemp()
E1.code = E2.code || E3.code || gen(E1.place, “:=“, E2.place, “<“,
E3.place);
10
3 @ Code Generation (Assignment
& Expression)
S1 → while E do S2
S1.begin := newLabel();
S1.after := newLabel();
S1.code := gen(S1.begin, “:”) || E.code || gen(
“if”, E.place, “= 0 goto”, S1.after) || S2.code ||
gen( “goto”, S1.begin) || gen( S1.after, “:”);

11
3 @ Code Generation
(Assignment & Expression)
• Example:
1. Consider the string:
A := B + C
Draw the decorated parse tree based on the
previous syntax directed translation.
2. Consider the string:
while a < b do a := a + 1
Draw the decorated parse tree.

12
Declarations
• While process declarations, the compiler
– reserves memory area for the variables
– stores the relative address of each variable in the symbol table (the
relative address is an address in the static data area relative to the
beginning – offset address)
• For this purpose, the compiler maintains an offset variable
that indicates the first address not yet allocated.
• Initially, offset is set to zero.
• Each time an address is allocated to a variable, the offset
is incremented by the width of the data object denoted by
the name.
• The procedure enter (name, type, address) creates a
symbol table entry for name with type type and address
address. 13
Declarations (cont’d)
P → {offset = 0} D S
D → D;D
D → id : T enter(id.lexeme, T.type, offset);
T → integer T.type = integer;
T.size = 2;
T → real T.type = real;
T.size = 4;
T → array[num] of T T1.type = array([num.value], T2.type);
T1.size = num.value*T2.size;
T → ^T T1.type = pointer( T2.type);
T1.size = 2;
14
Declarations (cont’d)
• Example
Consider the following declaration
x : integer;
y : real;
z : char;
t : array[10] of integer;
v : ^Integer;
What would be the content of the symbol
table after this declaration is processed?
15
Declarations (cont’d)
Symbol table after processing the previous declarations.

Name Type address


x Integer 0
y Real 2
z Char 6
t Array([10], Integer) 7
v Pointer(Integer) 27

16

You might also like