Compiler Design
By
Radhika B S
Intermediate Code Generation
● Intermediate codes are machine independent
● Compilers can also directly generate target code
● Generation of intermediate code helps in multiplexing and code optimization
● Intermediate code can be represented using different forms such as trees, three address code,
etc.,
2
Three Address Code
● Contain at most one operator on the right side of an instruction
● There is no standard format/language for three address code
● Compilers implement theses codes using Objects or Records with fields for operator and
operands.
● Its built from two concepts: addresses and instructions
● An Address can be one of the following
○ A name
○ A constant
○ A compiler generated temporary
3
Three Address Code
● Common instructions include
○ Assignment
○ Copy
○ Unconditional jump
○ Conditional jump
○ Function call
4
Three Address Code
5
Three Address Code
● Three representations of these instructions are
○ Quadruples
○ Triples
○ Indirect Triples
6
Quadruples
● A quadruple has 4 fields: op, arg1, arg2, result
● Instructions with unary operators do not use arg2
● Operators like papram do not use arguments
● Jump instructions use the result for target label
7
Triples
● A triple has 3 fields: op, arg1, arg2
● Using triples, we refer to the result of an operation x op y by its position, rather than by an explicit
temporary name.
● A ternary operations like x[i] = y, x = y[i] require two entries in the triple structure
● A benet of quadruples over triples can be seen in an optimizing compiler, where instructions are
often moved around.
8
Indirect Triples
● Indirect triples consist of a listing of pointers to triples, rather than a listing of triples themselves.
● With indirect triples, an optimizing compiler can move an instruction by reordering the
instruction list, without a affecting the triples themselves.
9
Types and Declaration
● Types are useful in Type Checking and translation applications
● Types have structure, which are represented using type expressions
● A type expression is either a basic type or is formed by applying an operator called a type
constructor to a type expression.
● The sets of basic types and constructors depend on the language to be checked.
● Two types are structurally equivalent if and only if one of the following conditions is true:
○ They are the same basic type.
○ They are formed by applying the same constructor to structurally equivalent types.
○ One is a type name that denotes the other.
10
11
Translation of Expressions
12
Translation of Expressions
13
Incremental Translation
14
Types Checking
● To do type checking a compiler needs to assign a type expression to each component of the
source program.
● The compiler must then determine that these type expressions conform to a collection of logical
rules that is called the typesystem for the source language.
● A sound type system eliminates the need for dynamic checking for type errors, because it allows
us to determine statically that these errors cannot occur when the target program runs.
● An implementation of a language is strongly typed if a compiler guarantees that the programs it
accepts will run without type errors.
15
Rules for Types Checking
● Type checking can take on two forms: synthesis and inference
● Type synthesis builds up the type of an expression from the types of its subexpressions
● It requires names to be declared before they are used.
● A typical rule for type synthesis has the form
● Type inference determines the type of a language construct from the way it is used.
● A typical rule for type inference has the form
16
Type Conversion
● A compiler may convert one of the operands of an operator to ensure both the operands are of
the same type
● Type synthesis can be included in SDT as follows
● Type conversion rules vary from language to language.
● Conversion from one type to another is said to be implicit/coercion if it is done automatically by
the compiler.
● Conversion is said to be explicit/casts if the programmer must write something to cause the
conversion.
17
Type Conversion
● Generally conversions are of two forms: widening and narrowing
18
Type Conversion
● The semantic action for checking E E1 + E2 uses two functions:
○ max(t1, t2): To find the maximum of the two types t1 and t2
○ widen(a,t,w) : To convert a from type t to type w
19