编译原理教程课后习题答案——第四章

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第四章语义分析和中间代码生成

完成下列选择题:

(1) 四元式之间的联系是通过实现的。

a. 指示器

b. 临时变量

c. 符号表

d. 程序变量

(2) 间接三元式表示法的优点为。

a. 采用间接码表,便于优化处理

b. 节省存储空间,不便于表的修改

c. 便于优化处理,节省存储空间

d. 节省存储空间,不便于优化处理

(3) 表达式(┐A∨B)∧(C∨D)的逆波兰表示为。

a. ┐AB∨∧CD∨

b. A┐B∨CD∨∧

c. AB∨┐CD∨∧

d. A┐B∨∧CD∨

(4) 有一语法制导翻译如下所示:

S→bAb {print″1″}

A→(B {print″2″}

A→a {print″3″}

B→Aa) {print″4″}

若输入序列为b(((aa)a)a)b,且采用自下而上的分析方法,则输出序列为。

a. b.

c. d.

【解答】

(1) b (2) a (3) b (4) b

何谓“语法制导翻译”试给出用语法制导翻译生成中间代码的要点,并用一简例予以说明。

【解答】语法制导翻译(SDTS)直观上说就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并且在语法分析的同时执行这些子程序。也即在语法分析过程中,当一个产生式获得匹配(对于自上而下分析)或用于归约(对于自下而上分析)时,此产生式相应的语义子程序进入工作,完成既定的翻译任务。

用语法制导翻译(SDTS)生成中间代码的要点如下:

(1) 按语法成分的实际处理顺序生成,即按语义要求生成中间代码。

(2) 注意地址返填问题。

(3) 不要遗漏必要的处理,如无条件跳转等。

例如下面的程序段:

if (i>0) a=i+e-b*d; else a=0;

在生成中间代码时,条件“i>0”为假的转移地址无法确定,而要等到处理“else”时方可确定,这时就存在一个地址返填问题。此外,按语义要求,当处理完(i>0)后的语句(即“i>0”为真时执行的语句)时,则应转出当前的if语句,也即此时应加入一条无条件跳转指令,并且这个转移地址也需要待处理完else之后的语句后方可获得,就是说同样存在着地址返填问题。对于赋值语句a=i+e-b*d,其处理顺序(也即生成中间代码顺序)是先生成i+e 的代码,再生成b*d的中间代码,最后才产生“-”运算的中间代码,这种顺序不能颠倒。令为文法G[S]生成的二进制数的值,例如对输入串,则=。按照语法制导翻译方法的思想,给出计算的相应的语义规则,G(S)如下:

G[S]: S→|L

L→LB|B

B→0|1

【解答】计算的文法G′[S]及语义动作如下:

产生式语义动作

G′[S]:S′→S {print}

S→L1·L2 {:= + 2L}

S→L { := }

L→L1B {:=*2 +

:= +1}

L→B {:=

:=2}

B→1 {:=1}

B→0 {:=0}

下面的文法生成变量的类型说明:

D→id L

L→,id L|:T

T→integer|real

试构造一个翻译方案,仅使用综合属性,把每个标识符的类型填入符号表中(对所用到的过程,仅说明功能即可,不必具体写出)。

【解答】此题只需要对说明语句进行语义分析而不需要产生代码,但要求把每个标识符的类型填入符号表中。对D、L、T,为其设置综合属性type,而过程enter(name,type)用来把名字name填入到符号表中,并且给出此名字的类型type。翻译方案如下:D→id L

{enter , ;}

L→,id L(1)

{enter , L(1).type);

=L(1).type;}

L→:T

{=;}

T→integer

{=integer;}

T→real

{=real;}

写出翻译过程调用语句的语义子程序。在所生成的四元式序列中,要求在转子指令之前的参数四元式par按反序出现(与实现参数的顺序相反)。此时,在翻译过程调用语句时,是否需要语义变量(队列)queue

【解答】为使过程调用语句的语义子程序产生的参数四元式par按反序方式出现,过程调用语句的文法为

S→call i(arglist)

arglist→E

arglist→arglist(1),E

按照该文法,语法制导翻译程序不需要语义变量队列queue,但需要一个语义变量

栈STACK,用来实现按反序记录每个实在参数的地址。翻译过程调用语句的产生式及语义子

程序如下:

(1) arglist→E { 建立一个栈,它仅包含一项}

(2) arglist→arglist(1),E { 将压入arglist(1). STACK栈,arglist. STACK=arglist(1).STACK}

(3) S→call i (arglist) {while ≠null do

begin

将栈顶项弹出并送入p单元之中;

emit (par,_ ,_ ,p);

end;

emit (call,_ ,_ , entry (i));}

设某语言的while语句的语法形式为

S→ while E do S(1)

其语义解释如图4-1所示。

(1) 写出适合语法制导翻译的产生式;

(2) 写出每个产生式对应的语义动作。

图4-1 习题的语句结构图

【解答】本题的语义解释图已经给出了翻译后的中间代码结构。在语法制导翻译过程中,

当扫描到while时,应记住E的代码地址;当扫描到do时,应对E的“真出口”进行回填,

使之转到S(1)代码的入口处;当扫描到S(1)时,除了应将E的入口地址传给S(1).chain

之外,还要形成一个转向E入口处的无条件转移的四元式,并且将继续传下去。因此,应把

S→while E do S(1) 改写为如下的三个产生式:

W→while

A→W E do

S→A S(1)

每个产生式对应的语义子程序如下:

W→while

{ =nxq;}

A→W E do

{ Backpatch,nxq);

=;

=;}

S→A S(1)

{ Backpatch(S(1).chain,;

相关文档
最新文档