编译原理教程(第二版)胡元义课后答案第四章
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{enter (id.name, L.type);} L→,id L(1) {enter (id.name, L(1).type); L.type=L(1).type;}
第四章 语义分析和中间代码生成 L→:T {L.type=T.type;}
T→integer
{T.type=integer;} T→real
第四章 语义分析和中间代码生成 4.8 按照三种基本控制结构文法将下面的语句翻
译成四元式序列: while (A<C∧B<D) { if (A≥1) C=C+1; else while (A≤D) A=A+2;
}
第四章 语义分析和中间代码生成 【解答】 该语句的四元式序列如下(其中E1 、E2
第四章 语义分析和中间代码生成 4.7 改写布尔表达式的语义子程序,使得i(1) rop
i(2)不按通常方式翻译为下面的相继两个四元式: (jrop, i(1), i(2), 0) (j ,__ ,__ , 0 ) 而是翻译成如下的一个四元式: (jnrop, i(1), i(2), 0) 使得当i(1) rop i(2) 为假时发生转移,而为真时并
d. 节省存储空间,不便于优化处理
第四章 语义分析和中间代码生成 (3) 表达式(┐A∨B)∧(C∨D)的逆波兰表示为 a. ┐AB∨∧CD∨ c. AB∨┐CD∨∧ (4) 有一语法制导翻译如下所示: S→bAb {print″1″} 。
b. A┐B∨CD∨∧ d. A┐B∨∧CD∨
A→(B
A→a B→Aa)
{print″2″}
{print″3″} {print″4″}
若输入序列为b(((aa)a)a)b,且采用自下而上的分析 方法,则输出序列为 。
第四章 语义分析和中间代码生成 a. 32224441 c. 12424243 【解答】 (1) b (2) a (3) b (4) b 4.2 何谓“语法制导翻译”?试给出用语法制导翻译 生成中间代码的要点,并用一简例予以说明。 【解答】 语法制导翻译(SDTS)直观上说就是为每个产 生式配上一个翻译子程序(称语义动作或语义子程序),并且 在语法分析的同时执行这些子程序。也即在语法分析过程中, 当一个产生式获得匹配(对于自上而下分析)或用于归约(对 于自下而上分析)时,此产生式相应的语义子程序进入工作, 完成既定的翻译任务。 b. 34242421 d. 34442212
第四章 语义分析和中间代码生成
第四章 语义分析和中间代码生成
4.1 完成下列选择题: (1) 四元式之间的联系是通过 a. 指示器 b. 临时变量 实现的。
c. 符号表
d. 程Baidu Nhomakorabea变量
。
(2) 间接三元式表示法的优点为 a. 采用间接码表,便于优化处理 b. 节省存储空间,不便于表的修改 c. 便于优化处理,节省存储空间
(3) E→(E(1))
{E.tc=E(1).tc; E.fc=E(1).fc;}
(4) E→┐E(1) {E.fc=nxq;emit(j,__ ,__ ,0);Backpatch(E(1).fc,nx q);}
第四章 语义分析和中间代码生成 (5) EA→E(1) ∧ (6) E→EAE(2) {EA.fc=E(1).fc;}
109 (=[ ],T5 ,T4 ,T6 )
110 ( * ,T3 ,T6 ,T7 ) 111 ( +,prod,T7,prod) 112 ( +, i, 1, i ) 113 (j,_ ,_ ,102 )
{T.type=real;}
4.5 写出翻译过程调用语句的语义子程序。在所 生成的四元式序列中,要求在转子指令之前的参数四 元式par按反序出现(与实现参数的顺序相反)。此时, 在翻译过程调用语句时,是否需要语义变量(队 列)queue?
第四章 语义分析和中间代码生成 【解答】 为使过程调用语句的语义子程序产生 的参数四元式par按反序方式出现,过程调用语句的文 法为 S→call i(arglist) arglist→E
第四章 语义分析和中间代码生成 用语法制导翻译(SDTS)生成中间代码的要点如下: (1) 按语法成分的实际处理顺序生成,即按语义
要求生成中间代码。
(2) 注意地址返填问题。 (3) 不要遗漏必要的处理,如无条件跳转等。 例如下面的程序段: if (i>0) a=i+e-b*d; else a=0;
不发生转移(即顺序执行下一个四元式),从而产生效
率较高的四元式代码。
第四章 语义分析和中间代码生成 【解答】 程序如下: 按要求改造描述布尔表达式的语义子
(1) E→i {E.tc=null;E.fc=nxq;emit(jez,entry(i),__ ,0);} (2) E→i(1) rop i(2) {E.tc=null;E.fc=nxq;emit(jnrop,entry(i(1)),entry (i(2));) /* nrop表示关系运算符与rop相反*/
第四章 语义分析和中间代码生成 在生成中间代码时,条件“i>0”为假的转移地址 无法确定,而要等到处理“else”时方可确定,这时就
存在一个地址返填问题。此外,按语义要求,当处理
完(i>0)后的语句(即“i>0”为真时执行的语句)时,则 应转出当前的if语句,也即此时应加入一条无条件跳
转指令,并且这个转移地址也需要待处理完else之后
L.length:=L1.length +1}
第四章 语义分析和中间代码生成 4.4 下面的文法生成变量的类型说明: D→id L
L→,id L|:T
T→integer|real 试构造一个翻译方案,仅使用综合属性,把每个 标识符的类型填入符号表中(对所用到的过程,仅说明 功能即可,不必具体写出)。
B→0|1
【解答】 计算S.val的文法G′[S]及语义动作如下: 产生式 S→L1·2 L L2.val/2L2.length} 语义动作 {S.val:=L1.val +
G′[S]:S′→S {print(S.val)}
第四章 语义分析和中间代码生成 S→L L→L1B L→B { S.val:=L.val } {L.val:=L1.val*2 + B.val {L.val:=B.val L.length:=2} B→1 B→0 {B.val:=1} {B.val:=0}
emit (call,_ ,_ , entry (i));}
第四章 语义分析和中间代码生成 4.6 设某语言的while语句的语法形式为 S→ while E do S(1)
其语义解释如图4-1所示。
(1) 写出适合语法制导翻译的产生式; (2) 写出每个产生式对应的语义动作。
第四章 语义分析和中间代码生成
和E3 分别对应A<C∧B<D、A≥1和A≤D,并且关系运 算符优先级高): 100 (j<,A,C,102) 101 (j,_,_,113) /*E1为F*/
102 (j<,B,D,104)
103 (j,_,_,113) 104 (j=,A,1,106)
/*E1为T*/
/*E1为F*/ /*E2为T*/
prod=prod+a[i]*b[i];
i=i+1; } 试按语法制导翻译法将上述源程序翻译成四元式 序列(设A是数组a的起始地址,B是数组b的起始地址; 机器按字节编址,每个数组元素占四个字节)。
第四章 语义分析和中间代码生成 【解答】 源程序翻译为下列四元式序列: 100 (= ,0 ,_ ,prod)
101 (= ,1 ,_ , i )
102 (j≤,i ,20,104 ) 103 ( j ,_ ,_ ,114 ) 104 ( * ,4 ,i ,T1 ) 105 ( - ,A ,4 ,T2 )
106 (=[ ],T2 ,T1 ,T3 )
第四章 语义分析和中间代码生成 107 ( * ,4 ,i ,T4 ) 108 ( - ,B ,4 ,T5 )
的语句后方可获得,就是说同样存在着地址返填问题。 对于赋值语句a=i+e-b*d,其处理顺序(也即生成中间
代码顺序)是先生成i+e的代码,再生成b*d的中间代码,
最后才产生“-”运算的中间代码,这种顺序不能颠倒。
第四章 语义分析和中间代码生成 4.3 令S.val为文法G[S]生成的二进制数的值,例如 对输入串101.101,则S.val=5.625。按照语法制导翻译方 法的思想,给出计算S.val的相应的语义规则,G(S)如下: G[S]: S→L.L|L L→LB|B
E的代码 真 S( 1 )的 代 码 假
图4-1 习题4.6的语句结构图
第四章 语义分析和中间代码生成 【解答】 本题的语义解释图已经给出了翻译后 的中间代码结构。在语法制导翻译过程中,当扫描到 while时,应记住E的代码地址;当扫描到do时,应对E 的“真出口”进行回填,使之转到S(1)代码的入口处; 当扫描到S(1)时,除了应将E的入口地址传给S(1).chain 之外,还要形成一个转向E入口处的无条件转移的四元 式,并且将E.fc继续传下去。因此,应把S→while E do S(1) 改写为如下的三个产生式: W→while A→W E do S→A S(1)
{E.tc=E(2).tc;E.fc=merg(EA.fc,E(2).fc);}
(7) E0→E(1)∨ {E0.tc=nxq;emit(j,__ ,__ ,0);Backpatch(E(1).fc,n xq);} (8) E→E0E(2) {E.fc=E(2).fc;Backpatch(E0.tc,nxq);}
arglist→arglist(1),E
按照该文法,语法制导翻译程序不需要语义变量 队列queue,但需要一个语义变量栈STACK,用来实现 按反序记录每个实在参数的地址。翻译过程调用语句 的产生式及语义子程序如下:
第四章 语义分析和中间代码生成 (1) arglist→E { 建立一个 arglist.STACK栈,它仅包含一项E.place} (2) arglist→arglist(1) ,E 入 arglist(1). STACK 栈 STACK=arglist(1).STACK} (3) S→call i (arglist) arglist.STACK≠null do begin 将arglist.STACK栈顶项弹出并送入p单元之中; emit (par,_ ,_ ,p); end; { 将E.place压 , arglist. {while
第四章 语义分析和中间代码生成 每个产生式对应的语义子程序如下: W→while { W.quad=nxq;} A→W E do { Backpatch(E.tc,nxq);
A.chain=E.fc;
A.quad=W.quad;} S→A S(1) { Backpatch(S(1).chain,A.quad); emit(j,_,_,A.quad); S.chain=A.chain;}
/*跳过else后的语句*/
/*E3为T*/ /*E3为F*/ /*A:=A+2*/ /*转回内层while语句开始处*/
112 (j,_,_,100)
113
/*转回外层while语句开始处*/
第四章 语义分析和中间代码生成 4.9 已知源程序如下: prod=0; i=1; while (i≤20) {
第四章 语义分析和中间代码生成 105 (j,_,_,108) 106 (+, C, 1, C) /*E2为F*/ /*C:=C+1*/
107 (j,_,_,112)
108 (j≤,A,D,110) 109 (j,_,_,112) 110 (+, A, 2, A) 111 (j,_,_,108)
第四章 语义分析和中间代码生成 【解答】 此题只需要对说明语句进行语义分析
而不需要产生代码,但要求把每个标识符的类型填入
符号表中。对D、L、T,为其设置综合属性type,而过
程enter(name,type)用来把名字name填入到符号表中, 并且给出此名字的类型type。翻译方案如下:
D→id L
第四章 语义分析和中间代码生成 L→:T {L.type=T.type;}
T→integer
{T.type=integer;} T→real
第四章 语义分析和中间代码生成 4.8 按照三种基本控制结构文法将下面的语句翻
译成四元式序列: while (A<C∧B<D) { if (A≥1) C=C+1; else while (A≤D) A=A+2;
}
第四章 语义分析和中间代码生成 【解答】 该语句的四元式序列如下(其中E1 、E2
第四章 语义分析和中间代码生成 4.7 改写布尔表达式的语义子程序,使得i(1) rop
i(2)不按通常方式翻译为下面的相继两个四元式: (jrop, i(1), i(2), 0) (j ,__ ,__ , 0 ) 而是翻译成如下的一个四元式: (jnrop, i(1), i(2), 0) 使得当i(1) rop i(2) 为假时发生转移,而为真时并
d. 节省存储空间,不便于优化处理
第四章 语义分析和中间代码生成 (3) 表达式(┐A∨B)∧(C∨D)的逆波兰表示为 a. ┐AB∨∧CD∨ c. AB∨┐CD∨∧ (4) 有一语法制导翻译如下所示: S→bAb {print″1″} 。
b. A┐B∨CD∨∧ d. A┐B∨∧CD∨
A→(B
A→a B→Aa)
{print″2″}
{print″3″} {print″4″}
若输入序列为b(((aa)a)a)b,且采用自下而上的分析 方法,则输出序列为 。
第四章 语义分析和中间代码生成 a. 32224441 c. 12424243 【解答】 (1) b (2) a (3) b (4) b 4.2 何谓“语法制导翻译”?试给出用语法制导翻译 生成中间代码的要点,并用一简例予以说明。 【解答】 语法制导翻译(SDTS)直观上说就是为每个产 生式配上一个翻译子程序(称语义动作或语义子程序),并且 在语法分析的同时执行这些子程序。也即在语法分析过程中, 当一个产生式获得匹配(对于自上而下分析)或用于归约(对 于自下而上分析)时,此产生式相应的语义子程序进入工作, 完成既定的翻译任务。 b. 34242421 d. 34442212
第四章 语义分析和中间代码生成
第四章 语义分析和中间代码生成
4.1 完成下列选择题: (1) 四元式之间的联系是通过 a. 指示器 b. 临时变量 实现的。
c. 符号表
d. 程Baidu Nhomakorabea变量
。
(2) 间接三元式表示法的优点为 a. 采用间接码表,便于优化处理 b. 节省存储空间,不便于表的修改 c. 便于优化处理,节省存储空间
(3) E→(E(1))
{E.tc=E(1).tc; E.fc=E(1).fc;}
(4) E→┐E(1) {E.fc=nxq;emit(j,__ ,__ ,0);Backpatch(E(1).fc,nx q);}
第四章 语义分析和中间代码生成 (5) EA→E(1) ∧ (6) E→EAE(2) {EA.fc=E(1).fc;}
109 (=[ ],T5 ,T4 ,T6 )
110 ( * ,T3 ,T6 ,T7 ) 111 ( +,prod,T7,prod) 112 ( +, i, 1, i ) 113 (j,_ ,_ ,102 )
{T.type=real;}
4.5 写出翻译过程调用语句的语义子程序。在所 生成的四元式序列中,要求在转子指令之前的参数四 元式par按反序出现(与实现参数的顺序相反)。此时, 在翻译过程调用语句时,是否需要语义变量(队 列)queue?
第四章 语义分析和中间代码生成 【解答】 为使过程调用语句的语义子程序产生 的参数四元式par按反序方式出现,过程调用语句的文 法为 S→call i(arglist) arglist→E
第四章 语义分析和中间代码生成 用语法制导翻译(SDTS)生成中间代码的要点如下: (1) 按语法成分的实际处理顺序生成,即按语义
要求生成中间代码。
(2) 注意地址返填问题。 (3) 不要遗漏必要的处理,如无条件跳转等。 例如下面的程序段: if (i>0) a=i+e-b*d; else a=0;
不发生转移(即顺序执行下一个四元式),从而产生效
率较高的四元式代码。
第四章 语义分析和中间代码生成 【解答】 程序如下: 按要求改造描述布尔表达式的语义子
(1) E→i {E.tc=null;E.fc=nxq;emit(jez,entry(i),__ ,0);} (2) E→i(1) rop i(2) {E.tc=null;E.fc=nxq;emit(jnrop,entry(i(1)),entry (i(2));) /* nrop表示关系运算符与rop相反*/
第四章 语义分析和中间代码生成 在生成中间代码时,条件“i>0”为假的转移地址 无法确定,而要等到处理“else”时方可确定,这时就
存在一个地址返填问题。此外,按语义要求,当处理
完(i>0)后的语句(即“i>0”为真时执行的语句)时,则 应转出当前的if语句,也即此时应加入一条无条件跳
转指令,并且这个转移地址也需要待处理完else之后
L.length:=L1.length +1}
第四章 语义分析和中间代码生成 4.4 下面的文法生成变量的类型说明: D→id L
L→,id L|:T
T→integer|real 试构造一个翻译方案,仅使用综合属性,把每个 标识符的类型填入符号表中(对所用到的过程,仅说明 功能即可,不必具体写出)。
B→0|1
【解答】 计算S.val的文法G′[S]及语义动作如下: 产生式 S→L1·2 L L2.val/2L2.length} 语义动作 {S.val:=L1.val +
G′[S]:S′→S {print(S.val)}
第四章 语义分析和中间代码生成 S→L L→L1B L→B { S.val:=L.val } {L.val:=L1.val*2 + B.val {L.val:=B.val L.length:=2} B→1 B→0 {B.val:=1} {B.val:=0}
emit (call,_ ,_ , entry (i));}
第四章 语义分析和中间代码生成 4.6 设某语言的while语句的语法形式为 S→ while E do S(1)
其语义解释如图4-1所示。
(1) 写出适合语法制导翻译的产生式; (2) 写出每个产生式对应的语义动作。
第四章 语义分析和中间代码生成
和E3 分别对应A<C∧B<D、A≥1和A≤D,并且关系运 算符优先级高): 100 (j<,A,C,102) 101 (j,_,_,113) /*E1为F*/
102 (j<,B,D,104)
103 (j,_,_,113) 104 (j=,A,1,106)
/*E1为T*/
/*E1为F*/ /*E2为T*/
prod=prod+a[i]*b[i];
i=i+1; } 试按语法制导翻译法将上述源程序翻译成四元式 序列(设A是数组a的起始地址,B是数组b的起始地址; 机器按字节编址,每个数组元素占四个字节)。
第四章 语义分析和中间代码生成 【解答】 源程序翻译为下列四元式序列: 100 (= ,0 ,_ ,prod)
101 (= ,1 ,_ , i )
102 (j≤,i ,20,104 ) 103 ( j ,_ ,_ ,114 ) 104 ( * ,4 ,i ,T1 ) 105 ( - ,A ,4 ,T2 )
106 (=[ ],T2 ,T1 ,T3 )
第四章 语义分析和中间代码生成 107 ( * ,4 ,i ,T4 ) 108 ( - ,B ,4 ,T5 )
的语句后方可获得,就是说同样存在着地址返填问题。 对于赋值语句a=i+e-b*d,其处理顺序(也即生成中间
代码顺序)是先生成i+e的代码,再生成b*d的中间代码,
最后才产生“-”运算的中间代码,这种顺序不能颠倒。
第四章 语义分析和中间代码生成 4.3 令S.val为文法G[S]生成的二进制数的值,例如 对输入串101.101,则S.val=5.625。按照语法制导翻译方 法的思想,给出计算S.val的相应的语义规则,G(S)如下: G[S]: S→L.L|L L→LB|B
E的代码 真 S( 1 )的 代 码 假
图4-1 习题4.6的语句结构图
第四章 语义分析和中间代码生成 【解答】 本题的语义解释图已经给出了翻译后 的中间代码结构。在语法制导翻译过程中,当扫描到 while时,应记住E的代码地址;当扫描到do时,应对E 的“真出口”进行回填,使之转到S(1)代码的入口处; 当扫描到S(1)时,除了应将E的入口地址传给S(1).chain 之外,还要形成一个转向E入口处的无条件转移的四元 式,并且将E.fc继续传下去。因此,应把S→while E do S(1) 改写为如下的三个产生式: W→while A→W E do S→A S(1)
{E.tc=E(2).tc;E.fc=merg(EA.fc,E(2).fc);}
(7) E0→E(1)∨ {E0.tc=nxq;emit(j,__ ,__ ,0);Backpatch(E(1).fc,n xq);} (8) E→E0E(2) {E.fc=E(2).fc;Backpatch(E0.tc,nxq);}
arglist→arglist(1),E
按照该文法,语法制导翻译程序不需要语义变量 队列queue,但需要一个语义变量栈STACK,用来实现 按反序记录每个实在参数的地址。翻译过程调用语句 的产生式及语义子程序如下:
第四章 语义分析和中间代码生成 (1) arglist→E { 建立一个 arglist.STACK栈,它仅包含一项E.place} (2) arglist→arglist(1) ,E 入 arglist(1). STACK 栈 STACK=arglist(1).STACK} (3) S→call i (arglist) arglist.STACK≠null do begin 将arglist.STACK栈顶项弹出并送入p单元之中; emit (par,_ ,_ ,p); end; { 将E.place压 , arglist. {while
第四章 语义分析和中间代码生成 每个产生式对应的语义子程序如下: W→while { W.quad=nxq;} A→W E do { Backpatch(E.tc,nxq);
A.chain=E.fc;
A.quad=W.quad;} S→A S(1) { Backpatch(S(1).chain,A.quad); emit(j,_,_,A.quad); S.chain=A.chain;}
/*跳过else后的语句*/
/*E3为T*/ /*E3为F*/ /*A:=A+2*/ /*转回内层while语句开始处*/
112 (j,_,_,100)
113
/*转回外层while语句开始处*/
第四章 语义分析和中间代码生成 4.9 已知源程序如下: prod=0; i=1; while (i≤20) {
第四章 语义分析和中间代码生成 105 (j,_,_,108) 106 (+, C, 1, C) /*E2为F*/ /*C:=C+1*/
107 (j,_,_,112)
108 (j≤,A,D,110) 109 (j,_,_,112) 110 (+, A, 2, A) 111 (j,_,_,108)
第四章 语义分析和中间代码生成 【解答】 此题只需要对说明语句进行语义分析
而不需要产生代码,但要求把每个标识符的类型填入
符号表中。对D、L、T,为其设置综合属性type,而过
程enter(name,type)用来把名字name填入到符号表中, 并且给出此名字的类型type。翻译方案如下:
D→id L