Principles of Programming Languages
h"p://www.di.unipi.it/~andrea/Dida2ca/PLP-16/
Prof. Andrea Corradini
Department of Computer Science, Pisa
• Intermediate-Code Genera=on
– Intermediate representa=ons
– Syntax-directed transla=on to three address code
Lesson 11!
2
Intermediate Code Genera=on (II)
• Facilitates retarge&ng: enables aGaching a back end for the new machine to an exis=ng front end
Parsing
Syntax-Directed Defini=ons Syntax-Directed Transla=on Schemes
Back end
Intermediate
code Target
code
Tokens
Summary
• Intermediate representa=ons
• Three address statements and their implementa=ons
• Syntax-directed transla=on to three address statements
– Expressions and statements
– Logical and rela=onal expressions
– Transla=ng short-circuit Boolean expressions and flow-of-
control statements with backpatching lists
4
Intermediate Representa=ons
• Graphical representa&ons (e.g. AST and DAGs)
• Pos2ix nota&on: opera=ons on values stored on operand stack (similar to JVM bytecode)
• Three-address code: (e.g. triples and quads) x := y op z
• Two-address code:
x := op y
which is the same as x := x op y
Syntax-Directed Transla=on of Abstract Syntax Trees
Produc=on S → id := E E → E
1+ E
2E → E
1* E
2E → - E
1E → ( E
1) E → id
Seman=c Rule
S.nptr := mknode(‘:=’, mkleaf(id, id.entry), E.nptr) E.nptr := mknode(‘+’, E
1.nptr, E
2.nptr)
E.nptr := mknode(‘*’, E
1.nptr, E
2.nptr) E.nptr := mknode(‘uminus’, E
1.nptr) E.nptr := E
1.nptr
E.nptr := mkleaf(id, id.entry)
6
Abstract Syntax Trees
E.nptr
* E.nptr
E.nptr a!
b!
+ E.nptr
*!
a! +!
b! c!
E.nptr c E.nptr
( )
a * (b + c)!
Pro: easy restructuring of code and/or expressions for
intermediate code op=miza=on
Cons: memory intensive
Abstract Syntax Trees versus DAGs
:=
a +
*
uminus b
c
*
uminus b
Tree c
:=
a +
*
uminus b
c DAG
a := b * -c + b * -c!
• Repeated subtrees are shared
• Implementa=on: mkleaf and makenode are redefined. They do
8
Pos]ix Nota=on
a := b * -c + b * -c!
iload 2 // push b iload 3 // push c ineg // uminus imul // *
iload 2 // push b iload 3 // push c ineg // uminus imul // *
iadd // +
istore 1 // store a
Bytecode (for example) a b c uminus * b c uminus * + assign
Pos]ix nota=on represents opera=ons on a stack
Pro: easy to generate
Cons: stack opera=ons are more
difficult to op=mize
Three-Address Code (1)
a := b * -c + b * -c!
t1 := - c t2 := b * t1 t3 := - c t4 := b * t3 t5 := t2 + t4 a := t5
Linearized representation of a syntax tree
:=
a +
*
uminus b
c
*
uminus b
Tree c
Three-Address Code (2)
a := b * -c + b * -c!
t1 := - c t2 := b * t1 t5 := t2 + t2 a := t5
Linearized representation of a syntax DAG
:=
a +
*
uminus b
c DAG
Three-Address Statements
“Addresses” are names, constants or temporaries
• Assignment statements: x:= y op z, x:= op y
• Indexed assignments: x:= y[i], x[i]:= y
• Pointer assignments: x:= &y, x:= *y, *x:= y
• Copy statements: x:= y
• Unconditional jumps: goto lab
• Conditional jumps: if x relop y goto lab
• Function calls: param x… ; call p, n
(or y = call p, n) ; return y
Implementa=on of Three-Address Statements: Quads
# Op Arg1 Arg2 Res
(0) uminus c t1
(1) * b t1 t2
(2) uminus c t3
(3) * b t3 t4
(4) + t2 t4 t5
(5) := t5 a
Quads (quadruples) Pro: easy to rearrange code for global op=miza=on Cons: lots of temporaries
Three-address code
t1 := - c t2 := b * t1 t3 := - c t4 := b * t3 t5 := t2 + t4 a := t5
Sample expression
a := b * -c + b * -c
!
Implementa=on of Three-Address Statements: Triples
# Op Arg1 Arg2
(0) uminus c
(1) * b (0)
(2) uminus c
(3) * b (2)
(4) + (1) (3)
(5) := a (4)
Triples Pro: temporaries are implicit
Three-address code
t1 := - c t2 := b * t1 t3 := - c t4 := b * t3 t5 := t2 + t4 a := t5
Sample expression
a := b * -c + b * -c
!
Implementa=on of Three-Address Statements: Indirect Triples
# Op Arg1 Arg2
(14) uminus c
(15) * b (14)
(16) uminus c
(17) * b (16)
(18) + (15) (17)
(19) := a (18)
Triple container
Pro: temporaries are implicit & easier to rearrange code
# Stmt (0) (14) (1) (15) (2) (16) (3) (17) (4) (18) (5) (19)
Program
Syntax-Directed Transla=on into Three-Address Code
Synthesized attributes:
S.code three-address code for S S.begin label to start of S or nil S.after label to end of S or nil E.code three-address code for E
E.place a name holding the value of E ProducEons
S → id := E
| while E do S | S ; S
E → E + E | E * E | - E | ( E ) | id
| num gen(E.place ‘:=’ E
1.place ‘+’ E
2.place)
Syntax-Directed Transla=on into Three-Address Code (cont’d)
ProducEons S → id := E S → while E do S1 E → E1 + E2 E → E1 * E2 E → - E1 E → ( E1 ) E → id E → num S → S1 ; S2
Semantic rules
S.code := E.code || gen(id.place ‘:=’ E.place); S.begin := S.after := nil (see next slide)
E.place := newtemp();
E.code := E1.code || E2.code || gen(E.place ‘:=’ E1.place ‘+’ E2.place) E.place := newtemp();
E.code := E1.code || E2.code || gen(E.place ‘:=’ E1.place ‘*’ E2.place) E.place := newtemp();
E.code := E1.code || gen(E.place ‘:=’ ‘uminus’ E1.place) E.place := E1.place
E.code := E1.code E.place := id.name E.code := ‘’
E.place := newtemp();
E.code := gen(E.place ‘:=’ num.value)
S.code := S1.code || S2.code S.begin := S1. begin S.after := S2.after
Syntax-Directed Transla=on into Three-Address Code (cont’d)
ProducEon
S → while E do S1
Semantic rule
S.begin := newlabel() S.after := newlabel()
S.code := gen(S.begin ‘:’) ||
E.code ||
gen(‘if’ E.place ‘=‘ ‘0’ ‘goto’ S.after) ||
S1.code ||
gen(‘goto’ S.begin) ||
…
if E.place = 0 goto S.after S.code
E.code
goto S.begin
S.begin:
S.after:
18
Example (check it at home!)
i := 2 * n + k;
while i do
i := i - k!
t1 := 2
t2 := t1 * n t3 := t2 + k i := t3
L1: if i = 0 goto L2 t4 := i - k
i := t4 goto L1 L2:
How does the code access names?
• The three-address code generated by the syntax- directed defini=ons shown is simplis=c
• It assumes that the names of variables can be easily resolved by the back-end in global or local variables
• We need local symbol tables to record global declara=ons as well as local declara=ons in procedures, blocks, and records (structs) to resolve names
• We will see all this later in the course
Transla=ng Logical and Rela=onal Expressions
a or b and not c
t1 := not c
t2 := b and t1 t3 := a or t2
if a < b goto L1 t1 := 0
goto L2 L1: t1 := 1 L2:
a < b
Boolean expressions intended to represent values:
Boolean expressions used to alter the control flow:
Short-Circuit Code
• The boolean operators &&, || and ! are translated into jumps.
• Example:
if ( x < 100 || x > 200 && x != y ) x = 0;
may be translated into:
if x < 100 goto L2
ifFalse x > 200 goto L1 ifFalse x ! = y goto L1 L2: x=0
L1:
Transla=ng Flow-of-control Statements
22
·˨̊ᗮ
"Đdz 67.XÆ>dzƯ dz
ߖᗮྲྀအᑌᗮहအྲྀበೊ়ᅻᗮዔఀᗮዔᅻࡐྲྀበเࡐዔೊအྲྀᗮအᗮ࣒အအเࡐྲྀᗮᒏႼᅻበበအྲྀበᗮྲྀዔအᗮዔఀᅻŸࡐ়়ᅻበበᗮहအ়ᗮ
ೊྲྀᗮዔఀᗮहအྲྀዔᒏዔᗮအᗮበዔࡐዔ༌ྲྀዔበᗮበᎯहఀᗮࡐበᗮዔఀအበᗮஸྲྀᅻࡐዔ়ᗮ࣒ᒹᗮዔఀᗮအเเအᑌྲྀஸᗮஸᅻࡐ༌༌ࡐᅻгᗮ
ŗ͆ ҿ
͆ ҿ
͆ Hҿ
ɼÎ͆æ ŗ:͆
ɼÎ͆æ f͆ ɼ %͆
'ɼ Î͆æ :͆
צྮᗮዔఀበᗮႼᅻအ়Ꭿहዔೊအྲྀበýᗮ࿘အྲྀዔᅻ༌ྲྀࡐเᗮ
͆ᅻႼᅻበྲྀዔበᗮࡐᗮ࣒အအเࡐྲྀᗮᒏႼᅻበበೊအྲྀᗮࡐྲ়ྀᗮྲྀအྲྀᔳ ዔᅻ༌ೊྲྀࡐเᗮ
͆ᅻႼᅻበྲྀዔበᗮࡐᗮበዔࡐዔ༌ྲྀዔȪᗮ
ݫೊበᗮஸᅻࡐ༌༌ࡐᅻᗮஸྲྀᅻࡐเᔎበᗮዔఀᗮᅻᎯྲྀྲྀྲྀஸᗮᒏࡐ༌Ⴜเᗮအᗮᑌఀเᗮᒏწᅻበበೊအྲྀበᗮዔఀࡐዔᗮᑌᗮ
ೊྲྀዔᅻအ়Ꭿह়ᗮೊగᗮիᒏࡐ༌ႼเᗮΥȪ ̊ДȪᗮ ӕበᗮೊྲྀᗮዔఀࡐዔᗮᒏࡐ༌Ⴜเýᗮ࣒အዔఀᗮԊ ࡐྲ়ྀᗮ
͆ఀࡐᐕᗮࡐᗮበᒹྲྀዽఀᔳ በೊᔎ়ᗮࡐዔዔᅻ࣒Ꭿዔᗮ
͆ᑌఀೊहఀᗮஸೊᐕበᗮዔఀᗮዔᅻࡐྲྀበเዔೊအྲྀᗮೊྲྀዔအᗮዔఀᅻŸࡐ়়ᅻበበᗮೊྲྀበዔᅻᎯहዔೊအྲྀበȪᗮ
֏အᅻᗮበ༌Ⴜเೊहዔᒹýᗮ ᑌᗮ࣒Ꭿเ়ᗮᎯႼᗮዔఀᗮዔᅻࡐྲྀበเࡐዔೊအྲྀበᗮ
͆͆ࡐྲ়ྀᗮ
Ɩ͆͆ࡐኪᗮበዔᅻྲྀஸበýᗮᎯበᔳ
ೊྲྀஸᗮበᒹྲྀዔࡐᒏŸ়ᅻहዔ়ᗮ়୪ྲྀዔೊအྲྀበȷᗮ ݫఀᗮበ༌ࡐྲྀዔೊहᗮᅻᎯเበᗮ়୪ྲྀೊྲྀஸᗮዔఀ ʗᗮ
ǎ͆ࡐዔዔᅻ࣒Ꭿዔበᗮ हအᏆเ়ᗮ࣒ᗮೊ༌Ⴜเ༌ྲྀዔ়ᗮೊྲྀበዔࡐ়ᗮ࣒ᒹᗮ࣒Ꭿೊเ়ೊྲྀஸᗮᏅႼᗮ በᒹྲྀዔࡐᒏᗮዔᅻበᗮࡐྲ়ྀᗮዔఀྲྀᗮ༌ೊዔዔೊྲྀஸᗮ हအ়ᗮ৲Ꭿᅻೊྲྀஸᗮࡐᗮዔᅻ਼ᗮዔᅻࡐᐕᅻበࡐเýᗮအᅻᗮ࣒ᒹᗮࡐྲྀᒹᗮအᗮዔఀᗮࡐႼზᅻအࡐहఀበᗮအᎯዔเྲ়ྀᗮೊྲྀᗮܺहዔೊအྯᗮΥȪΥȪᗮ ݫఀᗮዔᅻࡐྲྀበเࡐዔೊအྲྀᗮအᗮ
ɼǬ"͆:͆हအྲྀበበዔበᗮအᗮ
# ͆အเเအᑌ়ᗮ࣒ᒹᗮ
ŗ: ͆ࡐበᗮเเᎯበᔳ ዔᅻࡐዔ়ᗮೊྲྀᗮ֏ೊஸȪᗮνȪͯΥ
ÏࡐÃ Ȫᗮ ߖೊዔఀྲྀᗮ
# ͆ࡐᅻᗮෟᎯ༌Ⴜበᗮ࣒ࡐበ়ᗮအྲྀᗮዔఀᗮᐕࡐเᎯᗮအᗮ
͆צᗮ
͆በᗮዔᅻᎯýᗮहအྲྀዔᅻအเᗮအᑌበᗮዔအᗮዔఀᗮ୪ᅻበዔᗮೊྲྀበዔᅻᎯहዔအྲྀᗮအᗮ
: ͆͆ࡐྲ়ྀᗮᗮ
͆ೊበᗮࡐเበýᗮहအྲྀዔᅻအเᗮ
အᑌበᗮዔအᗮዔఀᗮೊྲྀበዔᅻᎯहዔೊအྲྀᗮ༌༌়ೊࡐዔเᒹᗮအเเအᑌྲྀஸᗮ
: '͆͆ዔအᗮ
( !͆(¡ ͆
ዔအᗮ
(¡ď͆ƾ֖֕֗֘ūҿ
( ͆
ዔအᗮ
ƿ֛֚֙֜
ዔᗮ
(¡ !͆(¡͆
( !͆ ¹͆
: Þ ͆ (¡ !͆ ¹͆
2Ŵ ͆
͆ ¹͆ 'Ϯ i!͆
Ï
ࡐÃᗮᗮ
(ď͆ ¹͆2% ͆
¡ i!͆ ¹͆ ͆
0 ͆ ¹͆
ዔအᗮ
(¡ !͆( ͆
ዔအᗮ
(¡ď͆ Ï࣒
ΗೊƉเበᗮ
( !͆ ɧ͆
2Ŵ ͆
'Ϯ0 ͆
(ď͆
हÃᗮ ᑌఀเᗮ
֍ೊிᎯᅻᗮνȩͯΥюᗮ Ԧအ়ᗮအᅻᗮೊƁýᗮŸเበƅýᗮࡐྲ়ྀᗮᑌఆೊเŸበዔࡐዔ༌ྲྀዔበᗮ
ݫఀᗮเࡐ࣒เበᗮအᅻᗮዔఀᗮෟᎯ༌Ⴜበᗮྲྀᗮ
͆͆ࡐྲ়ྀᗮ
2'͆͆ࡐᅻᗮ༌ࡐྲྀࡐஸ়ᗮᎯበೊྲྀஸᗮྲྀఀᅻೊዔ়ᗮ ࡐዔዔᅻೊ࣒ᎯዔበȪᗮ ߖዔఀᗮࡐᗮ࣒အအเࡐྲྀᗮᒏႼᅻበበအྲྀᗮ
͆ᑌᗮࡐበበအहೊࡐዔᗮዔᑌအᗮเࡐ࣒เበюᗮ
͆!͆ዔఀᗮ
Synthesized A"ributes:
S.code, B.Code
Inherited A"ributes:
labels for jumps:
B.true, B.false, S.next
·˨̊ᗮ
"Đdz 67.XÆ>dzƯ dz
ߖᗮྲྀအᑌᗮहအྲྀበೊ়ᅻᗮዔఀᗮዔᅻࡐྲྀበเࡐዔೊအྲྀᗮအᗮ࣒အအเࡐྲྀᗮᒏႼᅻበበအྲྀበᗮྲྀዔအᗮዔఀᅻŸࡐ়়ᅻበበᗮहအ়ᗮ
ೊྲྀᗮዔఀᗮहအྲྀዔᒏዔᗮအᗮበዔࡐዔ༌ྲྀዔበᗮበᎯहఀᗮࡐበᗮዔఀအበᗮஸྲྀᅻࡐዔ়ᗮ࣒ᒹᗮዔఀᗮအเเအᑌྲྀஸᗮஸᅻࡐ༌༌ࡐᅻгᗮ
ŗ͆ ҿ
͆ ҿ
͆ Hҿ
ɼÎ͆æ ŗ:͆
ɼÎ͆æ f͆ ɼ %͆
'ɼ Î͆æ:͆
צྮᗮዔఀበᗮႼᅻအ়Ꭿहዔೊအྲྀበýᗮ࿘အྲྀዔᅻ༌ྲྀࡐเᗮ͆ᅻႼᅻበྲྀዔበᗮࡐᗮ࣒အအเࡐྲྀᗮᒏႼᅻበበೊအྲྀᗮࡐྲ়ྀᗮྲྀအྲྀᔳ ዔᅻ༌ೊྲྀࡐเᗮ͆ᅻႼᅻበྲྀዔበᗮࡐᗮበዔࡐዔ༌ྲྀዔȪᗮ
ݫೊበᗮஸᅻࡐ༌༌ࡐᅻᗮஸྲྀᅻࡐเᔎበᗮዔఀᗮᅻᎯྲྀྲྀྲྀஸᗮᒏࡐ༌Ⴜเᗮအᗮᑌఀเᗮᒏწᅻበበೊအྲྀበᗮዔఀࡐዔᗮᑌᗮ
ೊྲྀዔᅻအ়Ꭿह়ᗮೊగᗮիᒏࡐ༌ႼเᗮΥȪ ̊ДȪᗮ ӕበᗮೊྲྀᗮዔఀࡐዔᗮᒏࡐ༌Ⴜเýᗮ࣒အዔఀᗮԊ ࡐྲ়ྀᗮ͆ఀࡐᐕᗮࡐᗮበᒹྲྀዽఀᔳ በೊᔎ়ᗮࡐዔዔᅻ࣒Ꭿዔᗮ͆ᑌఀೊहఀᗮஸೊᐕበᗮዔఀᗮዔᅻࡐྲྀበเዔೊအྲྀᗮೊྲྀዔအᗮዔఀᅻŸࡐ়়ᅻበበᗮೊྲྀበዔᅻᎯहዔೊအྲྀበȪᗮ
֏အᅻᗮበ༌Ⴜเೊहዔᒹýᗮ ᑌᗮ࣒Ꭿเ়ᗮᎯႼᗮዔఀᗮዔᅻࡐྲྀበเࡐዔೊအྲྀበᗮ͆͆ࡐྲ়ྀᗮƖ͆͆ࡐኪᗮበዔᅻྲྀஸበýᗮᎯበᔳ
ೊྲྀஸᗮበᒹྲྀዔࡐᒏŸ়ᅻहዔ়ᗮ়୪ྲྀዔೊအྲྀበȷᗮ ݫఀᗮበ༌ࡐྲྀዔೊहᗮᅻᎯเበᗮ়୪ྲྀೊྲྀஸᗮዔఀ ʗᗮǎ͆ࡐዔዔᅻ࣒Ꭿዔበᗮ हအᏆเ়ᗮ࣒ᗮೊ༌Ⴜเ༌ྲྀዔ়ᗮೊྲྀበዔࡐ়ᗮ࣒ᒹᗮ࣒Ꭿೊเ়ೊྲྀஸᗮᏅႼᗮ በᒹྲྀዔࡐᒏᗮዔᅻበᗮࡐྲ়ྀᗮዔఀྲྀᗮ༌ೊዔዔೊྲྀஸᗮ हအ়ᗮ৲Ꭿᅻೊྲྀஸᗮࡐᗮዔᅻ਼ᗮዔᅻࡐᐕᅻበࡐเýᗮအᅻᗮ࣒ᒹᗮࡐྲྀᒹᗮအᗮዔఀᗮࡐႼზᅻအࡐहఀበᗮအᎯዔเྲ়ྀᗮೊྲྀᗮܺहዔೊအྯᗮΥȪΥȪᗮ ݫఀᗮዔᅻࡐྲྀበเࡐዔೊအྲྀᗮအᗮɼǬ"͆:͆हအྲྀበበዔበᗮအᗮ# ͆အเเအᑌ়ᗮ࣒ᒹᗮŗ: ͆ࡐበᗮเเᎯበᔳ ዔᅻࡐዔ়ᗮೊྲྀᗮ֏ೊஸȪᗮνȪͯΥÏࡐÃ Ȫᗮ ߖೊዔఀྲྀᗮ# ͆ࡐᅻᗮෟᎯ༌Ⴜበᗮ࣒ࡐበ়ᗮအྲྀᗮዔఀᗮᐕࡐเᎯᗮအᗮ͆ צᗮ͆
በᗮዔᅻᎯýᗮहအྲྀዔᅻအเᗮအᑌበᗮዔအᗮዔఀᗮ୪ᅻበዔᗮೊྲྀበዔᅻᎯहዔအྲྀᗮအᗮ: ͆͆ࡐྲ়ྀᗮᗮ͆ೊበᗮࡐเበýᗮहအྲྀዔᅻအเᗮ
အᑌበᗮዔအᗮዔఀᗮೊྲྀበዔᅻᎯहዔೊအྲྀᗮ༌༌়ೊࡐዔเᒹᗮအเเအᑌྲྀஸᗮ: '͆͆
ዔအᗮ( !͆
(¡ ͆ ዔအᗮ(¡ď͆
ƾ֖֕֗֘ūҿ
( ͆ ዔအᗮ
ƿ֛֚֙֜
ዔᗮ (¡ !͆
(¡͆
( !͆ ¹͆
: Þ ͆ (¡ !͆ ¹͆
2Ŵ ͆
͆ ¹͆ 'Ϯ i!͆
ÏࡐÃᗮᗮ (ď͆ ¹͆
2% ͆
¡ i!͆ ¹͆ ͆
0 ͆ ¹͆ ዔအᗮ(¡ !͆
( ͆ ዔအᗮ(¡ď͆ Ï࣒ΗೊƉเበᗮ
( !͆ ɧ͆
2Ŵ ͆
'Ϯ0 ͆
(ď͆ हÃᗮ ᑌఀเᗮ
֍ೊிᎯᅻᗮνȩͯΥюᗮ Ԧအ়ᗮအᅻᗮೊƁýᗮŸเበƅýᗮࡐྲ়ྀᗮᑌఆೊเŸበዔࡐዔ༌ྲྀዔበᗮ
ݫఀᗮเࡐ࣒เበᗮအᅻᗮዔఀᗮෟᎯ༌Ⴜበᗮྲྀᗮ͆͆ࡐྲ়ྀᗮ2'͆͆ࡐᅻᗮ༌ࡐྲྀࡐஸ়ᗮᎯበೊྲྀஸᗮྲྀఀᅻೊዔ়ᗮ ࡐዔዔᅻೊ࣒ᎯዔበȪᗮ ߖዔఀᗮࡐᗮ࣒အအเࡐྲྀᗮᒏႼᅻበበအྲྀᗮ͆ᑌᗮࡐበበအहೊࡐዔᗮዔᑌအᗮเࡐ࣒เበюᗮ ͆!͆ዔఀᗮ
23
˙ -$˙° ˙ $#ZKZ˙= $ ˙
แࡐ࣒แᗮዏအᗮᑌఀೊहఀᗮहအྲྀዏᅻအแᗮအᑌበᗮೊᗮ#͆ೊበᗮዏᅻᎯûᗮࡐྲ়ྀᗮ#͆ዏఀᗮแࡐ࣒แᗮዏအᗮᑌఀೊहఀᗮहအྲྀዏᅻအแᗮ
အᑌበᗮ ೊᗮ#͆ೊበᗮࡐแበȩᗮ ߖೊዏఀᗮ ࡐᗮ በዏࡐዏ༌ྲྀዏᗮ/͆ ᑌᗮ ࡐበበအहೊࡐዏᗮ ࡐྲྀᗮ ೊྲྀఀᅻೊዏীᗮ ࡐዏዏᅻೊ࣒Ꭿዏᗮ
ɣȁϏi়͆ྲྀအዏೊྲྀஸᗮࡐᗮแࡐ࣒แᗮအᅻᗮዏఀᗮೊྲྀበዏᅻᎯहዏೊအྲྀᗮೊ༌༌়ೊࡐዏแᒹᗮ ࡐዏᅻᗮዏఀᗮहအ়ᗮအᅻᗮ͆
צྲྀᗮበအ༌ᗮहࡐበበûᗮዏఀᗮೊྲྀበዏᅻᎯहዏೊအྲྀᗮೊ༌༌়ೊࡐዏแᒹᗮအแแအᑌೊྲྀஸᗮ͆͆ೊበᗮࡐᗮෟᎯ༌Ⴜᗮዏအᗮበအཌᗮ แࡐ࣒แᗮ ^@ť ĕťෟᎯ༌ႼᗮዏအᗮࡐᗮෟᎯ༌Ⴜᗮዏအᗮ^ťᅻအ༌ᗮᑌೊዏఀೊྲྀᗮ2͆͆ೊበᗮࡐᐕအೊ়়ᗮᎯበೊྲྀஸᗮ͆i͆
ݫఀᗮበᒹྲྀዏࡐᒏŸ়ೊᅻहዏ়ᗮ়୪ྲྀೊዏೊအྲྀᗮೊྲྀᗮ֍ೊஸȪᗮνȩͯϕŸνȩͯϚᗮႼᅻအ়ᎯहበᗮዏఀᅻƉࡐ়়ᅻበበᗮहအ৸ᗮ
အᅻᗮ࣒အအแࡐྲྀᗮᒏႼᅻበበೊအྲྀበᗮೊྲྀᗮዏఀᗮहအྲྀዏᒏዏᗮအᗮೊŸûᗮ್ŸแበŸûᗮࡐྲ়ྀᗮᑌఀೊแŸበዏࡐዏ༌ྲྀዏበȪᗮ
DF;VT);:u
ŏ؛ ò ͆
͆ Ŵ؛ (ɼ
N!36T)u GV1!Ou
͆i͆ 90T͆
ΦϏ͆ ͆͆© © ͆0͆͆i\͆
͆͆ (Iɼ͆
͆ Ď؛ ɼ͆ #͆ \͆ ɂ͆ #͆͆ ҿ 9ʿT͆
#͆ / 2h i͆ / ƥ i͆
2 ͆ /
͆ Ď؛ ȣɼ͆ #͆\͆ 2h͆ɼ%͆ #͆͆ ҿ 90T͆
#͆͆ / 90T͆
: Ǿ͆i͆/ % ͆i͆ ҿ ͆i͆
͆ / # ͆
È͆ 0#\͆ È͆ 2h ͆
Ù Ù ͆N͆'·Ϯ Ɠ͆i\͆
È͆ 0#\͆ È͆ % F ͆
2͆ ò 'ɼ͆ #͆ \͆ :͆ 0 ͆ / 90T͆
#͆͆ ҿ 90T͆
#͆ŏ͆ ҿ 2͆ˋi͆
2h ͆i͆ ҿ 0 ͆
2 ͆ ҿ 00 \͆ È͆ ɵ ͆
È͆ 0# \͆ È͆ : F ͆
È͆ N͆'·Ϯ 0 \͆
͆ Ȟᗮ :͆ %͆ : ͆i͆ ҿ 90˼T͆
Ɋ% Ƌ͆i͆ҿ 2͆i͆
2 ͆ /
֍ೊஸᎯᅻᗮνȩͯνђᗮ ܺᒹྲྀዏࡐᒏŸ়ೊᅻहዏ়ᗮ়୪ྲྀೊዏೊအྲྀᗮးᅻᗮအᑌŸအ૬Ɖहအྲྀዏᅻအแᗮበዏࡐዏ༌ྲྀዏበȪᗮ ߖᗮࡐበበᎯ༌ᗮዏఀࡐዏᗮ90T͆हᅻࡐዏበᗮࡐᗮྲྀᑌᗮแࡐ࣒แᗮࡐहఀᗮዏೊ༌ᗮೊዏᗮೊበᗮहࡐแแ়ûᗮࡐྲ়ྀᗮዏఀࡐዏᗮ
Inherited AGributes
Not relevant for control flow
Transla=on of Boolean Expressions
24
˙ -8˙°Ž˙ 8#ZKZ˙= 8 ˙ हအྲ়ྀഇዏഇအྲྀࡐแᗮࡐྲ়ྀᗮᎯྲྀहအྲ়ྀഇዏഇအྲྀࡐแᗮෟᎯ༌Ⴜበᗮዏအᗮ အྲྀᗮအᗮዏᑌအᗮแࡐ࣒แበгᗮ (͆!͆ഇᗮ(͆ഇበᗮዏᅼᎯĉᗮ ࡐྲ়ྀᗮ(͆͆ഇᗮ(͆ഇበᗮࡐแበȩᗮ
>F;VT*;6u N!56T)u GV1!Ou (͆ C͆ (c͆ l l ť(%͆ (c !͆/(4!͆
(c ͆/ Ě0T͆
(% 4 !͆/(4 !͆
(% ͆/(͆͆
(͆ Jҿ (c͆PPť(%͆ (c !͆/Ě0T͆
(c ͆/(´͆
(% ƕ!͆/( !͆
(% 4͆ҿ(͆͆
( ¡ ͆/
(͆ C͆ ᗮ(c͆ (c ͆!͆ҿ(͆͆
(c ͆/(4!͆
( ͆/(c 4 ͆
(͆ C͆ c͆ Éɼ%͆ ( ͆/
Ù Z ͆N͆ȩϮ c ͆͆ÉIɼ ͆% ͆͆NK..N͆ (4͆!\͆
Z Z ͆N͆K..N͆ (͆´\͆
(͆ C͆ #ɼ (4 ͆/NK..N͆ ( !\͆
(͆ C͆ ɼ (͆͆/N͆K..«͆ (͆Þ\͆
֏ഇஸᎯᅼᗮνȩͯϚюᗮ ֿྲྀᅼࡐዏഇྲྀஸᗮዏఀᅼŸࡐ়়ᅼበበᗮहအ়ᗮအᅼᗮ࣒အအแࡐྲྀበᗮ
ݫఀᗮအᎯᅼዏఀᗮႼᅼအ়Ꭿहዏഇအྲྀᗮഇྲྀᗮ֏ഇஸȪᗮ νȩͯϚĉᗮ(͆ C͆ c͆ Éɼ % ͆ഇበᗮዏᅼࡐྲྀበแࡐዏ়ᗮ়ഇᅼहዏแᒹᗮ ഇྲྀዏအᗮ ࡐᗮ हအ༌Ⴜࡐᅼഇበအྲྀᗮ ዏఀᅼŸࡐ়়ᅼበበᗮ ഇྲྀበዏᅼᎯहዏഇအྲྀᗮ ᑌഇዏఀᗮ ෟᎯ༌Ⴜበᗮ ዏအᗮ ዏఀᗮ ࡐႼႼᅼအႼᅼഇࡐዏᗮ ႼแࡐहበȪᗮ ֏အᅼᗮഇྲྀበዏࡐྲྀहĉᗮ(͆အᗮዏఀᗮအᅼ༌ᗮҿĨ͆ 0͆ዏᅼࡐྲྀበแࡐዏበᗮഇྲྀዏအѓᗮ
Ϯ &Ϯ Ϯ Ϯ K..͆ (!͆
K..͆ (4͆
ݫఀᗮᅼ༌ࡐഇྲྀഇྲྀஸᗮႼᅼအ়Ꭿहዏഇအྲྀበᗮအᅼᗮ(͆ࡐᅼᗮዏᅼࡐྲྀበแࡐዏ়ᗮࡐበᗮအแแအᑌበгᗮ
؛ ܺᎯႼႼအበᗮ(͆ഇበᗮအᗮዏఀᗮအᅼ༌ᗮ(c͆ , , Ϗ(% 4͆ רᗮ(c͆ഇበᗮዏᅼᎯĉᗮዏఀྲྀᗮᑌᗮഇ༌༌়ഇࡐዏแᒹᗮ คྲྀအᑌᗮዏఀࡐዏᗮ(͆ഇዏበแᗮഇበᗮዏᅼᎯĉᗮበအᗮ(c 4͆!͆ഇበᗮዏఀᗮበࡐ༌ᗮࡐበᗮ(4͆!͆רᗮ(c͆ഇበᗮࡐแበŃᗮ ዏఀྲྀᗮ(%͆༌Ꭿበዏᗮ࣒ᗮᐕࡐแᎯࡐዏ়ĉᗮበအᗮᑌᗮ༌ࡐคᗮ(c ࣒͆ᗮዏఀᗮ้ࡐ࣒แᗮအᗮዏఀᗮ୪ᅼበዏᗮ ഇྲྀበዏᅼᎯहዏഇအྲྀᗮഇྲྀᗮዏఀᗮहအ়ᗮအᅼᗮ(% ͆ ݫఀᗮዏᅼᎯᗮࡐྲ়ྀᗮࡐแበᗮᒏഇዏበᗮအᗮ(%͆ࡐᅼᗮዏఀᗮበࡐཌྷᗮ ࡐበᗮዏఀᗮዏᅼᎯᗮࡐྲ়ྀᗮࡐแበᗮᒏഇዏበᗮအᗮ(͆ᅼበႼहዏഇᐕแᒹȪᗮ
Inherited AGributes
Example
if ( x < 100 || x > 200 && x != y ) x = 0;
is translated into:
if x < 100 goto L2 goto L3
L3: if x > 200 goto L4 goto L1
L4: if x != y goto L2 goto L1
L2: x=0 L1:
if x < 100 goto L2
ifFalse x > 200 goto L1 ifFalse x ! = y goto L1 L2: x=0
By removing several redundant jumps we can obtain the equivalent:
Transla=ng Short-Circuit Expressions Using Backpatching
E → E or M E | E and M E | not E
| ( E )
| id relop id | true
| false M → ε
M : marker nonterminal
Synthesized attributes:
E.truelist backpatch list for jumps on true E.falselist backpatch list for jumps on false
M.quad location of current three-address quad
Idea: avoid using inherited a"ributes by genera=ng par=al
code. Addresses for jumps will be inserted when known.
Backpatch Opera=ons with Lists
• makelist(i) creates a new list containing three-address location i, returns a pointer to the list
• merge(p
1, p
2) concatenates lists pointed to by p
1and p
2, returns a pointer to the concatenated list
• backpatch(p, i) inserts i as the target label for each of
the statements in the list pointed to by p
28
Backpatching with Lists: Example
a < b or c < d and e < f
100: if a < b goto _ 101: goto _
102: if c < d goto _ 103: goto _
104: if e < f goto _ 105: goto _
backpatch
100: if a < b goto TRUE 101: goto 102
102: if c < d goto 104 103: goto FALSE
104: if e < f goto TRUE 105: goto FALSE
Backpatching with Lists: Transla=on Scheme
M → ε { M.quad := nextquad() } E → E1 or M E2
{ backpatch(E1.falselist, M.quad);
E.truelist := merge(E1.truelist, E2.truelist);
E.falselist := E2.falselist } E → E1 and M E2
{ backpatch(E1.truelist, M.quad);
E.truelist := E2.truelist;
E.falselist := merge(E1.falselist, E2.falselist); } E → not E1 { E.truelist := E1.falselist;
E.falselist := E1.truelist } E → ( E1 ) { E.truelist := E1.truelist;
E.falselist := E1.falselist }
Backpatching with Lists: Transla=on Scheme (cont’d)
E → id1 relop id2
{ E.truelist := makelist(nextquad());
E.falselist := makelist(nextquad() + 1);
emit(‘if’ id1.place relop.op id2.place ‘goto _’);
emit(‘goto _’) }
E → true { E.truelist := makelist(nextquad());
E.falselist := nil;
emit(‘goto _’) }
E → false { E.falselist := makelist(nextquad());
E.truelist := nil;
emit(‘goto _’) }
Flow-of-Control Statements and Backpatching: Grammar
S → if E then S
| if E then S else S | while E do S
| begin L end | A
L → L ; S | S
Synthesized attributes:
S.nextlist backpatch list for jumps to the next statement after S (or nil)
L.nextlist backpatch list for jumps to the next statement after L (or nil)
S1 ; S2 ; S3 ; S4 ; S5 … backpatch(S1.nextlist, 200) backpatch(S2.nextlist, 300)
100: Code for S1 200: Code for S2 300: Code for S3
Jumps out of S1
Flow-of-Control Statements and Backpatching
The grammar is modified adding suitble marking non-terminals S → A { S.nextlist := nil }
S → begin L end
{ S.nextlist := L.nextlist } S → if E then M S1
{ backpatch(E.truelist, M.quad);
S.nextlist := merge(E.falselist, S1.nextlist) } L → L1 ; M S { backpatch(L1.nextlist, M.quad);
L.nextlist := S.nextlist; } L → S { L.nextlist := S.nextlist; } M → ε { M.quad := nextquad() }
A → …
Non-compound statements, e.g. assignment, func&on call
Flow-of-Control Statements and Backpatching (cont’d)
S → if E then M1 S1 N else M2 S2
{ backpatch(E.truelist, M1.quad);
backpatch(E.falselist, M2.quad);
S.nextlist := merge(S1.nextlist,
merge(N.nextlist, S2.nextlist)) } S → while M1 E do M2 S1
{ backpatch(S1.nextlist, M1.quad);
backpatch(E.truelist, M2.quad);
S.nextlist := E.falselist;
emit(‘goto M1.quad’) }
N → ε { N.nextlist := makelist(nextquad());
Summarizing…
• Transla=on from source code to intermediate representa=on can be performed in a syntax- directed way during parsing
• We considered transla=on of expressions and statements to three address code, with a
simplified handling of names (for example: no defini=ons)
• More effec=ve transla=on of boolean expressions for flow control require inherited aGributes
• They can be avoided using backpatching
34