|
Inherited attributes offer an efficient way to generate boolean expressions.
Each boolean expression B has two inherited abbributes, B.true and B.false.
The idea is that B should arrange to branch to label B.true when B is true and to branch to label B.false when B is false. There is no attribute B.addr; the value of B is not stored in a variable.
Each statement S has an inherited attribute S.next, which is a label to which S should branch if it needs to do a branch at a place other than its end.
Production and action |
---|
B → E1 == E2 gen(If E1.addr ≠ E2.addr goto B.false); gen(goto B.true); |
B → E1 < E2 gen(If E1.addr ≥ E2.addr goto B.false); gen(goto B.true); |
B → true gen(goto B.true); |
B → false gen(goto B.false); |
B → B1.true = newLabel(); B1.false = B.false; B1 gen(label B1.true); B2.true = B.true B2.false = B.false and B2 |
B → B1.true = B.true; B1.false = newLabel(); B1 gen(label B1.false); B2.true = B.true B2.false = B.false or B2 |
B → B1.true = B.false B1.false = B.true not B1 |
S → id = E gen(id.name = E.addr); |
S → { SL.next = S.next; SL } |
SL → SL1.next = newLabel(); S.next = SL.next; SL1 gen(label SL1.next); S |
SL → ε Do nothing |
S → if B.true = newLabel(); B.false = newLabel(); ( B ) gen(label B.true); S1.next = S2.next = S.next; S1 else gen(goto S.next); gen(label B.false); S2 |
S → if B.true = newLabel(); B.false = S1.next = S.next ( B ) gen(label B.true); S1 |
S → while begin = newLabel(); B.true = newlabel(); B.false = S.next; S1.next = begin; gen(label begin) ( B ) gen(label B.true); S1 gen(goto begin); |
Let's use the above rules to translate
count = 0; while(x < y) { count = 2*count; x = x + 1; }into intermediate code. Here is the result.
t1 = 0 // count = 0 count = t1 label L1 // start while loop if x ≥ y goto L4 goto L2 label L2 t3 = 2 // count = 2*count count = t3 * count label L3 t4 = 1 // x = x + 1 x = x + t4 goto L1 // end of while loop label L4
|