Boolean expressions 1 productionsemantic action E E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel...

47
Boolean expressions 1 production semantic action E E1 or E2 E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel = E.falseLabel; E.code = E1.code || gen (E1.falseLabel ‘:’) || E2.code E E1 and E2 E1.trueLabel = freshLabel(); E1.falseLabel = E.falseLabel; E2.trueLabel = E.trueLabel; E2.falseLabel = E.falseLabel; E.code = E1.code || gen (E1.trueLabel ‘:’) || E2.code E not E1 E1.trueLabel = E.falseLabel; E1.falseLabel = E.trueLabel; E.code = E1.code; E (E1) E1.trueLabel = E.trueLabel; E1.falseLabel = E.falseLabel; E.code = E1.code; E id1 E.code=gen (‘if’ id1.var relop id2.var ‘goto’ Generate code that jumps to E.trueLabel if E’s value is true and to B.falseLabel if E’s value is false.

Transcript of Boolean expressions 1 productionsemantic action E E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel...

Page 1: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

1

Boolean expressions

production semantic action

E E1 or E2 E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel = E.falseLabel;E.code = E1.code || gen (E1.falseLabel ‘:’) || E2.code

E E1 and E2 E1.trueLabel = freshLabel(); E1.falseLabel = E.falseLabel;E2.trueLabel = E.trueLabel; E2.falseLabel = E.falseLabel;E.code = E1.code || gen (E1.trueLabel ‘:’) || E2.code

E not E1 E1.trueLabel = E.falseLabel; E1.falseLabel = E.trueLabel; E.code = E1.code;

E (E1) E1.trueLabel = E.trueLabel; E1.falseLabel = E.falseLabel; E.code = E1.code;

E id1 relop id2 E.code=gen (‘if’ id1.var relop id2.var ‘goto’ E.trueLabel)||gen(‘goto’ E.falseLabel);

E true E.code = gen(‘goto’ B.trueLabel)

E false E.code = gen(‘goto’ B.falseLabel);

Generate code that jumps to E.trueLabel if E’s value is true and to B.falseLabel if E’s value is false.

Page 2: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

2

Boolean expressionsproduction semantic action

E E1 or E2 E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel();E2.trueLabel = E.trueLabel;E.falseLabel = E.falseLabel;E.code = E1.code || gen (E1.falseLabel ‘:’) || E2.code

Page 3: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

3

Boolean Expressions: an Example

E

E E

a < b

or

E

c < d

E

e < f

and

Page 4: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

4

Boolean Expressions: an Example

E

E E

a < b

or

E

c < d

E

e < f

and

if a < b goto 103 100:T1 := 0 101:goto 104 102:T1 := 1 103:

Page 5: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

5

Boolean Expressions: an Example

E

E E

a < b

or

E

c < d

E

e < f

and

if a < b goto 103 100:T1 := 0 101:goto 104 102:T1 := 1 103:

if c < d goto 107 104:T2 := 0 105:goto 108 106:T2 := 1 107:

Page 6: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

6

Boolean Expressions: an Example

E

E E

a < b

or

E

c < d

E

e < f

and

if a < b goto 103 100:T1 := 0 101:goto 104 102:T1 := 1 103:

if c < d goto 107 104:T2 := 0 105:goto 108 106:T2 := 1 107:

if e < f goto 111 108:T3 := 0 109:goto 112 110:T3 := 1 111:

112:

Page 7: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

7

Boolean Expressions: an Example

E

E E

a < b

or

E

c < d

E

e < f

and

if a < b goto 103 100:T1 := 0 101:goto 104 102:T1 := 1 103:

if c < d goto 107 104:T2 := 0 105:goto 108 106:T2 := 1 107:

if e < f goto 111 108:T3 := 0 109:goto 112 110:T3 := 1 111:

112:113:T4 := T2 and T3

Page 8: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

8

Boolean Expressions: an Example

E

E E

a < b

or

E

c < d

E

e < f

and

if a < b goto 103 100:T1 := 0 101:goto 104 102:T1 := 1 103:

if c < d goto 107 104:T2 := 0 105:goto 108 106:T2 := 1 107:

if e < f goto 111 108:T3 := 0 109:goto 112 110:T3 := 1 111:

112:113:T4 := T2 and T3

T5 := T1 or T4

Page 9: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

9

Boolean expressions

production semantic action

B B1 or B2 B1.trueLabel = B.trueLabel; B1.falseLabel = freshLabel(); B2.trueLabel = B.trueLabel; B2.falseLabel = B.falseLabel;B.code = B1.code || gen (B1.falseLabel ‘:’) || B2.code

B B1 and B2 B1.trueLabel = freshLabel(); B1.falseLabel = B.falseLabel;B2.trueLabel = B.trueLabel; B2.falseLabel = B.falseLabel;B.code = B1.code || gen (B1.trueLabel ‘:’) || B2.code

B not B1 B1.trueLabel = B.falseLabel; B1.falseLabel = B.trueLabel; B.code = B1.code;

B (B1) B1.trueLabel = B.trueLabel; B1.falseLabel = B.falseLabel; B.code = B1.code;

B id1 relop id2 B.code=gen (‘if’ id1.var relop id2.var ‘goto’ B.trueLabel)||gen(‘goto’ B.falseLabel);

B true B.code = gen(‘goto’ B.trueLabel)

B false B.code = gen(‘goto’ B.falseLabel);

Generate code that jumps to B.trueLabel if B’s value is true and to B.falseLabel if B’s value is false.

Page 10: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

10

Boolean expressionsproduction semantic action

B B1 or B2 B1.trueLabel = B.trueLabel; B1.falseLabel = freshLabel();B2.trueLabel = B.trueLabel;B.falseLabel = B.falseLabel;B.code = B1.code || gen (B1.falseLabel ‘:’) || B2.code

Page 11: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

11

Example

S

if B then S1

B1 B2and

falsetrue

B1.trueLabel = freshLabel();B1.falseLabel = B.falseLabel;B2.trueLabel = B.trueLabel;B2.falseLabel = B.falseLabel;B.code = B1.code || gen (B1.trueLabel ‘:’) || B2.code

B.code = gen(‘goto’ B1.trueLabel)

B.code = gen(‘goto’ B2.falseLabel)

Page 12: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

12

Example

S

if B then S1

B1 B2and

falsetrue

B.trueLabel = freshLabel();B.falseLabel = S.next;S1.next = S.next;S.code = B.code || gen (B.trueLabel ‘:’) || S1.code

B1.trueLabel = freshLabel();B1.falseLabel = B.falseLabel;B2.trueLabel = B.trueLabel;B2.falseLabel = B.falseLabel;B.code = B1.code || gen (B1.trueLabel ‘:’) || B2.code

B.code = gen(‘goto’ B1.trueLabel)

B.code = gen(‘goto’ B2.falseLabel)

Page 13: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

13

Computing the labels

• We can build the code while parsing the tree bottom-up, leaving the jump targets vacant.

• We can compute the values for the labels in a second traversal of the AST

Page 14: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

Why is it difficult?

• Think of an if-then-else statement. • To compute S1.next, we need to know the code of all

blocks S1, B, S2, in order to compute the address that follows them.

• On the other hand, to compute the code of S1, we need to know S1.next, or S.next, which is not known before S1 is computed.

• So we cannot compute S1’s code with all jump targets, but we can compute it up to “leaving space” for future insertion of S1.next.

• Using backpatching we maintain a list of all empty spaces that need to jump to S1.next.

• When we know S1.next, we go over this list and update the jump targets with S1.next’s value.

if B

S

then elseS1 S2

Page 15: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

15

Backpatching

• Goal: generate code in a single pass

• Generate code as we did before, but manage labels differently

• Keep targets of jumps empty until values are known, and then back-patch them

• For every label, maintain a list of instructions that jump to this label

• When the address of the label is known, go over the list and update the address of the label

Page 16: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

• BackPatching is putting the address instead

of labels when the proper label is determined. Backpatching Algorithms perform three types of operations–  makelist(i) – creates a new list containing only i, an

index into the array of quadruples and returns pointer to the list it has made.

– merge(i,j) – concatenates the lists pointed to by i and j ,and returns a pointer to the concatenated list.

– backpatch(p,i) – inserts i as the target label for each of the statements on the list pointed to by p.

• New synthesized attributes for B– B.truelist – list of jump instructions that eventually

get the label where B goes when B is true.– B.falselist – list of jump instructions that eventually

get the label where B goes when B is false.16

Page 17: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

17

Functions for list handling

• makelist(addr) – create a list of instructions containing addr

• merge(p1,p2) – concatenate the lists pointed to by p1 and p2, returns a pointer to the new list

• backpatch(p,addr) – inserts i as the target label for each of the instructions in the list pointed to by p

Page 18: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

Accumulating the code

• Assume a bottom-up parsing so that the code is created in the correct order from left to right, bottom-up.

• The semantic analysis is actually executed during parsing and the code is accumulated.

• Recall that we associated two labels B.trueLabel and B.falseLabel for each expression B, which are the labels to which we should jump if B turns out true or false.

• We will now replace these with two lists B.truelist and B.falselist, which record all instructions that should be updated with the address of B.trueLabel or B.falseLabel when we discover their values.

• In addition, we also replace S.next with S.nextlist, maintaining all instructions that should jump to S.next, when we know what it is.

Page 19: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

Accumulating Code (cont’d)

• B.truelist and B.falselist are generated attributes: the descendants tell the parent where there is code to fix.

• When ascending to the parent of B, we know what are the relevant addresses and we can backpatch them into all the instruction locations that are in the list.

• Similarly for S.nextlist.• We will need a function nextinstr() that retruns

the address of the next instruction.

Page 20: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

Computing Boolean expressions • Recall the code jumps to B.true ot B.false according to B’s

value.• Previously:

• Now with backpatching:

{ B.code := gen ( ' if ' id1.var relop.op id2.var ' goto ' B.true ) ||

gen ( ' goto ' B.false ) }

B → id1 relop id2

{ B.code := gen ( ' goto ' B.true ) } B → true

{ B.code := gen ( ' goto ' B.false ) } B → false

{ B.truelist := makelist ( nextinstr ) ; B.falselist := makelist ( nextinstr + 1 ) ; emit ( ' if ' id1.var relop.op id2.var ' goto_ ' ) || emit ( ' goto_ ' ) }

B → id1 relop id2

{ B.truelist := makelist ( nextinstr ) ; emit ( ' goto_ ' ) } B → true{ B.falselist := makelist ( nextinstr ) ; emit ( ' goto_ ' ) } B → false

Page 21: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

Computing Boolean expressions• Recall the code jumps to B.true ot B.false according to B’s

value.• Previously:

• Now with backpatching:

{ B1.true := B.false ; B1.false := B.true ; B.code := B1.code } B → not B1

{ B1.true := B.true ; B1.false := B.false ; B.code := B1.code } B → ( B1 )

{ B.truelist := B1.falselist ; B.falselist := B1.truelist } B → not B1

{ B.truelist := B1.truelist ; B.falselist := B1.falselist } B → ( B1 )

Page 22: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

Computing Boolean expressions• Recall the code jumps to B.true ot B.false according to B’s

value.• Previously:

• Now with backpatching:

{ B1.true := B.true ; B1.false := newlable() ; B2.true := B.true ;

B2.false := B.false ; B.code := B1.code || gen ( B1.false ' : ') || B2.code }

B → B1 or B2

{ B1.true := newlabel (); B1.false := B.false ; B2.true := B.true ;

B2.false := B.false ; B.code := B1.code || gen ( B1.true ' : (' || B2.code }

B → B1 and B2

{ backpatch ( B1.falselist, M.instr ) ;

B.truelist := merge ( B1.truelist, B2.truelist ) ; B.falselist := B2.falselist }

B → B1 or M B2

{ backpatch ( B1.truelist, M.instr ) ; B.truelist := B2.truelist ;

B.falselist := merge ( B1.falselist, B2.falselist ) }

B → B1 and M B2

{ M.instr := nextinstr } M →

Page 23: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

23

Backpatching Boolean expressionsproduction semantic action

B B1 or M B2 backpatch(B1.falseList,M.instr);B.trueList = merge(B1.trueList,B2.trueList);B.falseList = B2.falseList;

B B1 and M B2 backpatch(B1.trueList,M.instr);B.trueList = B2.trueList;B.falseList = merge(B1.falseList,B2.falseList);

B not B1 B.trueList = B1.falseList;B.falseList = B1.trueList;

B (B1) B.trueList = B1.trueList;B.falseList = B1.falseList;

B id1 relop id2 B.trueList = makeList(nextInstr);B.falseList = makeList(nextInstr+1);emit (‘if’ id1.var relop id2.var ‘goto _’) || emit(‘goto _’);

B true B.trueList = makeList(nextInstr);emit (‘goto _’);

B false B.falseList = makeList(nextInstr);emit (‘goto _’);

M M.instr = nextinstr;

Page 24: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

24

Using a marker

• { M.instr = nextinstr;}• Use M to obtain the address just before B2 code starts

being generated

B1 or

B

M B2

Example:

Page 25: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

25

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto _

B id1 relop id2 B.trueList = makeList(nextInstr);B.falseList = makeList(nextInstr+1);emit (‘if’ id1.var relop id2.var ‘goto _’) || emit(‘goto _’);

B.t = {100}B.f = {101}

Page 26: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

26

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto _

B.t = {100}B.f = {101}

M M.instr = nextinstr;

M.i = 102

Page 27: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

27

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto _

B.t = {100}B.f = {101} M.i = 102

B id1 relop id2 B.trueList = makeList(nextInstr);B.falseList = makeList(nextInstr+1);emit (‘if’ id1.var relop id2.var ‘goto _’) || emit(‘goto _’);

102: if x> 200 goto _103: goto _

B.t = {102}B.f = {103}

Page 28: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

28

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto _

B.t = {100}B.f = {101} M.i = 102

102: if x> 200 goto _103: goto _

B.t = {102}B.f = {103}

M M.instr = nextinstr;

M.i = 104

Page 29: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

29

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto _

B.t = {100}B.f = {101} M.i = 102

102: if x> 200 goto _103: goto _

B.t = {102}B.f = {103}

M.i = 104

B id1 relop id2 B.trueList = makeList(nextInstr);B.falseList = makeList(nextInstr+1);emit (‘if’ id1.var relop id2.var ‘goto _’) || emit(‘goto _’);

104: if x!=y goto _105: goto _

B.t = {104}B.f = {105}

Page 30: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

30

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto _

B.t = {100}B.f = {101} M.i = 102

102: if x> 200 goto 104103: goto _

B.t = {102}B.f = {103}

M.i = 104

104: if x!=y goto _105: goto _

B.t = {104}B.f = {105}

B B1 and M B2 backpatch(B1.trueList,M.instr);B.trueList = B2.trueList;B.falseList = merge(B1.falseList,B2.falseList);

B.t = {104}B.f = {103,105}

Page 31: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

31

ExampleX < 100 or x > 200 and x != y

B

B

x < 100

B

x > 200

B

x != y

B

and

or M

M

100: if x< 100 goto _101: goto 102

B.t = {100}B.f = {101} M.i = 102

102: if x> 200 goto 104103: goto _

B.t = {102}B.f = {103}

M.i = 104

104: if x!=y goto _105: goto _

B.t = {104}B.f = {105}

B.t = {104}B.f = {103,105}

B B1 or M B2 backpatch(B1.falseList,M.instr);B.trueList = merge(B1.trueList,B2.trueList);B.falseList = B2.falseList;

B.t = {100,104}B.f = {103,105}

Page 32: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

32

Example

100: if x<100 goto _101: goto _102: if x>200 goto _103: goto _104: if x!=y goto _105: goto _

100: if x<100 goto _101: goto _102: if x>200 goto 104103: goto _104: if x!=y goto _105: goto _

100: if x<100 goto _101: goto 102102: if x>200 goto 104103: goto _104: if x!=y goto _105: goto _

Before backpatching After backpatchingby the productionB B1 and M B2

After backpatchingby the productionB B1 or M B2

Page 33: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

33

Backpatching for statementsproduction semantic action

S if (B) M S1 backpatch(B.trueList,M.instr);S.nextList = merge(B.falseList,S1.nextList);

S if (B) M1 S1 N else M2 S2

backpatch(B.trueList,M1.instr);backpatch(B.falseList,M2.instr);temp = merge(S1.nextList,N.nextList);S.nextList = merge(temp,S2.nextList);

S while M1 (B) M2 S1

backpatch(S1.nextList,M1.instr);backpatch(B.trueList,M2.instr);S.nextList = B.falseList;emit(‘goto’ M1.instr);

S { L } S.nextList = L.nextList;

S A S.nextList = null;

M M.instr = nextinstr;

N N.nextList = makeList(nextInstr); emit(‘goto _’);

L L1 M S backpatch(L1.nextList,M.instr); L.nextList = S.nextList;

L S L.nextList = S.nextList

Page 34: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

34

Generate code for procedures

• we will see handling of procedure calls in much more detail later

n = f(a[i]);

t1 = i * 4t2 = a[t1] // could have expanded this as well param t2t3 = call f, 1n = t3

Page 35: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

35

Extend grammar for procedures

• type checking– function type: return type, type of formal parameters– within an expression function treated like any other

operator

• symbol table– parameter names

D define T id (F) { S } F | T id, FS return E; | …E id (A) | … A | E, A

expressions

statements

Page 36: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

36

Summary

• Three address code is our IR.• Intermediate code generation is executed while parsing (via

semantic actions). • Creating code for Boolean expressions and for control

statements is more involved. • We typically use short circuit evaluation, value of an

expression is implicit in control location. • We need to compute the branching addresses.• Option 1: compute them in a second AST pass.• Option 2: backpatching (a single pass): maintain lists of

incomplete jumps, where all jumps in a list have the same target. When the target becomes known, all instructions on its list are “filled in”.

Page 37: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

37

Recap

• Lexical analysis– regular expressions identify tokens (“words”)

• Syntax analysis– context-free grammars identify the structure of the program

(“sentences”)

• Contextual (semantic) analysis– type checking defined via typing judgements– can be encoded via attribute grammars

• Syntax directed translation– attribute grammars

• Intermediate representation – many possible IRs– generation of intermediate representation– 3AC

Page 38: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

38

Journey inside a compiler

LexicalAnalysi

s

Syntax Analysi

s

Sem.Analysi

s

Inter.Rep.

Code Gen.

float position;

float initial;

float rate;

position = initial + rate * 60

<float> <ID,position> <;> <float> <ID,initial> <;> <float> <ID,rate> <;> <ID,1> <=> <ID,2> <+> <ID,3> <*> <60>

TokenStream

Page 39: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

39

Journey inside a compiler

LexicalAnalysi

s

Syntax Analysi

s

Sem.Analysi

s

Inter.Rep.

Code Gen.

<ID,1> <=> <ID,2> <+> <ID,3> <*> <60>

60

<id,1>

=

<id,3>

<id,2>

+

*

AST

id symbol type data

1 position float …

2 initial float …

3 rate float …

symbol table

S ID = EE ID | E + E | E * E | NUM

Page 40: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

40

Journey inside a compiler

LexicalAnalysi

s

Syntax Analysi

s

Sem.Analysi

s

Inter.Rep.

Code Gen.

60

=

<id,3>

<id,2>

+

*

<id,1>

inttofloat

60

<id,1>

=

<id,3>

<id,2>

+

*

AST AST

coercion: automatic conversion from int to floatinserted by the compiler

id symbol type

1 position float

2 initial float

3 rate float

symbol table

Page 41: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

41

Journey inside a compiler

LexicalAnalysi

s

Syntax Analysi

s

Sem.Analysi

s

Inter.Rep.

Code Gen.

t1 = inttofloat(60)t2 = id3 * t1t3 = id2 + t2id1 = t3

3AC

60

=

<id,3>

<id,2>

+

*

<id,1>

inttofloat

production semantic rule

S id = E S.code := E. code || gen(id.var ‘:=‘ E.var)

E E1 op E2 E.var := freshVar(); E.code = E1.code || E2.code || gen(E.var ‘:=‘ E1.var ‘op’ E2.var)

E inttofloat(num) E.var := freshVar(); E.code = gen(E.var ‘:=‘ inttofloat(num))

E id

E.var := id.var; E.code = ‘’

t1 = inttofloat(60)t2 = id3 * t1

t3 = id2 * t2id1 = t3

(for brevity, bubbles show only code generated by the node and not all accumulated “code” attribute)

note the structure:translate E1translate E2

handle operator

Page 42: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

42

Journey inside a compiler

Inter.Rep.

Code Gen.

LexicalAnalysi

s

Syntax Analysi

s

Sem.Analysi

s

3AC Optimized

t1 = inttofloat(60)t2 = id3 * t1t3 = id2 + t2id1 = t3

t1 = id3 * 60.0id1 = id2 + t1

value known at compile timecan generate code with converted value

eliminated temporary t3

Page 43: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

43

Journey inside a compiler

Inter.Rep.

Code Gen.

LexicalAnalysi

s

Syntax Analysi

s

Sem.Analysi

s

Optimized

t1 = id3 * 60.0id1 = id2 + t1

Code Gen

LDF R2, id3MULF R2, R2, #60.0LDF R1, id2ADDF R1,R1,R2STF id1,R1

Page 44: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

44

Problem 3.8 from [Appel]

A simple left-recursive grammar: E E + id E id

A simple right-recursive grammar accepting the same language:

E id + E E id

Which has better behavior for shift-reduce parsing?

Page 45: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

45

Answer

The stack never has more than three items on it. In general, withLR-parsing of left-recursive grammars, an input string of length O(n)requires only O(1) space on the stack.

E E + idE id

Input

id+id+id+id+id

id (reduce) E E + E + id (reduce) E E + E + id (reduce) E E + E + id (reduce) E E + E + id (reduce) E

stack

left recursive

Page 46: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

46

Answer

The stack grows as large as the input string. In general, with LR-parsingof right-recursive grammars, an input string of length O(n) requires O(n) space on the stack.

E id + EE id

Input

id+id+id+id+id

id id + id + id id + id + id + id + id id + id + id id + id + id + id id + id + id + id + id + id + id + id + id (reduce) id + id + id + id + E (reduce) id + id + id + E (reduce) id + id + E (reduce) id + E (reduce) E

stack

right recursive

Page 47: Boolean expressions 1 productionsemantic action E  E1 or E2E1.trueLabel = E.trueLabel; E1.falseLabel = freshLabel(); E2.trueLabel = E.trueLabel; E2.falseLabel.

47

Next…

• Runtime Environments