Anda di halaman 1dari 5

Computer Science 332 8.

3 Assignment Statements
In 8.1 we ignored the issue of symbol-table entry and lookup
(just assumed .place attribute worked properly)
Compiler Construction Now we show how symbol tables are actually used.
Replace .code attribute and gen function with emit function,
which emits (generates) three-address code directly
Chapter 8: Intermediate Code From previous section, we assume expressions are evaluated
Generation in context of declarations:
8.3-8.4: Assignment Statements and P 

MD
M 


Boolean Expressions D 

D ; D | id : T | proc id ; D ; S
N 

8.3 Assignment Statements Reusing Temporary Names


S 

id := E { p := lookup (id.name); // get address: t1, etc. newtmp generates a new temporary variable (t1, t2, t3, ...)
if p nil then emit (p ':=' E.place)


each time it is called


else error } If we put temporaries in the symbol table, it eventually gets
E 

E1 + E2 { E.place := newtmp; // returns t1, t2, etc.


cluttered with them (t1043, t1044, t1045, ...)
emit(E.place ':= ' E1.place '+' E2.place) }
But we only need at most three of them, for three-address
E 

- E1 { E.place := newtmp;
code:
emit(E.place ':= 'uminus' E1.place) }
evaluate E1 into t1
E 

( E1 ) { E.place := E1.place; } E 

E1 + E2 ⇒ evaluate E2 into t2
E 

id { p := lookup (id.name); t1 := t1 + t2
if p nil then E.place := p


else error }
Reusing Temporary Names 8.4 Boolean Expressions
Solution: keep a count of temporaries, which gets incremented Recall our grammar from PS7:
when a temp is created, and decremented when a temp is used
as an operand (acts like a stack) expr 

comp-expr | cond-expr | bool-expr | ... | boolean


E.g., x := a * b + c * d – e * f comp-expr 

expr > expr | expr < expr


cond-expr 

if expr then expr else expr


Statement Count
0 bool-expr 

expr and expr | expr or expr


t0 := a * b 1
boolean 

true | false
t1 := c * d 2
t0 := t0 + t1 1
t1 := e * f 2 Need a way of translating booleans and control-flow (if-then-
t0 := t0 - t1 1 else) into three-address code
x := t0 0

8.4 Boolean Expressions Numerical Representation


• Two basic approaches
– Numerical Representation a or b and not c


• true represented as 1
• false represented as 0
• and, or work like arithmetic expressions t1 := not c
– Flow-of-control t2 := b and t1
• Represent value of boolean by position in program t3 := a or t1
• E.g., if first part of or evaluates to true, jump over evaluation of
second part
Numerical Representation Numerical Representation
E 

E1 or E2 { E.place := newtmp;
emit(E.place ':= ' E1.place 'or' E2.place) }
if a < b then 1 else 0 E 

E1 and E2 { E.place := newtmp;


emit(E.place ':= ' E1.place 'and' E2.place) }

⇓ E 

not E1 { E.place := newtmp;


emit(E.place ':= ' 'not' E1.place) }
100: if a < b goto 103
101: t := 0
102: goto 104 E 

( E1 ) { E.place := E1.place; }
103: t :=1
E 

true { E.place := newtmp; emit(E.place ':= 1' )}


104: ...
E 

false { E.place := newtmp; emit(E.place ':= 0' )}

Numerical Representation Flow-of-Control Statements


Consider grammar
E 

id1 relop id2 { E.place := newtmp;


S if E then S1 | if E then S1 else S2 | while E do S1


emit( 'if' id1.place relop.op id2.place


'goto' nexstat + 3); Each boolean expression E gets two label attributes
emit(E.place ':= 0');
emit( 'goto' nexstat + 2); – true : where to go when expression evaluates to true
emit(E.place ':= 1');}
false : where to go when expression evaluates to false
where nexstat is address of next statement Inherited attribute S.next is address of next instruction after S
Inherited attribute S.begin is address of first instruction of S
Flow-of-Control Statements Flow-of-Control Statements

E.code S.begin:
E.code E.code
E.true: S1.code E.true: S1.code E.true: S1.code
E.false: ... goto S.next goto S.begin
if-then
E.false: S2.code E.false: ...
S.next: ... while-do
if-then-else

Flow-of-Control Statements Flow-of-Control Statements


S 

if E then S1 { E.true := newlabel;


E.false := S.next;
S 

while E do S1 { S.begin := newlabel;


S1 .next := S.next;
E.true := newlabel;
S.code := E.code || gen (E.true ':' ) S1 .code }
E.false := S.next;
S 

if E then S1 else S2 { E.true := newlabel; S1 .next := S.begin;

E.false := newlabel; S.code := gen (S.begin ':' ) || E.code ||


S1 .next := S.next; gen (E.true ':' ) || S1 .code ||
S2 .next := S.next; gen ('goto' S.begin) }
S.code := E.code ||
gen (E.true ':' ) S1 .code ||
gen ('goto' S.next ) ||
gen (E.false ':' ) S2 .code }
Control-Flow Translation of Boolean Control-Flow Translation
Expressions
E 

E1 or E2 { E1.true := E.true;
• Now we can see how to implement the flow-of-control version
E1.false := newlabel
of boolean expression translation.
E2.true := E.true;
• E.g., a < b or c < d and e < f E2.false := E.false;


E.code := E1.code || gen (E1.false ':' ) || E2.code }

if a < b goto Ltrue // whole thing true E 

E1 and E2 { E1.true := newlabel;


goto L1
L1: if c < d goto L2 E1.false := E.false
goto Lfalse // whole thing false E2.true := E.true;
L2: if e < f goto Ltrue
goto Lfalse E2.false := E.false;
E.code := E1.code || gen (E1.true ':' ) || E2.code }

Control-Flow Translation Control-Flow Translation


E 

not E1 { E1.true := E.false; E 

id1 relop id2 { gen ( 'if' id1.place relop.op id2.place


E1.false := E.true 'goto' E.true) ||
E.code := E1.code; } gen ( 'goto' E.false) }

E 

( E1 ) {E1.true := E.true;
E1.false := E.false
E.code := E1.code;}

E 

true { E.code := gen ( 'goto' ) || E.true }

E 

false { E.code := gen ( 'goto' ) || E.false}

Anda mungkin juga menyukai