Syntax Directed
Syntax Directed
Syntax Directed
y Translation
&
Intermediate Code Generation
Yacc specification
Lex specification JVM specification
with semantic rules
• Translation Schemes:
– indicate the order of evaluation of semantic actions associated with a production rule.
– In other words, translation schemes give a little bit information about implementation details.
%token DIGIT
%%
L : E ‘\n’ { printf(“%d\n”, $1); }
;
E : E ‘+’ T { $$ = $1 + $3; }
| T { $$ = $1
$1; }
;
T : T ‘*’ F { $$ = $1 * $3; }
| F { $$ = $1; }
;
F : ‘(’ E ‘)’ { $$ = $2; }
| DIGIT { $$ = $1; }
;
%%
Input: 5+3*4 L
E.val=17 return
E.val=5 + T.val=12
T val=5
T.val=5 T.val=3
T val=3 * F val=4
F.val=4
digit.lexval=5 digit.lexval=3
Input: 5+3*4 L
E.val=17
E.val=5 T.val=12
T val=5
T.val=5 T.val=3
T val=3 F.val=4
F val=4
digit.lexval=5 digit.lexval=3
Target
Intermediate
Front end Back end machine
code
code
• Enables
E bl machine-independent
hi i d d t code
d optimization
ti i ti
p1 := mkleaf(id, pa);
P2 := mkleaf(num, 4); - id
p3 := mknode('-', p1, p2);
to entry for c
p4 := mkleaf(id
mkleaf(id, pc);
p5 := mknode('+', p3, p4); id num 4
to entry for a
+ *
* d
a -
b c
a * (b + c) E nptr
E.nptr * E.nptr
E nptr
a ( E.nptr )
E.nptr + E.nptr
b c
*
Pro: easy restructuring of code
and/or expressions for a +
intermediate code optimization
Cons: memoryy intensive b c
Dr. P K Singh
21
TCS - 502
Abstract Syntax Trees versus DAGs
a := b * -c + b * -c
:
:= :
:=
a + a +
* * *
c c c
Tree DAG
a := b * -c + b * -c
a := b * -c + b * -c
t1 := - c t1 := - c
t2 := b * t1 t2 := b * t1
t3 := - c t5 := t2 + t2
t4 := b * t3 a := t5
t5 :=
: t2 + t4
a := t5
Linearized representation
p Linearized representation
p
of a syntax tree of a syntax DAG
Productions Synthesized
y attributes:
S → id := E S.code three-address code for S
| while E do S S.begin label to start of S or nil
E→E+E S after
S.after label to end of S or nil
|E*E E.code three-address code for E
|-E E.place a name holding the value of E
|(E)
| id
| num gen(E.place ‘:=’ E1.place ‘+’ E2.place)
Code generation
t3 := t1 + t2
E → E1 + E2 E.place := newtemp();
E.code := E1.code || E2.code || gen(E.place ‘:=’ E1.place ‘+’ E2.place)
E → E1 * E2 E.place
place := newtemp();
E.code := E1.code || E2.code || gen(E.place ‘:=’ E1.place ‘*’ E2.place)
E → - E1 E.place := newtemp();
E.code
code := E1.code
code || gen(E.place
place ‘:=’ uminus E1.place)
:= ‘uminus’ place)
E → ( E1 ) E.place := E1.place
E.code := E1.code
E → id E.place := id.name
E.code := ‘’
E → num E.place
place := newtemp();
E.code := gen(E.place ‘:=’ num.value)
Production
S → while E do S1
Semantic rule
S begin: E.code
S.begin: E code
S.begin := newlabel()
if E.place = 0 goto S.after
S.after := newlabel()
S.code := gen(S.begin ‘:’) || S.code
E.code || goto S.begin
gen(‘if’ E.place ‘=‘ ‘0’ ‘goto’ S.after) || …
S.after:
S1.code ||
gen(‘goto’
(‘ t ’ S.begin)
S b i ) ||
gen(S.after ‘:’)
t1 := 2
t2 := t1 * n
t3 := t2 + k
i := t3
L1: if i = 0 goto L2
t4 := i - k
i := t4
goto L1
L2:
Quads (quadruples)
# Op Arg1 Arg2
(0) uminus
i c
(1) * b (0)
((2)) uminus c
(3) * b (2)
(4) + (1) (3)
(5) := a (4)
Triples
Pro: temporaries are implicit
Cons: difficult to rearrange code
E → E1 * E2 { E.place
place := newtemp();
emit(E.place ‘:=’ E1.place ‘*’ E2.place) }
E → - E1 { E.place
place := newtemp();
emit(E.place ‘:=’ ‘uminus’ E1.place) }
E → ( E1 ) { E.place
place := E1.place
place }
E → id { p := lookup(top(tblptr), id.name);
if p = nil then error()
else if p.level = 0 then // global variable
E.place := id.place
else // local variable in frame
E.place := fp[p.offset] }
Dr. P K Singh TCS - 502 43
Syntax-Directed Translation of Expressions in Scope (cont’d)
E → E1 ^ { E.place := newtemp();
emit(E.place ‘:=’ ‘*’ E1.place) }
45
Reusing Temporary Names
generate
E1 + E2 Evaluate E1 into t1
Evaluate E2 into t2
t3 := t1 + t2
46
Reusing Temporary Names (cont’d)
x := a * b + c * d - e * f
Statement c
0
$0 := a * b 1
$1 := c * d 2
$0 := $0 + $1 1
$1 := e * f 2
$0 := $0 - $1 1
x := $0 0
47
Addressing Array Elements: One-Dimensional
y
Arrays
A : array [10..20] of integer;
t1 := c // c = baseA - 10 * 4
t2 := i * 4
t3 := t1[t2]
… := t3
48
Addressing Array Elements: Multi-Dimensional Arrays
low1 = 1, low2 = 1, n1 = 2, n2 = 3, w = 4
baseA A[1,1]
baseA A[1,1]
A[1,2] A[2,1]
A[1,3] A[1,2]
A[2,1] A[2,2]
A[2,2] A[1,3]
A[2 3]
A[2,3] A[2 3]
A[2,3]
Row-major Column-major
49
Addressing Array Elements: Multi-Dimensional
y
Arrays
A : array [1..2,1..3] of integer; (Row-major)
50
Addressing Array Elements: Grammar
S → L := E
Synthesized attributes:
E→E+E E.place name of temp holding value of E
|(E) Elist.array array name
|L Elist.place name of temp holding index value
L → Elist ] Elist.ndim number of array dimensions
| id L.place lvalue (=name of temp)
L.offset index into array (=name of temp)
Elist → Elist , E null indicates non-array simple id
| id [ E
51
Addressing Array Elements
S → L := E { if L.offset = null then
emit(L.place ‘:=’ E.place)
else
emit(L.place[L.offset] ‘:=’ E.place) }
E → E1 + E2 { E.place := newtemp();
emit(E.place
it(E l ‘:=’
‘ ’ E1.place
l ‘+’ E2.place)
l )}
E → ( E1 ) { E.place := E1.place }
E→L { if L.offset = null then
E.place := L.place
else
E.place ::= newtemp();
emit(E.place ‘:=’ L.place[L.offset] }
52
Addressing Array Elements
L → Elist ] { L.place
L place := newtemp();
L.offset := newtemp();
emit(L.place ‘:=’ c(Elist.array);
emit(L.offset ‘:=’ Elist.place ‘*’ width(Elist.array)) }
L → id { L.place := id.place;
L.offset := null }
Elist → Elist1 , E
{ t := newtemp(); m := Elist1.ndim + 1;
emit(t ‘:=’
:= Elist1.place
place ‘*’
* limit(Elist1.array,
array m));
emit(t ‘:=’ t ‘+’ E.place);
Elist.array := Elist1.array; Elist.place := t;
Elist.ndim := m }
Elist → id [ E { Elist.array := id.place; Elist.place := E.place;
Elist.ndim := 1 }
53
Translating Assignments
Production Semantic Rules
p := lookup(id.name);
if p != NULL then
S Æ id := E emit(p ':=' E.place)
else
error
E.place := newtemp;
E Æ E1 + E2
emit(E.place ':=' E1.place '+' E2.place)
E.place := newtemp;
E Æ E1 * E2
emit(E.place ':=' E1.place '*' E2.place)
E.place
E place :=
: newtemp;
E Æ -E1
emit(E.place ':=' 'uminus' E1.place)
E.true := newlabel;
E.false := S.next;
S1.next := S.next;
S code :=
S.code : E.code
E code || gen(E
gen(E.true
true ':')
: ) || S1
S1.code
code
E.true
E t := newlabel;
l b l
E.false := newlabel;
S1.next := S.next;
S2.next := S.next;
S.code := E.code || gen(E.true ':') || S1.code ||
gen('goto'
g g S.next) || g
gen(E.false ':') ||
S2.code
P K Singh M M M Engg. College, Gorakhpur ICG - 63
S Æ while E do S1
S.begin := newlabel;
E.true := newlabel;
E.false := S.next;
S1.next := S.begin;
S.code := gen(S.begin ':') || E.code || gen(E.true
':') || S1.code || gen('goto' S.begin)
E1.true := E.true;
E1.false := newlabel;
E Æ E1 or E2 E2.true
true := E
E.true;
true;
E2.false := E.false;
E.code := E1.code || gen(E1.false ':') || E2.code
E1.true := newlabel;
E1.false := E.false;
E Æ E1 and E2 E2.true := E.true;
E2.false := E.false;
E.code := E1.code || gen(E1.true ':') || E2.code
E Æ false E.code :=
: gen(
gen('goto'
goto E.false)
while a < b do 1
L1: if a < b goto L2
2
if c < d then goto Lnext
x := y + z L2: if c < d goto L3
else goto L4
x := y - z L3: t1 := y + z
x:= t1
goto L1
L4: t2 := y – z
X := t2
goto L1
g
Lnext:
P K Singh M M M Engg. College, Gorakhpur ICG - 67
Mixed-Mode Expressions
• Boolean expressions often have arithmetic subexpressions, e.g. (a + b) < c
• If false has the value 0 and true has the value 1
– arithmetic expressions
p can have boolean subexpressions
p
– Example: (a < b) + (b < a) has value 0 if a and b are equal
and 1 otherwise
• Some operators may require both operands to be boolean
• Other operators may take both types of arguments, including mixed arguments
t1 := not c
a or b and not c t2 := b and t1
t3 := a or t2
if a < b goto L1
a<b t1 := 0
goto L2
L1: t1 := 1
L2:
70
Backpatching
E → E or M E
Synthesized attributes:
| E and M E E d
E.code three-address
h dd code
d
| not E E.truelist backpatch list for jumps on true
|(E) E.falselist backpatch list for jumps on false
| id relop
l id M quad
M.quad location of current three-address
three address quad
| true
| false
M→ε
71
Backpatch Operations with Lists
72
Backpatching with Lists: Example
100: if a < b goto _
101: goto _
102: if c < d goto
g _
a < b or c < d and e < f
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
73
Backpatching with Lists: Translation Scheme
M→ε { M.quad := nextquad() }
E → E1 or M E2
{ backpatch(E1.falselist,
falselist M.quad);
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.falselist truelist }
E → ( E1 ) { E.truelist := E1.truelist;
E.falselist := E1.falselist }
74
Backpatching with Lists: Translation Scheme
(cont’d)
E → id1 relop id2
{ E.truelist := makelist(nextquad());
E f l li t := makelist(nextquad()
E.falselist k li ( d() + 1);
1)
emit(‘if’ id1.place relop.op id2.place ‘goto _’);
emit(‘goto _ _’) }
E → true { E.truelist := makelist(nextquad());
E.falselist := nil;
emit(‘goto
emit( goto _’)) }
E → false { E.falselist := makelist(nextquad());
E.truelist := nil;
emit(‘goto
it(‘ t _’) ’) }
75
Flow-of-Control Statements and Backpatching:
Grammar
S → if E then S
| if E then
th S else
l S Synthesized attributes:
| while E do S S.nextlist backpatch list for jumps to the
| begin
g L end next statement after S (or nil)
|A L.nextlist backpatch list for jumps to the
next statement after L (or nil)
L→L;S
|S
Jumps
76
Flow-of-Control Statements and Backpatching
77
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);
backpatch(E.truelist, quad);
S.nextlist := E.falselist;
emit(‘goto _’) }
N→ε { N.nextlist := makelist(nextquad());
emit(‘goto _’) }
78
Translating Procedure Calls
S → call id ( Elist )
Elist → Elist , E
|E
foo(a+1, b, 7) t1 := a + 1
t2 := 7
param t1
param b
param t2
call foo 3
79
Translating Procedure Calls
80