七, 控制语句也可采用改写文法的方法
S→if B then S 1
│if B then S1 else S2
│while B do S1
可将上述文法改写为,
C→if B then
T→C S 1 else
W→while
R→W B do
S→C S 1 | T S1 | R S1
C→if B then
{ backpatch(B.truelist,ip);
C.nextlist:=B.falselist }
T→C S 1 else
{ q:=ip;
emit(j,-,-,0);
backpatch(C.nextlist,ip);
T.nextlist:=merge(q,S1.nextlist) }
W→while
{ W.code:=ip }
R→W B do
{ backpatch(B.truelist,ip);
R.nextlist:=B.falselist;
R.code:=W.code }
S→C S 1
{ S.nextlist:=merge(C.nxtlisrt,S1.nextlist) }
S→T S 1
{ S.nextlist:=merge(T.nxtlisrt,S1.nextlist) }
S→R S 1
{ backpatch(S1.nextlist,R.code);
emit(j,-,-,R.code);
S.nextlist:=R.nextlist }
八, 数组元素按列存放时的处理
D=a+(in-ln)*dn-1*dn-2*…*d 1
+(in-1-ln-1)*dn-2*dn-3*…*d 1
+…+(i 2-l2)*d1+(i1-l1)
D=CONSPART+VARPART
CONSPART=a-C
C=ln*dn-1*dn-2*…*d 1 +ln-1*dn-2*dn-3*…*d 1
+…+l 2*d1+l1
VARPART =in*dn-1*dn-2*…*d 1 +in-1*dn-2*dn-3*…*d 1 +…+i 2*d1+i1
=(.,,((in*dn-1+in-1)*dn-2+ in-2 )*dn-3 +.,,+i2)*d1+i1
方法,
?VARPART的值不能按下标式的出现顺序
从左到右进行累计,它必须待所有下标
式都处理完毕之后,再从右到左进行计
算。
?设置一个栈 STACK,记录每个下标式结
果值的存放单元。待到所有下标式都处
理完毕之后,再自栈顶而下,按
VARPART的算式,累计它的值。
?为 Elist赋予一个语义属性 STACK
?不用改写文法
A→V:=E
V→i[Elist]│i
Elist→Elist 1,E | E
E→E 1 op E2│-E1│(E1)│V
九, 自上而下语法制导翻译概说
方法,
·每个非终结符对应一个递归过程 ( 函数 )
·有关语义值作为函数值返回
·在产生式的中间可以调用语义子程序
1,控制语句的翻译
S?if B then S1
?if B then S1 else S2
?while B do S1
?A
PROCEDURE S;
BEGIN
CASE lookahead OF
′if′,BEGIN
match(′if′);
(B.truelist,B.falselist):=B;
backpatch(B.truelist,ip);
IF lookahead=′then′
THEN BEGIN match(′then′);
S1.nextlist:=S
END
ELSE ERROR;
IF lookahead=′else′
THEN BEGIN
match(′else′);
q:=ip;
emit(j,?,?,0);
backpatch(B.falselist,ip);
S1.nextlist:=merge(S1.nextlist,q);
S2.nextlist:=S;
q:=merge(S1.nextlist,S2.nextlist);
RETURN(q)
END
ELSE RETURN(merge(S1.nextlist,B.falselist))
END;
′while′,BEGIN
match(′while′);
q:=ip;
(B.truelist,B.falselist):=B;
backpatch(B.truelist,ip);
IF lookahead=′do′
THEN BEGIN match(′do′);
S1.nextlist:=S;
backpatch(S1.nextlist,q);
emit(j,?,?,q);
RETURN(B.falselist)
END
ELSE ERROR;
END;
′i′,BEGIN
A;
RETURN(makelist( ))
END;
OTHERWISE,ERROR
END OF CASE
END OF S;
2,算术表达式的翻译
E?T{+T}
T?F{*F}
F?i?(E)
PROCEDURE F;
IF lookahead=′i′
THEN BEGIN match(′i′);
RETURN(lookup(i.name))
END
ELSE IF lookahead=′(′
THEN BEGIN match(′(′);
PLACE:=E;
IF lookahead=′)′
THEN BEGIN match(′)′);
RETURN(PLACE)
END
ELSE ERROR
END
ELSE ERROR;
PROCEDURE T;
BEGIN
T1.PLACE:=F;
WHILE lookahead=′*′ DO
BEGIN
match(′*′);
T2.PLACE:=F;
T1:=newtemp;
emit(*,T1.PLACE,T2.PLACE,T1);
T1.PLACE:=T1
END;
RETURN(T1.PLACE)
END OF T;
PROCEDURE E;
BEGIN
E1.PLACE:=T;
WHILE lookahead=′+′ DO
BEGIN
match(′+′);
E2.PLACE:=T;
T1:=newtemp;
emit(+,E1.PLACE,E2.PLACE,T1);
E1.PLACE:=T1
END;
RETURN(E1.PLACE)
END OF T;
讲, 第五章部分习题
5-5,5-8( a),5-13