Semantic Analysis
Semantic Analysis
L −› id Enter(id.ptr, L.type)
Abstract Specification
D Call enter()
T T.type =int L L.type=int
Call enter()
int L.type=int L , id id.ptr =c
Call enter()
L.type =int L , id id.ptr = b
id id.ptr=a
Synthesized and Inherited attributes
Inherited attributes
An Inherited attribute is the one whose value at a
node in the parse tree is defined in terms of the
attributes of the parent and/or siblings of that node.
An example
D −› TL L.type = T.type
Here L.type is an inherited attribute.
Inherited attributes are convenient for expressing
the dependency of programming language
construct on the context in which it appears.
Dependency graph
S-attributed definitions
Syntax directed definitions that use synthesized
attributes only are known as S-attributed definitions
L-attributed definitions
Syntax directed definitions are L-attributed if for every
production A −› X1 X2…. Xn an inherited attribute of Xj for
j lies between 1 and n depends on:
1. The attributes(both synthesized as well as inherited) of
the symbols X1, X2,.., Xj-1 and
2. the inherited attributes of A.
This requires the evaluation order as follows:
in(A), in(X1), syn(x1), in(x2), Syn(X2), … , in(Xn),
Syn(Xn), Syn(A).
Possibility of computing the values of
attributes alogwith parsing:
For LL parsing
D −› T { L.type = T.type;} L
L −› {L1.type = L.type;} L1, id {L.dmyenter(id.ptr,
L.type);}
L −› id {L.dmy=enter(id.ptr, L.type);}
T −› int {T.type = int;}
Dependency Graph
D L1.dmy
L3.dmy
id1 id1.ptr=a
Syntax Directed Translation Schemes:
For LR parsing
D −› T L{ Enter(L.place,id.place);}
L −› L1, id {L.place = L1.place; append(L.place, id.place);
L −› id {append(L.place,id.place);}
T −› int {T.type = int;}
Syntax Directed Translation Schemes:
Example(LR Parsing)
D a
T T.type =int L L.place
b
int L.place L , id
c
L.place L , id a b
id a
SDTS : Example(LR Parsing)
E −› E1 + T {E.val = E1.val +T.val;}
E −› T {E.val = T.val;}
T −› T1 * F {T.val = T1.val * F.val;}
T −› F {T.val = F.val;}
F −› NUM {F.val = NUM.val;}
E.val=T.valE + T T.val=T.val*F.val
T
T.val=F.val T *
T.val=F.val F F.val = NUM.val
NUM=a NUM=b
E.True = i
E.False = i+1
SDTS to translate Boolean
expressions into Three-address code
Example: an expression a < b and c > d is represented as
follows (assuming short circuited evaluation):
i) if a < b goto (i+2)
i+1) goto __
i+2) if c > d goto __
i+3) goto __
E.True = i +2
E.False = i +3
E.True = i i+2
SDTS to translate Boolean
expressions into Three-address code
Therefore SDTS is:
E −› E1 or M E2
{ backpatch(E1.False, M.quad);
E.True = merge(E1.True,E2.True);
E.False = E2.False;
}
M −› є { M.quad = Netquad;}
SDTS to translate Boolean
expressions into Three-address code
Example: an expression not a < b is represented as follows :
i) if a < b goto __
i+1) goto __
E.True = i +1
E.False = i
SDTS to translate Boolean
expressions into Three-address code
Therefore SDTS is:
E −› not E1
{ E.True = E1.False;
E.False = E1.True;
}
SDTS to translate Statements into
Three-address code
A simple statement is an expression terminated by
semicolon.Therefore SDTS is:
S −› E ;
{ S.Next= NULL;
}
M −› є { M.quad = Netquad;}
N −› є { N.Next = makelist(Nextquad);
gencode(goto ____);
}
SDTS to translate Control structures
into Three-address code
Example: while E do S1 is represented as follows:
goto ___
SDTS to translate control structures
into Three-address code
Therefore SDTS is:
S −› while M1 E do M2 S1
{ backpatch(E.True, M2.quad);
backpatch(S1.Next, M1.quad);
S.Next = E.False;
gencode(goto M1.quad);
}
M −› є { M.quad = Netquad;}
SDTS to translate Control structures
into Three-address code
Example: for(E1; E2;E3) S1 is represented as follows:
code for E1
code for E3
goto
int a[1..5,2..7];
D −› type id[dlist]
type −› int | float
dlist −› dlist1, const1..const2 | const1..const2
Computation of C
C = (lb1*d2*d3*…..dk+ lb2*d3*d4*…..dk+ …… +lbk)*bpw;
Can be written as:
C =((((((lb1*d2)+lb2)*d3+lb3)*d4+……+lbk)*bpw;
SDTS to translate an array reference
into Three-address code
Therefore the SDTS is:
type −› int {type.val = 2;}
type −› float {type.val = 4;}
dlist −› const1..const2 { dlist.zize = const2.val –const1.val+1;
Initialize Queue by adding dlist.size;
C= const1.val;
}
Dlist −› dlist1, const1..const2
{dlist.size = const2.val –const1.val+1;
append dlist.size to Queue;
C= C*dlist.size+const1.val
}
SDTS to translate an array reference
into Three-address code