a+b=5 a=2 b=3 x=5 y=3 z=2
执行z:=z+x; 后,实参和的形参的变化:
a+b=5 a=2 b=3 x=5 y=3 z=7
过程工作完成返回之前必须把第二个单元的内容存放到第一个单元所指的那个实参单元之中。实参和的形参的变化:
a+b=5 a=7 b=3 x=5 y=3 z=7
因此,程序执行后输出 a的值是 7。
(4) 所谓传名是在进入调用段之前不对实在参数预先进行计值,而是过程中每当使用到相应的形参时才对它实行计值。因此,在实现时通常都把实参处理成型个子程(称为参数子程序),每当过程体中使用到相应形参时就调用这个子程序。
因此,过程体执行y:=y+1;语句,实现时处理成为:
a=a+1;
过程体执行z:=z+x;语句,实现时处理成为:
a=a+(a+b);
6
执行上述两语句后,a的值是 9。因此,程序执行后输出 a的值是 9。 综上所述程序执行时a的输出:
(1)传值: 2 (2)传地址: 8 (3)得结果: 7 (4)传名: 9
5. 已知文法G[S] S→S*aP | aP | *aP P→+aP | +a
(1) 将文法G[S]改写为LL(1)文法G?[S]; (2) 构造文法G?[S]的预测分析表。 解答
构造文法的预测分析表,通常应当按下列步骤进行: (1) 消除文法的左递归
(2) 对消除左递归后的文法,提取左公因子。
(3) 对经过上述改造后的文法,计算它的每个非终结符的FIRST 和FOLLOW集合。(4) 根据FIRST 和FOLLOW集合构造预测分析表。 消除直接左递归方法:假设关于非终结符P的规则为 P→Pα|β
其中,β不以P打头。把P的规则改写为如下非直接左递归形式: P→βP ? P→αP ?|?
文法G[S] 消除直接左递归方法后,文法变为G?[S]: S→aPS? | *aPS? S?→*aPS? | ε P→+aP | +a
提公共左因子的方法:假设关于非终结符A的规则为 A→ δβ1| δβ2|…| δβn|γ1| γ2|…| γm 其中,每个γ不以δ开头。把A的规则改写为如下形式: A→αA?| γ1| γ2|…| γm A?→β1|β2|…|βn
于是,文法 G?(S) 提公共左因子后,文法变为G??[S] S→aPS? | *aPS?
7
S?→*aPS? | ε P→+aP? P?→P | ε
计算每个非终结符的FIRST 和FOLLOW集合: a. 计算非终结符X的FIRST方法:
(1)若有产生式X?a…,则把a加入到FIRST(X)中; (2)若X??也是一条产生式,则把?也加到FIRST(X)中; (3)若X?Y…是一个产生式且Y?VN,则把FIRST(Y)中的所有非?元素都加到FIRST(X)
中;若X?Y1Y2…YK 是一个产生式,Y1,Y2,…,Yi-1都是非终结符,而且,对于任何j, 1≤j≤i-1,FIRST(Yj)都含有?,则把FIRST(Yj)中的所有非?元素都加到FIRST(X)中;特别是,若所有的FIRST(Yj)( j=1,2,…,K)均含有?,则把?加到FRIST(X)中。
根据计算非终结符的FIRST方法的第一点,有 FIRST(S)={a,*} FIRST(S?)={*} FIRST(P)={+} FIRST(P?)={}
根据计算非终结符的FIRST方法的第二点,有 FIRST(S)={a,*} FIRST(S?)={*,ε} FIRST(P)={+} FIRST(P?)={ ε}
根据计算非终结符的FIRST方法的第三点,有 FIRST(S)={a,*} FIRST(S?)={*,ε} FIRST(P)={+} FIRST(P?)={+,ε}
b. 计算非终结符X的FOLLOW方法:
(1)对于文法的开始符号S,置#于FOLLOW(S) 中;
(2).若A→αBβ是一个产生式,则把FIRST(β)\\{?}加至FOLLOW(B)中;
(3)若A→αB是一个产生式,或A→αBβ是一个产生式而β??(即??FIRST(β)),则把FOLLOW(A),加至FOLLOW(B)中。
根据计算非终结符的FOLLOW方法的第一点,有 FOLLOW(S)={#} FOLLOW(S?)={} FOLLOW(P)={} FOLLOW(P?)={}
根据计算非终结符的FOLLOW方法的第二点,有 FOLLOW(S)={#} FOLLOW(S?)={#} FOLLOW(P)={*,#} FOLLOW(P?)={*,#}
8
根据FIRST 和FOLLOW集合构造预测分析表方法: (1)对文法G的每个产生式A→?执行第二步和第三步; (2)对每个终结符a?FIRST(?),把A→?加至?[A,a]中;
(3)若?? FIRST(?),则对任何b?FOLLOW(A),把A→?加至?[A,b]中; (4)把所有无定义的?[A,a]标上“出错标志”。 构造预测分析表方法如下: S S? P P?
6. 设文法G(S): S→(T) | aS | a T→T,S | S ⑴ 消除左递归和提公共左因子; ⑵ 构造相应的FIRST和FOLLOW集合; ⑶ 构造预测分析表。 解答
(1)消除左递归和提公共左因子,文法变为G?[S]
S →(L) | aS?
S?→S |ε L→SL? L?→,SL? |ε 此文法没有公共左因子
(2) 构造相应的FIRST和FOLLOW集合 FIRST(S)={a,(} FIRST(S?)={a,(,ε} FIRST(L)={a, (} FIRST(L?)={,, ε} FOLLOW(S)={,, ), #} FOLLOW(S?)={,, ), #} FOLLOW(L)={ )}
* S→*aPS? S?→*aPS? P?→ε + P→+aP? P?→P a S→aPS? # S?→ε P?→ε 9
FOLLOW(L?)={ )} (3) 构造预测分析表
S S? L L?
7. 设文法G[S]
S ?(A) S ?a A ?A+S A ?S
(1) 构造每个非终结符的FIRSTVT和LASTVT集合; (2) 构造优先关系表; 解答
对于这类题目,关键是准确掌握FIRSTVT和LASTVT集合的定义和构造方法。
FIRSTVT(P)={a|P+?a?或P+?Qa...,a?VT而Q?VN}
即,对于非终结符P,其往下推导所可能出现的首个算符。
LASTVT(P)={a|P+??a或P+?...aQ,a?VT而Q?VN}
即,对于非终结符P,其往下推导所可能出现的最后一个算符。
构造FIRSTVT和LASTVT集合的方法 (1) 构造FIRSTV集合
若有产生式P?a?或P?Qa?,则a?FIRSTVT(P);
若有a?FIRSTVT(Q),且有产生式P?Q?,则a?FIRSTVT(P)。
(2) 构造LASTVT集合
若有产生式P??a或P??aQ,则a?LASTVT(P);
若有a?LASTVT(Q),且有产生式P??Q,则a?LASTVT(P)。
对于文法G[S],构造它的每个非终结符的FIRSTVT和LASTVT集合: FIRSTVT(S)={a, ( } FIRSTVT(A)={+, a, ( } LASTVT(S)={a, )} LASTVT(A)={+, a, )}
构造算符优先关系表方法: (1) ?=?关系
直接看产生式的右部,若出现了 P →…ab…或P →…aQb,则a=b
(2)?
求出每个非终结符P的FIRSTVT(P)
10
( S →(L) S?→S L→SL? ) S?→ε L?→ε a S → aS? S?→S L→SL? , S?→ε L?→,SL? # S?→ε