Syntax directed translation of
expression into 3-address code
S id := E |
S.code = E.code ||
|
|
gen(id.place:= E.place)
|
E E1 + E2 |
E.place:= newtmp
|
|
E.code:= E 1 .code || E2 .code ||
|
|
gen(E.place := E 1 .place + E 2 .place)
|
E E1 * E 2 |
E.place:= newtmp
|
|
E.code := E 1 .code || E 2 .code ||
|
|
gen(E.place := E1 .place * E 2 .place)
|
|
|
Three-address code is a sequence of statements of the general form
X := y op z
Where x, y and z are names, constants, or compiler generated temporaries. op stands for any operator, such as fixed- or floating-point arithmetic operator, or a logical operator on Boolean-valued data. Note that no built up arithmetic
expression are permitted, as there is only one operator on the right side of a statement. Thus a source language expression like x + y * z might be translated into a sequence
t1 := y * z
t2 := x + t1
where t1 and t2 are compiler-generated temporary names. This unraveling of complicated arithmetic expression and of nested flow-of-control statements makes three- address code desirable for target code generation and optimization.
The use of names for the intermediate values computed by a program allows three-address code to be easily rearranged unlike postfix notation. We can easily generate code for the three-address code given above. The S-attributed definition above generates three-address code for assigning statements. The synthesized attribute S.code represents the three-address code for the assignment S. The nonterminal E has two attributes:
. E.place , the name that will hold the value of E, and
. E.code , the sequence of three-address statements evaluating E.
The function newtemp returns a sequence of distinct names t1, t2,.. In response to successive calls.
|