compiler construction
DESCRIPTION
Compiler Construction. Sohail Aslam Lecture 39. Boolean Experssions. In programming languages, boolean expressions have two primary purposes: compute logical values x = a < b && d > e conditional expressions in flow-of-control statements. Boolean Experssions. - PowerPoint PPT PresentationTRANSCRIPT
Compiler Compiler ConstructionConstruction
Compiler Compiler ConstructionConstruction
Sohail Aslam
Lecture 39
2
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsIn programming languages, boolean expressions have two primary purposes:• compute logical values
x = a < b && d > e• conditional expressions in flow-
of-control statements
3
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsIn programming languages, boolean expressions have two primary purposes:• compute logical values
x = a < b && d > e• conditional expressions in flow-
of-control statements
4
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsConsider the grammar
E → E or E | E and E | not E | ( E ) | id relop id | true | false
5
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions We will implement the
boolean expression by flow of control method
I.e., representing the value of a boolean expression by a position reached in the program
6
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions We will implement the
boolean expression by flow of control method
I.e., representing the value of a boolean expression by a position reached in the program
7
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → id1 relop id2
E.code = gen(‘if’ id1 relop id2 ‘goto’ E.true)
|| gen(‘goto’ E.false)
8
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsE → true
E.code = gen(‘goto’ E.true)
E → falseE.code = gen(‘goto’ E.false)
9
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsE → E1 or E2
E1.true = E.true E1.false = newlabel()E2.true = E.true E2.false = E.falseE.code = E1.code ||
gen(E1.false ‘:’) || E2.code
10
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsE → E1 and E2
E1.true = newlabel() E1.false = E.false E2.true = E.true E2.false = E.falseE.code = E1.code ||
gen(E1.true ‘:’) || E2.code
11
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → not E1
E1.true = E.false E1.false = E.true E.code = E1.code
12
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → ( E1 )
E1.true = E.true E1.false = E.false E.code = E1.code
13
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions Consider the expression
a < b or c < d and e < f
Suppose the true and false exits for the entire expression are Ltrue and Lfalse
14
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions Consider the expression
a < b or c < d and e < f
Suppose the true and false exits for the entire expression are Ltrue and Lfalse
15
if a < b goto Ltruegoto L1
L1: if c < d goto L2goto Lfalse
L2: if e < f goto Ltruegoto Lfalse
if a < b or c < d and e < f
16
while a < b if c < d then x = y + z else x = y – z
Consider the while statement
17
L1: if a < b goto L2
goto Lnext
L2: if c < d goto L3
goto L4
L3: t1 = y + z
x = t1
goto L1
L4: t2 = y – zx = t2goto L1
Lnext: nop
while a < b if c < d then x = y + z else x = y – z
18
ImplementationImplementationImplementationImplementation The easiest way to implement
syntax-directed definitions is to use two passes
• construct a syntax tree for the input
• walk the tree in depth-first order
19
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions The problem in generating
three-address code in one pass is that we may not know the labels that the control must go to when we generate jump statements
20
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
However, by using a technique called back-patching, we can generate code in one pass.
21
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
we will generate the jumps with targets temporarily left unspecified
22
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions Each such statement will be
put on a list of goto statements
We will fill the labels when the proper label can be determined (backpatch)
23
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions Each such statement will be
put on a list of goto statements
We will fill the labels when the proper label can be determined (backpatch)
24
BackpatchingBackpatchingBackpatchingBackpatching Assume that the quadruples
are put into an array
Labels will be indicies into this array
To manipulate list of labels, we will use three functions:
25
BackpatchingBackpatchingBackpatchingBackpatching
1. makelist(i) creates and returns a new list containing only i, the index of quadruple
26
BackpatchingBackpatchingBackpatchingBackpatching
2. merge(p1, p2) concatenates lists pointed to by p1 and p2 and returns the concatenated list
27
BackpatchingBackpatchingBackpatchingBackpatching
3. backpatch(p, i) inserts i as the target label for each of the goto statements on list pointed to by p
28
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions We now construct a
translation scheme suitable for producing quads (IR) for boolean expressions during bottom-up parsing
29
The grammar we use is
E → E1 or M E2
| E1 and M E2
| not E1 | ( E1 )| id1 relop id2| true| false
M → {M.quad = nextquad()}
M is the marker non-terminal
M.quad records the number of first statement of E2
30
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions We will associate synthesized
attributes truelist and falselist with the nonterminal E
Incomplete jumps will be placed on these list
31
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions We associate the semantic
action
{ M.quad = nextquad() }
with the production M →
32
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions
The function nextquad() returns the index of the next quadruple to follow
33
Boolean Expressions: ANDBoolean Expressions: ANDBoolean Expressions: ANDBoolean Expressions: ANDE → E1 and M E2{
backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist,
E2.falselist);}
Let us look at the mechanics
34
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions
E → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
If E1 is false, E is also false
35
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean ExpressionsE → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
so the statements on E1.falselist become part of E.falselist
36
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions
E → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
If E1 is true, we must test E2
Compiler Compiler ConstructionConstruction
Compiler Compiler ConstructionConstruction
Sohail Aslam
Lecture 40
38
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean ExpressionsE → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
So the target for E1.truelist must be the beginning of code generated for E2
39
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean ExpressionsE → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
This target is obtained using the markernonterminal M.
40
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions
E → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
M.quad records the number of the firststatement of E2.code.
41
Boolean Expressions: ORBoolean Expressions: ORBoolean Expressions: ORBoolean Expressions: ORE → E1 or M E2
{backpatch(E1.falselist, M.quad); E.truelist = merge(E1.truelist, E2.truelist);E.falselist = E2.falselist;
}If E1 is false, need to test E2
42
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → not E1
{E.truelist = E1.falselist;E.falselist = E1.truelist;
}
43
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → ( E1 ){
E.truelist = E1.truelist;E.falselist = E1.falselist;
}
44
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean ExperssionsE → id1 relop id2
{E.truelist = makelist(nextquad()); E.falselist = makelist(nextquad()
+1); emit(‘if’ id1 relop id2 ‘goto _’) ;emit(‘goto _’ );
}
45
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → true{
E.truelist = makelist(nextquad());
emit(‘goto _’ );}
46
Boolean ExperssionsBoolean ExperssionsBoolean ExperssionsBoolean Experssions
E → false{
E.falselist = makelist(nextquad());
emit(‘goto _’ );}
47
Boolean ExpressionsBoolean ExpressionsBoolean ExpressionsBoolean Expressions
M → {
M.quad = nextquad();
}
48
BackpatchingBackpatchingBackpatchingBackpatching
consider again, the boolean expression
a < b or c < d and e < f
We carry out a bottom-up parse
49
BackpatchingBackpatchingBackpatchingBackpatching In response to reduction of
a < b to E, the two quadruples
100: if a < b goto _101: goto _
are generated
50
RecallRecallRecallRecallE → id1 relop id2
{E.truelist = makelist(nextquad()); E.falselist = makelist(nextquad()
+1); emit(‘if’ id1 relop id2 ‘goto _’) ;emit(‘goto _’ );
}View this in a parse tree
51
E.t = {100}E.f = {101}
c < da < b e < for and
52
BackpatchingBackpatchingBackpatchingBackpatching The marker non-terminal M in
the production
E → E1 or M E2
records the value of nextquad which at this time is 102.
53
E.t = {100}E.f = {101}
c < d
a < b
e < f
M.q = 102
or and
54
BackpatchingBackpatchingBackpatchingBackpatching The reduction of c < d to E,
the two quadruples
102: if c < d goto _103: goto _
are generated
55
E.t = {100}E.f = {101}
E.t = {102}E.f = {103}
c < d
a < b
e < f
M.q = 102
or and
56
BackpatchingBackpatchingBackpatchingBackpatching The marker non-terminal M in
the production
E → E1 and M E2
records the value of nextquad which at this time is 104.
57
E.t = {100}E.f = {101}
E.t = {102}E.f = {103}
c < d
a < b
e < f
M.q = 104
M.q = 102
or and
58
BackpatchingBackpatchingBackpatchingBackpatching Reducing e < f to E,
generates
104: if e < f goto _105: goto _
59
E.t = {100}E.f = {101}
E.t = {102}E.f = {103}
E.t = {104}E.f = {105}
c < d
a < b
e < f
M.q = 104
M.q = 102
or and
60
BackpatchingBackpatchingBackpatchingBackpatching We now reduce by the
production
E → E1 and M E2
61
E.t = {100}E.f = {101}
E.t = {104}E.f = {103, 105}
E.t = {102}E.f = {103}
E.t = {104}E.f = {105}
c < d
a < b
e < f
M.q = 104
M.q = 102
or and
62
Semantic ActionsSemantic ActionsSemantic ActionsSemantic Actions
E → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
63
BackpatchingBackpatchingBackpatchingBackpatching
The semantic action calls
backpatch({102},104)
where {102} denotes E1.truelist containing only 102
64
BackpatchingBackpatchingBackpatchingBackpatching
The six statements generated so far are thus
100: if a < b goto _101: goto _102: if c < d goto _103: goto _104: if e < f goto _105: goto _
65
BackpatchingBackpatchingBackpatchingBackpatching
The semantic action calls
backpatch({102},104)
which fills in 104 in statement 102.
66
BackpatchingBackpatchingBackpatchingBackpatching
The call fills in 104 in statement 102
100: if a < b goto _101: goto _102: if c < d goto 103: goto _104: if e < f goto _105: goto _
104
67
Semantic ActionsSemantic ActionsSemantic ActionsSemantic Actions
E → E1 and M E2
{ backpatch(E1.truelist, M.quad); E.truelist = E2.truelist;E.falselist = merge(E1.falselist, E2.falselist);}
68
E.t = {100}E.f = {101}
E.t = {104}E.f = {103, 105}
E.t = {102}E.f = {103}
E.t = {104}E.f = {105}
c < d
a < b
e < f
M.q = 104
M.q = 102
or
and
104103 105
69
BackpatchingBackpatchingBackpatchingBackpatching We now reduce by the
production
E → E1 or M E2
70
E.t = {100, 104}E.f = {103, 105}
E.t = {100}E.f = {101}
E.t = {104}E.f = {103, 105}
E.t = {102}E.f = {103}
E.t = {104}E.f = {105}
c < d
a < b
e < f
M.q = 104
M.q = 102
or
and
71
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsE → E1 or M E2
{backpatch(E1.falselist, M.quad); E.truelist = merge(E1.truelist, E2.truelist);E.falselist = E2.falselist;
}
72
BackpatchingBackpatchingBackpatchingBackpatching
The semantic action calls
backpatch({101},102)
which fills in 102 in statement 101.
73
BackpatchingBackpatchingBackpatchingBackpatching
100: if a < b goto _101: goto102: if c < d goto 104
103: goto _104: if e < f goto _105: goto _
102
74
BackpatchingBackpatchingBackpatchingBackpatching100: if a < b goto _101: goto 102102: if c < d goto 104 103: goto _104: if e < f goto _105: goto _
These instructions will have their targets filled later in the compilation
75
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsE → E1 or M E2
{backpatch(E1.falselist, M.quad); E.truelist = merge(E1.truelist, E2.truelist);E.falselist = E2.falselist;
}
76
E.t = {100, 104}E.f = {103, 105}
E.t = {100}E.f = {101}
E.t = {104}E.f = {103, 105}
E.t = {102}E.f = {103}
E.t = {104}E.f = {105}
c < d
a < b
e < f
M.q = 104
M.q = 102or
and
{100} {104}{103, 105}
77
Flow-of-Control StatementsFlow-of-Control StatementsFlow-of-Control StatementsFlow-of-Control Statements We now use backpatching
to translate flow-of-control statements in one pass
We will use the same list-handling procedures as before
78
Flow-of-Control StatementsFlow-of-Control StatementsFlow-of-Control StatementsFlow-of-Control Statements We now use backpatching
to translate flow-of-control statements in one pass
We will use the same list-handling procedures as before
79
Flow-of-Control StatementsFlow-of-Control StatementsFlow-of-Control StatementsFlow-of-Control StatementsS →if E then S
| if E then S else S| while E do S| begin L end| A
L → L ; S| S
S denotes a statement
L is a statementlistA is assignment
80
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsS → 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));}
If E is true, jump to M1.quad which is start of code for S1
N is marker non-terminal to introduce jump over code for S2
81
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsN → { N.nextlist = makelist(nextQuad()); emit(‘goto_’); }The attribute N.nextlist records the quad number of the goto it generates
82
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsM → { M.quad = nextQuad(); }
83
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsS → if E then M S1 {
backpatch(E.truelist, M.quad); S.nextlist = merge(
E.falselist,S1.nextlist);}
If E is true, jump to M.quad which is start of code for S1
84
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsS → while M1 E do M2 S1 {
backpatch(S1.nextlist, M1.quad); backpatch(E.truelist, M2.quad); S.nextlist = E.falselist;emit( ‘goto’ M1.quad);
}
85
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsS → begin L end { S.nextlist = L.nextlist; }
86
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsS → A{ S.nextlist = nil; }
initializes S.nextlist to an empty list
87
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsS → L1 ; M S {
backpatch(L1.nextlist, M.quad); L.nextlist = S.nextlist;
}
Statement following L1 in order of execution is beginning of S
88
Semantic ActionsSemantic ActionsSemantic ActionsSemantic ActionsL → S{ L.nextlist = S.nextlist; }
89
ExampleExampleExampleExample
if a<b or c<d and e<f then x=y+z else x=y-z
if E1 or M E2 then x=y+z else x=y-z
90
if E1 or M E2 then x=y+z else x=y-z
if E then x=y+z else x=y-z{ E.truelist=[100,104]
E.falselist=[103,105] }
91
100 if a < b goto _
101 goto 102
102 if c < d goto 104
103 goto _
104 if e < f goto _
105 goto_
106
107
108
109
92
if E then M1 x=y+z else x=y-z M1 → { M1.quad = 106 }
if E then M1 A else x=y-z A → x=y+z { emit(‘x=y+z’) }
if E then M1 S1 else A S1 → A{ S1.nextlist = nil}
if E then M1 S1 N else x=y-z N → { N.nextlist = [107]emit(‘goto _’ }
93
100 if a < b goto _
101 goto 102
102 if c < d goto 104
103 goto _
104 if e < f goto _
105 goto _
106 x=y+z
107 goto _
108
109
94
if E then M1 S1 N else M2 x=y-zM2 → { M2.quad = 108 }
if E then M1 S1 N else M2 A A → x=y-z { emit(‘x=y-z’) }
if E then M1 S1 N else M2 S2 S2 → A{ S2.nextlist = nil }
S{ backpatch([100,104],106) backpatch([103,105],108)S.nextlist=[107]}
95
100 if a < b goto _
101 goto 102
102 if c < d goto 104
103 goto _
104 if e < f goto _
105 goto _
106 x=y+z
107 goto _
108 x=y-z
109
106
106
108
108
96
100 if a < b goto 106
101 goto 102
102 if c < d goto 104
103 goto 108
104 if e < f goto 106
105 goto 108
106 x=y+z
107 goto _
108 x=y-z
109
97
Semantic Actions in YACCSemantic Actions in YACCSemantic Actions in YACCSemantic Actions in YACC
The syntax-directed translation statements can be conveniently specified in YACC
The %union will require more fields because the attributes vary
98
Semantic Actions in YACCSemantic Actions in YACCSemantic Actions in YACCSemantic Actions in YACC
The actual mechanics will be covered in the handout for the syntax-directed translation phase of the course project