Intermediate Code Generation
Intermediate Code Generation
Intermediate Code Generation
Triples
A triple has only three fields, which we call op, arg1, and arg2. Note that the
result field in above fig.(b) is used primarily for temporary names. Using triples,
we refer to the result of an operation x op y by its position, rather than by an
explicit temporary name. Thus, instead of the temporary t1 in Fig.(b), a triple
representation would refer to position (0). Parenthesized numbers represent
pointers into the triple structure itself. Representations of a = b*-c +b*-c is shown
below.
Sequences of Declarations
Languages such as C and Java allow all the declarations in a single procedure
to be processed as a group. The declarations may be distributed within a Java
procedure, but they can still be processed when the procedure is analyzed.
Therefore, we can use a variable, say off
set, to keep track of the next available relative address.
The translation scheme of below figure deals with a sequence of declarations
of the form T id, where T generates a type. Before the first declaration is
considered, offset is set to 0. As each new name x is seen, x is entered into the
symbol table with its relative address set to the current value of off set, which
is then incremented by the width of the type of x.
Translation of Expressions
The syntax-directed definition in below figure builds up the three-address
code for an assignment statement S using attribute code for S and attributes
addr and code for an expression E. Attributes S:code and E:code denote the
three-address code for S and E, respectively. Attribute E:addr denotes the
address that will hold the value of E. (recall an adress can be name, constant
or compiler generate temporary variable)
Incremental Translation
Code attributes can be long strings, so they are usually generated
incrementally. Thus, instead of building up E:code as in above figure, it can
be arrange to generate only the new three-address instructions, as in the
translation scheme of shown in below figure. In the incremental approach,
gen not only constructs a three-address instruction, it appends the instruction
to the sequence of instructions generated so far. The sequence may either be
retained in memory for further processing, or it may be output incrementally.
The translation scheme in below figure generates the same code as the
syntax directed definition in above figure. With the incremental approach, the
code attribute is not used, since there is a single sequence of instructions that
is created by successive calls to gen.
For example, the semantic rule for E ->E1 +E2 in below figure simply calls
gen to generate an add instruction; the instructions to compute E1 into E1:addr
and E2 into E2:addr have already been generated.
The new semantic action for E ->E1 +E2creates a node by using a constructor,
as in E ->E1 +E2 { E:addr = new Node(0+0; E1:addr; E2:addr); }
Addressing Array Elements
Array elements can be accessed quickly if they are stored in a block of consecu
tive locations. In C and Java, array elements are numbered 0; 1,… n -1, for an
array with n elements. If the width(w) of each array element is w, then the ith
element of array A begins in location
base + i x w
where base is the relative address of the storage allocated for the array. That
is, base is the relative address of A[0].
The relative address of A[i1][i2] can then be calculated by the formula
Translation of Array References