编译原理课后习题答案.docx
《编译原理课后习题答案.docx》由会员分享,可在线阅读,更多相关《编译原理课后习题答案.docx(30页珍藏版)》请在冰豆网上搜索。
编译原理课后习题答案
第一章
1.典型的编译程序在逻辑功能上由哪几部分组成?
答:
编译程序主要由以下几个部分组成:
词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。
2.实现编译程序的主要方法有哪些?
答:
主要有:
转换法、移植法、自展法、自动生成法。
3.将用户使用高级语言编写的程序翻译为可直接执行的机器语言程序有哪几种主要的方式?
答:
编译法、解释法。
4.编译方式和解释方式的根本区别是什么?
答:
编译方式:
是将源程序经编译得到可执行文件后,就可脱离源程序和编译程序单独执行,所以编译方式的效率高,执行速度快;
解释方式:
在执行时,必须源程序和解释程序同时参与才能运行,其不产生可执行程序文件,效率低,执行速度慢。
第二章
1.乔姆斯基文法体系中将文法分为哪几类?
文法的分类同程序设计语言的设计与实现关系如何?
答:
1)0型文法、1型文法、2型文法、3型文法。
2)
2.写一个文法,使其语言是偶整数的集合,每个偶整数不以0为前导。
答:
ZSME|B
S1|2|3|4|5|6|7|8|9
M|D|MD
D0|S
B2|4|6|8
E0|B
3.设文法G为:
ND|ND
D0|1|2|3|4|5|6|7|8|9
请给出句子123、301和75431的最右推导和最左推导。
答:
NNDN3ND3N23D23123
NNDNDDDDD1DD12D123
NNDN1ND1N01D01301
NNDNDDDDD3DD30D301
NNDN1ND1N31ND31N431ND431N5431D543175431
NNDNDDNDDDNDDDDDDDDD7DDDD75DDD754DD7543D75431
4.证明文法SiSeS|iS|i是二义性文法。
答:
对于句型iiSeS存在两个不同的最左推导:
SiSeSiiSes
SiSiiSeS
所以该文法是二义性文法。
5.给出描述下面语言的上下文无关文法。
(1)L1={anbnci|n>=1,i>=0}
(2)L2={aibj|j>=i>=1}
(3)L3={anbmcmdn|m,n>=0}
答:
(1)SAB
AaAb|ab
BcB|
(2)SASb|ab
Aa|
(3)SaSd|A|
AbAc|
6.设计一个最简的DFAM,使其能够识别所有的被3整除的无符号十进制整数。
答:
7.设计一个DFA,使其能够接受被4整除的二进制数。
答:
8.写出表达下列各项的正则表达式。
(1)二进制数且为5的倍数。
(2)Σ={a,b,c},第一个a位于第一个b之前的字符串。
(3)Σ={a,b,c},包含偶数个a的字符串。
(4)Σ={0,1},不包含11子串的字符串。
答:
(1)
可以先画出相应的有限自动机:
添加新的开始状态S和终止状态T:
根据以上自动机,列出以下方程:
①S=A
②A=0A+1B+T
③B=0C+1D
④C=0E+1A
⑤D=0B+1C
⑥E=0D+1E
解以上方程组:
⑥E=1*0D
②A=0*1B+0*T
⑥代入④C=01*0D+1A
⑤代入④C=01*00B+01*01C+1A
C=xB+yA
其中x=(01*01)*01*00y=(01*01)*1
⑤代入③B=0C+10B+11C
B=(0|11)C+10B
B=(10)*(0|11)C
将C=xB+yA代入上式B=uB+vA
B=u*vA
其中u=(10)*(0|11)xv=(10)*(0|11)y
将B=u*vA代入②A=0*1u*vA+0*T
A=(0*1u*v)*0*T
将A代入①S=(0*1u*v)*0*T
串(0*1u*v)*0*即为所求。
(2)该题目理解为:
至少有一个a和一个b,且a出现在b的前面(可以有间隔),则答案为:
c*a(a|c)*b(a|b|c)*
(3)((b|c)*a(b|c)*a)*(b|c)*(a(b|c)*a|b|c)*
(4)(0|10)*(1|)
第三章
1.词法分析器的功能是什么?
答:
读源程序的字符序列,逐个拼出单词,并构造相应的内部表示TOKEN;同时检查源程序中的词法错误。
2.试分析分隔符(空格、跳格及回车等)对词法分析的影响。
答:
空格、跳格、回车等分隔符号对词法分析不起作用,可以删除。
但是回车符号可以用于错误定位,所以在删除回车符号前需要统计回车的个数。
3.给出识别C语言全部实型常数的自动机。
答:
(+|-|)([1-9][0-9]*|0)(.[0-9][0-9]*|)(E(+|-|)[0-9][0-9]*)
4.写出识别C语言中所有单词的LEX程序。
答:
L=[A-Z]|[a-z]
D=[0-9]
D1=[1-9]
%%
(L|_)(L|D|_)*{return
(1);}
D1D*{return
(2);}
+{return(3);}
……
第四章
1.设有如下文法G[S]:
SaABbcd|
AASd|
BSAh|eC|
CSf|Cg|
(1)求每个产生式的Predict集。
(2)该文法是否为LL
(1)文法?
为什么?
答:
(1)
Predict(SaABbcd)={a}
Predict(S)={#,d,f,a,h}
Predict(AASd)={a,d}
Predict(A)={h,a,d,b,e}
Predict(BSAh)={a,d,h}
Predict(BeC)={e}
Predict(B)={b}
Predict(CSf)={a,f}
Predict(CCg)={a,f,g}
Predict(C)={g,b}
(2)由于Predict(AASd)Predict(A),所以该文法不是LL
(1)文法。
2.下列描述括号匹配的文法中,哪些是LL
(1)文法?
(1)S(SS’|
S’)|
(2)S(S)S|
(3)SS(S)S|
(4)S(S|S’
S’(S’)|
答:
(1)不是,
(2)是,(3)不是,(4)不是
3.已知文法G[E]:
EE+T|T
TT*F|F
Fi|(E)
请按递归下降法构造该文法的语法分析程序。
答:
求产生式的predict集合:
predict(EE+T)={i,(}
predict(ET)={i,(}
predict(TT*F)={i,(}
predict(TF)={i,(}
由于文法中非终极符号E和T对应的产生式的predict集合的交集都不为空,所以该文法不满足自顶向下分析的条件,现对文法进行等价变换得到如下文法:
ETE’
E’+TE’|
TFT’
T’*FT’|
Fi
F(E)
求新文法的predict集合:
Predict(ETE’)={(,i}
Predict(E’+TE’)={+}
Predict(E’)={#,)}
Predict(TFT’)={i,(}
Predict(T’*FT’)={*}
Predict(T’)={+,),#}
Predict(Fi)={i}
Predict(F(E))={(}
由于以上文法中任意非终极符号对应的产生式的predict集合的交集都为空,所以满足自顶向下分析的条件,所以可以写出如下的递归下降语法分析伪代码:
VoidE()
{if(token{(,i}){T();E’();}
elseError();}
voidE’()
{if(token{+}){Match(‘+’);T();E’();}
elseif(token{#,)}){;}
elseError();}
voidT()
{if(token{i,(}){F();T’();}
elseError();}
voidT’()
{if(token{*}){Match(‘*’);F();T’();}
elseif(token{+,),#}){;}
elseError();}
voidF()
{if(token{i}){Match(‘i’);}
elseif(token{(}){Match(‘(‘);E();Match(‘)’);}
elseError();}
4.构造一个LL
(1)文法G,它能识别语言L:
L={|为字母表上不包括两个相邻的1的非空串},其中={0,1}。
并证明你所构造的文法是LL
(1)文法。
答:
A0E|1F
B0E|1F
C0E
EB|
FC|
Predict(A0E)={0}
Predict(A1F)={1}
Predict(B0E)={0}
Predict(B1F)={1}
Predict(EB)={0,1}
Predict(E)={#}
Predict(FC)={0}
Predict(F)={#}
对任意非终极符号对应的产生式的predict集合的交集都为空,所以该文法是LL
(1)文法。
5.已知文法G[A]为:
AaABe|a
BBb|d
(1)试给出与G[A]等价的LL
(1)文法G’[A]。
(2)构造G’[A]的LL
(1)分析表并给出输入串aade#的分析过程。
答:
(1)所求G’[A]为:
AaA’
(1)
A’ABe
(2)
A’(3)
BdB’(4)
B’bB’(5)
B’(6)
Predict(AaA’)={a}
Predict(A’ABe)={a}
Predict(A’)={#,d}
Predict(BdB’)={d}
Predict(B’bB’)={b}
Predict(B’)={e}
对任意非终极符号对应的产生式的predict集合的交集都为空,所以该文法是LL
(1)文法。
(3)分析表如下:
a
b
d
e
#
A
(1)
A’
(2)
(3)
(3)
B
(4)
B’
(5)
(6)
aade#的分析过程如下
分析栈
输入流
动作
A#
aade#
替换
(1)
aA’#
aade#
匹配
A’#
ade#
替换
(2)
ABe#
ade#
替换
(1)
aA’Be#
ade#
匹配
A’Be#
de#
替换(3)
Be#
de#
替换(4)
dB’e#
de#
匹配
B’e#
e#
替换
e#
e#
匹配
#
#
成功
第五章(这章答案是错的)
1.设有下列文法:
(1)SaA
AAb
Ab
(2)SaSSb
SaSSS
Sc
(3)SAS
Sb
ASA
Aa
(4)ScA
SccB
BccB
Bb
AcA
Aa
构造上述文法的LR(0)归约活前缀状态机,并给出LR(0)分析表。
答:
(1)
(2)
(3)
(4)
2.设有下列文法:
(1)SSaS|b
(2)SbSb|cSc|b|c
(3)SbSb|bSc|d
(4)SaSb|bSa|ab
(5)SSab|bR
RS|a
(6)SSAB|BA
Bb
AaA|B
(7)SAaAb|BbBa
B
A
(8)AaABe|Ba
BdB|
说明上述文法是否为SLR
(1)文法。
若是,请构造SLR
(1)分析表;若不是,请说明理由。
答:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
3.设有下列文法:
SaAd|bBd|aBe|bAe
Ag
Bg
说明该文法是LR
(1)文法,但不是LALR
(1)文法。
答:
4.设有下列文法:
(1)EE+T|T
TTF|T
F(E)|F*|a|b
(2)SAa|bAc|dc|bda
Ad
说明上述文法是否为SLR
(1)文法?
是否为LALR
(1)文法?
并构造相应的分析表。
答:
(1)
(2)
5.设有下列文法:
LMLb|a
M
说明上述文法是否为LR
(1)文法,若不是,请说明理由。
答:
第六章
1.试写出下列类型的内部表示:
a.integer
b.ARRAY[1..5]ofRECORDi:
integer;b:
booleanEND
c.ARRAY[1..5]ofRECORDa:
ARRAY[1..10];r:
RECORDi,j:
integerENDEND
d.RECORDr:
RECORDx,y:
realEND;a:
ARRAY[1..10]ofintegerEND
2.设当前层数为l,可用区距为101,且有下列程序段:
CONSTmm=333;nn=444;
TYPEatype=ARRAY[1..10]OFreal;
rtype=RECORDi,j:
integerEND;
VARa,b:
atype;
x,y:
real
试写出各标识符的内部表示。
3.设当前层数和区距分别为l和off,且有函数说明首部:
FUNCTIONf(A:
atype;VARB:
atype;VARX:
real):
integer
其中atype的定义见题5,试写出f的内部表示。
4.要求在下面括号中写上相应ℓ(层数)和区距(off)。
()()PROCEDUREg(A:
atype;()()
VARB:
atype;()()
VARX:
real()())()().
5.给出下面C程序扫描到语句c=a+b+x时相应的全局符号表(采用顺序表结构)。
main()
{
inta=0;
floatc=1.0;
{
floata=3.0;
{
floatx=1.3;
floatb=0.3;
}
{
intb=10;
c=a+b+x;
}
}
}
6.给出题1中程序扫描到语句c=a+b+x时相应的全局符号表(采用外拉链的散列表结构)。
7.根据标识符的作用域规则,分别给出图6.5的程序中,过程P、Q、R、S中有效的标识符。
第七章
1.将算术表达式(a+b)*(c+d)-(a+b+c)翻译成四元式序列。
2.将下列语句翻译成四元式序列:
a.IFx>0THENx:
=0ELSEx:
=1
b.WHILEx>0DOx:
=x-1
c.IFx>0THENx:
=x+1ELSE
IFx<0THENx:
=x+1ELSEx:
=x+1
d.WHILEx>0DO
WHILEy>0DO
BEGINy:
=y-x;x:
=x-1END
3.给出如下程序段的四元式序列。
(四元式的操作符可用自身代替)。
其中A:
Arrayof[1..10]ofinteger。
a:
=1;
whilea<=10do
beginifa<>bthen
A[a]:
=A[b]+2;
elsea:
=a+1;
b:
=b+1;
end
4.试将FOR语句翻译成四元式序列。
5.试将UNTIL语句翻译成四元式序列。
6.试将CASE语句翻译成四元式序列。
7.试给出4、5、6题中翻译过程的语法制导程序。
第八章
1.将下面的程序段划分为基本块并画出其程序流图。
read(A);
read(B);
F:
=1;
C:
=A*A;
D:
=B*B;
ifCE:
=A*A;
F:
=F+1;
E:
=E+F;
write(E);
gotoL3;
L1:
E:
=B*B;
F:
=F+2;
write(E);
ifE>100gotoL2;
gotoL3;
L2:
F:
=F-1;
gotoL1;
L3:
write(E);
2.假设有如下语句序列,写出常表达式优化前和优化后的四元式中间代码。
(1)i:
=1;
(2)a:
=20;
j:
=i*(i+1);b:
=a*(a+10);
k:
=2*(i+j);c:
=a*b;
3.假设有如下语句序列或表达式,写出公共表达式优化前和优化后的四元式中间代码。
(1)x:
=x*y+z;y:
=x*y+z;z:
=x*y+z;
(2)(a*b+c)/(a*b-c)+(c*b+a-d)/(a*b+c)
4.写出如下循环语句不变式外提后的四元式中间代码。
whilei<=100do
beginu:
=A*B;
m:
=u*u;
S:
=S+m*m;
i:
=i+1;
end
5.写出下面循环语句不变式外提后的四元式中间代码,其中数组各下标的类型为1..10。
whilei<=100do
beginj:
=1;
whilej<=100do
begink:
=1;
whilek<=100do
A[i][j][k]:
=0;
end
end
第九章
1.过程活动记录包含哪些信息?
各信息的作用?
何时填写它们?
2.下面是一个调用递归函数的Pascal程序
programPP(input,output)
VARk:
integer;
FUNCTIONF(n:
integer):
integer
begin
ifn<=0thenF:
=1
elseF:
=n*F(n-1);
end;
begin
k:
=F(10);
…
end.
当第二次(递归地)进入F后,DISPLAY的内容是什么?
当时整个运行栈的内容是什么?
3.对于下面的程序:
procedureP(X,Y,Z);
begin
Y:
=Y+1;
Z:
=Z+X;
endP;
begin
A:
=2;
B:
=3;
P(A+B,A,A);
printA
end
当参数传递的办法分别为
(1)传值;
(2)传地址;(3)值-结果;(4)传名时,程序执行时输出的A分别是什么?
4.应用Pascal语言的作用域规则,说明下面程序中的名字a和b的每一次出现所应用的声明。
programa(input,output);
procedureb(u,v,x,y:
integer);
vara:
recorda,b:
integerend;
b:
reocrdb,a:
integerend;
begin
withadobegina:
=u;b:
=vend;
withbdobegina:
=x;b:
=yend;
writeln(a.a,a.b,b.a,b.b)
end;
begin
b(1,2,3,4)
end.
5.为下面的C程序构造一个可能的运行时环境。
inta[10];
char*a=”hello”;
intf(inti,intb[])
{intj=1;
A:
{inti=j;
charc=b[I];
…}
}
voidg(char*s)
{charc[10];
B:
{inta[5];
...}
}
main()
{intx=1;
x=f(x,a);
g(s);
return0;}
(1)在进入函数f中的块A之后。
(2)在进入函数g中的块B之后。
6.Display表和静态链的作用是什么?
试举一个程序例子,并考察其Display表和静态链的内容。
7.过程参数的传递方式有几种?
简述"传地址"和"传值"的实现原理。
第十章
1.什么叫指令的执行代价?
2.寄存器分配的原则是什么?
3.在剥夺寄存器的时候,应考虑哪些因素?
什么时候一个变量可以主动释放它所占用的寄存器?
4.试写出程序段
IFx>0THENy:
=y+1ELSE
IFx<0THENy:
=y-1
的目标代码,其中的变量均为非形参实型变量。
5.试写出程序段
WHILExBEGINy:
=y+1;
IFy>0THENy:
=y-xELSE
WHILEy<0DOy:
=y+x
END
的目标代码,其中变量均为非形参实型变量。
6.试为FOR循环语句设计目标代码。
7.试为REPEAT循环语句设计目标代码。
8.试为CASE语句设计目标代码。