L S - UConn - CSE - University of Connecticut

Compiler Construction Overview
CSE244
Aggelos Kiayias
Computer Science & Engineering Department
The University of Connecticut
371 Fairfield Road, Unit 1155
Storrs, CT 06269-1155
[email protected]
http://www.cse.uconn.edu/~akiayias
CH4.1
Top-Down Parsing
Grammar:
(1)
LS;L
(2)
L
CSE244 (3)
S  if e then S else S
(4)
S  while e do S
(5)
S  begin L end
(6)
Ss
Construct First & Follow Tables.
First
L
 if while begin s
S
if while begin s
Follow
L $ end
S
; else
CH4.2
Predictive Recursive Parser
CSE244
main()
{
lookahead=gettoken();
L();
}
L()
{
if lookahead belongs to
‘if’, ‘while’, ‘begin’ , s
then {S();
match(‘;’); L(); }
else /* epsilon production */
}
S()
{
if lookahead = ‘if’ then
{ match(‘if’); match(e); match(‘then’);
S(); match(‘else’); S(); }
else if lookahead = ‘while’ then
{ match(‘while’); match(e);
match(‘do’); S(); }
else if lookahead = ‘begin’ then
{ match(‘begin’); L(); match(‘end’); }
else if lookahead = s then
{ match(s); }
else print(‘error’);
}
match(t:token)
{
if t==gettoken()
then
{
nexttoken();
}
else
{
printf(“error”);
}
}
CH4.3
Table-Driven Parser
;
if
then
else
begin
end
while
s
$
(1)
(2)
(1)
(1)
(2)
(4)
(6)
CSE244
L
S
(1)
synch
(3)
synch
(5)
Grammar is LL(1)
CH4.4
Table-Driven Parser Code
CSE244
main()
{ initstack(); push(L);
repeat
X=top(); lookahead=gettoken();
if X is terminal or $ then
{
if X=lookahead then
{ pop(); nexttoken(); }
else error(); }
else /* X is a non-terminal */
{
switch M[X,lookahead] {
case 1:
pop(); push(S); push(‘;’); push(L);
nexttoken();
case 2:
;
case 3:
... ... ...
...
case ‘synch’: pop(); printf(“error: X expected”);
case ‘empty’: nexttoken(); printf(“error: lookahead
expected”); }
}
CH4.5
SLR Parsing
Grammar:
(1) E  E + T
(2) E  T
CSE244 (3) T  T F
(4) T  F
(5) F  F *
(6) F  a
(7) F  b
Construct First & Follow Tables:
First
E
ab
T
ab
F
ab
Follow
E $+
T $+ab
F $+ab*
CH4.6
Canonical Sets of Items + Goto Diagram
CSE244
Set I0
E’  . E
E.E+T
E.T
T.TF
T.F
F.F*
F.a
F.b
F
Set I3
TF.
FF.*
I4
Set I2
F
ET.
TT.F F
Set I8
F.F*
TTF.
F.a
FF.*
F.b
T
b
I5
a
a
*
I10
Set I6
EE+.T
+ T.TF
T.F
a
b F.F*
F.a
I5
F.b
Set I1
E
E’  E .
EE.+T
Set I4
F  a.
b
Set I5
F  b.
*
T
Set I7
EE+T.
TT.F
F.F*
F.a
F.b
F
Set I9
TF.
FF.*
*
b
a
I5
I4
Set I10
FF*.
CH4.7
SLR Table
+
CSE244
0
1
2
3
4
5
6
7
8
9
10
s6
r2
r4
r6
r7
r1
r3
r4
r5
*
s10
r6
r7
s10
s10
r5
a
s4
s4
r4
r6
r7
s4
s4
r3
r4
r5
b
s5
s5
r4
r6
r7
s5
s5
r3
r4
r5
$
E
1
T
2
acc
r2
r4
r6
r7
8
7
r1
r3
r4
r5
F
3
9
8
CH4.8
Code
CSE244
main()
{ initstack(); push(0);
repeat
state=top(); lookahead=gettoken();
{
switch action[state,lookahead] {
case ‘s4’:
push(4); nexttoken();
case ‘s5’:
push(5); nexttoken();
...
case ‘r1’:
pop();pop();pop();
push(goto(top()));
case ‘r2’:
pop();
push(goto(top()));
...
case ‘acc’:
printf(“Success”);
case ‘empty’: printf(“error”);
...
}
CH4.9
Translation
CSE244
Intuition behind translation:
 Assign attributes to terminals and non-terminals.
 Typically, some attributes will be of type e.g. string
and will carry the translated code as we traverse the
parse-tree.
 Write semantic rules for each production.
 Revisit all parsers and every time a certain
production is “selected” (top-down) or “reduced”
(bottom-up) execute all its semantic rules.
 Things to worry about: dependency between
attributes... course of parsing might be inconsistent
with attribute dependencies.
CH4.10
Simple Translation
CSE244
Grammar:
(1) L  S ; L
(2) L  
(3) S  if e then S else S
(4) S  while e do S
(5) S  begin L end
(6) S  s
Example of an accepted string:
s;
while e do
begin
s;
s;
end ;
if e then s else s ;
s;
Translation Example: removal
of while-loops
s;
100:
if e then goto 101 else goto 102 ;
101:
{ s;
s; };
goto 100;
102:
if e then s else s ;
CH4.11
s
Writing A Translation Scheme
CSE244
Grammar:
(1) L  S ; L1 { L.code =S.code || ‘;’ || L1.code }
(2) L  
{ L.code =  }
(3) S  if e then S1 else S2 { S.code = ‘if’ || e.lex || ‘then’ || S1.code ||
‘else’ || S2.code }
(4) S  while e do S1 { beginlabel = newlabel( );
blocklabel = newlabel ( );
endlabel = newlabel( );
S.code = beginlabel || ‘:’ || ‘if’ || e.lex ||
‘then’ || ‘goto’ || blocklabel || ‘else’ ||
‘goto’ || endlabel || ‘;’ || blocklabel || ‘:’ ||
S1.code || ‘goto’ || beginlabel || ‘;’ ||
endlabel || ‘:’ }
(5) S  begin L end { S.code = ‘{‘ || L.code || ‘}’ }
(6) S  s
{ S.code = s.lex }
CH4.12
Predictive Recursive Translation
CSE244
string main()
{
lookahead=gettoken();
return L();
}
string L()
{
if lookahead belongs to
‘if’, ‘while’, ‘begin’ , s
then {s1 = S();
match(‘;’);
s2 = L();
output = concatenate(s1,’;’,s2);
}
else {output = ‘’}
...
Dealing
with inherited
attributes:
define them as
input to
procedures
return output;
}
CH4.13
Bottom Up Translation
CSE244
main()
{ initstack(); push(0);
repeat
state=top(); lookahead=gettoken();
{
switch action[state,lookahead] {
...
case ‘r1’:
val2=topval();pop();
pop();
val1=topval();pop();
push(goto(top()),concat(val1||’;’||val2));
...
}
(1) L  S ; L1
{ L.code =S.code || ‘;’ || L1.code }
Dealing with inherited attributes:
predict their location into the stack
CH4.14
Yacc+Lex


CSE244 


Translation Engine
Bottom up translation (LALR)
We only need to write the translation scheme
following Yacc specifications.
A variety of attributes can be attached to each nonterminal.
Use of side-effects is possible and recommended to
deal with inherited attributes (instead of looking
into the stack).
CH4.15