点此下载
第一章
1.典型的编译程序在逻辑功能上由哪几部分组成?
答:编译程序主要由以下几个部分组成:词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。
2. 实现编译程序的主要方法有哪些?
答:主要有:转换法、移植法、自展法、自动生成法。
3. 将用户使用高级语言编写的程序翻译为可直接执行的机器语言程序有哪几种主要的方式?
答:编译法、解释法。
4. 编译方式和解释方式的根本区别是什么?
答:编译方式:是将源程序经编译得到可执行文件后,就可脱离源程序和编译程序单独执行,所以编译方式的效率高,执行速度快;
解释方式:在执行时,必须源程序和解释程序同时参与才能运行,其不产生可执行程序文件,效率低,执行速度慢。
第二章
答:1)0型文法、1型文法、2型文法、3型文法。
2)
2. 写一个文法,使其语言是偶整数的集合,每个偶整数不以0为前导。
答:
ZàSME | B
Sà1|2|3|4|5|6|7|8|9
Màe | D | MD
Dà0|S
Bà2|4|6|8
Eà0|B
3. 设文法G为:
Nà D|ND
Dà 0|1|2|3|4|5|6|7|8|9
请给出句子123、301和75431的最右推导和最左推导。
答:NÞNDÞN3ÞND3ÞN23ÞD23Þ123
NÞNDÞNDDÞDDDÞ1DDÞ12DÞ123
NÞNDÞN1ÞND1ÞN01ÞD01Þ301
NÞNDÞNDDÞDDDÞ3DDÞ30DÞ301
NÞNDÞN1ÞND1ÞN31ÞND31ÞN431ÞND431ÞN5431ÞD5431Þ75431
NÞNDÞNDDÞNDDDÞNDDDDÞDDDDDÞ7DDDDÞ75DDDÞ754DDÞ7543DÞ75431
4. 证明文法 SàiSeS|iS| i是二义性文法。
答:对于句型iiSeS存在两个不同的最左推导:
SÞiSeSÞiiSes
SÞiSÞiiSeS
所以该文法是二义性文法。
5. 给出描述下面语言的上下文无关文法。
(1) L1={anbnci |n>=1,i>=0 }
(2) L2={aibj|j>=i>=1}
(3) L3={anbmcmdn |m,n>=0}
答:
AàaAb | ab
BàcB | e
Aàa | e
AàbAc | e
6. 设计一个最简的DFA M,使其能够识别所有的被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*00 y=(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)x v=(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|e)
第三章
1. 词法分析器的功能是什么?
答:读源程序的字符序列,逐个拼出单词,并构造相应的内部表示TOKEN;同时检查源程序中的词法错误。
答:空格、跳格、回车等分隔符号对词法分析不起作用,可以删除。但是回车符号可以用于错误定位,所以在删除回车符号前需要统计回车的个数。
答:(+|-|e)([1-9][0-9]*|0)(.[0-9][0-9]*|e) (E(+|-|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]:
SàaABbcd | e
AàASd | e
BàSAh | eC | e
CàSf | Cg | e
答:(1)
Predict(SàaABbcd)={a}
Predict(Sà e)={#,d,f,a,h }
Predict(AàASd)={a,d}
Predict(Aà e)={h,a,d,b,e}
Predict(BàSAh)={a,d,h}
Predict(Bà eC)={e}
Predict(Bà e)={b}
Predict(CàSf)={a,f}
Predict(Cà Cg)={a,f,g}
Predict(Cà e)={g,b}
(2)由于Predict(AàASd)Ç Predict(Aà e)¹Æ,所以该文法不是LL(1)文法。
2. 下列描述括号匹配的文法中,哪些是LL(1)文法?
(1) Sà(SS’ | e
S’ à) | e
(2) Sà(S)S | e
(3) SàS(S)S | e
(4) Sà(S | S’
S’à(S’) | e
答:(1)不是,(2)是,(3)不是,(4)不是
3. 已知文法G[E]:
EàE+T | T
TàT*F | F
Fài | (E)
请按递归下降法构造该文法的语法分析程序。
答:求产生式的predict集合:
predict(EàE+T)={i,(}
predict(EàT)={i,(}
predict(TàT*F)={i,(}
predict(TàF)={i,(}
由于文法中非终极符号E和T对应的产生式的predict集合的交集都不为空,所以该文法不满足自顶向下分析的条件,现对文法进行等价变换得到如下文法:
EàTE’
E’à+TE’ | e
TàFT’
T’à*FT’ | e
Fài
Fà(E)
求新文法的predict集合:
Predict(EàTE’)={(,i}
Predict(E’à+TE’)={+}
Predict(E’àe)={#,)}
Predict(TàFT’)={i,(}
Predict(T’à*FT’)={*}
Predict(T’àe)={+,),#}
Predict(Fài)={i}
Predict(Fà(E))={(}
由于以上文法中任意非终极符号对应的产生式的predict集合的交集都为空,所以满足自顶向下分析的条件,所以可以写出如下的递归下降语法分析伪代码:
Void E()
{ if(tokenÎ{(,i}) {T();E’();}
else Error();}
void E’()
{ if(tokenÎ{+}) {Match(‘+’);T();E’();}
else if(tokenÎ{#,)}) {;}
else Error();}
void T()
{ if(tokenÎ{i,(}) {F();T’();}
else Error();}
void T’()
{ if(tokenÎ{*}) {Match(‘*’);F();T’();}
else if(tokenÎ{+,),#}) {;}
else Error();}
void F()
{ if(tokenÎ{i}) {Match(‘i’);}
else if(tokenÎ{(}) {Match(‘(‘);E();Match(‘)’);}
else Error();}
4. 构造一个LL(1)文法G,它能识别语言L:
L={w | w为字母表S上不包括两个相邻的1的非空串},其中S={0,1}。
并证明你所构造的文法是LL(1)文法。
答:Aà0E | 1F
Bà0E | 1F
Cà0E
EàB | e
FàC | e
Predict(Aà0E)={0}
Predict(Aà1F)={1}
Predict(Bà0E)={0}
Predict(Bà1F)={1}
Predict(EàB)={0,1}
Predict(Eàe)={#}
Predict(FàC)={0}
Predict(Fàe)={#}
对任意非终极符号对应的产生式的predict集合的交集都为空,所以该文法是LL(1)文法。
5. 已知文法G[A]为:
AàaABe | a
BàBb | d
答:(1)所求G’[A]为:
AàaA’ (1)
A’àABe (2)
A’à e (3)
BàdB’ (4)
B’àbB’ (5)
B’à e (6)
Predict(AàaA’)={a}
Predict(A’àABe)={a}
Predict(A’àe)={#,d}
Predict(BàdB’)={d}
Predict(B’àbB’)={b}
Predict(B’àe)={e}
对任意非终极符号对应的产生式的predict集合的交集都为空,所以该文法是LL(1)文法。
|
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) SàaA
AàAb
Aàb
(2) SàaSSb
SàaSSS
Sàc
(3) SàAS
Sàb
AàSA
Aàa
(4) SàcA
SàccB
BàccB
Bàb
AàcA
Aàa
构造上述文法的LR(0)归约活前缀状态机,并给出LR(0)分析表。
答:
(1)
(2)
(3)
(4)
2. 设有下列文法:
(1) SàSaS | b
(2) SàbSb | cSc | b | c
(3) SàbSb | bSc | d
(4) SàaSb | bSa | ab
(5) SàSab | bR
RàS | a
(6) SàSAB | BA
Bàb
AàaA | B
(7) SàAaAb | BbBa
Bàe
Aàe
(8) AàaABe | Ba
BàdB | e
说明上述文法是否为SLR(1)文法。若是,请构造SLR(1)分析表;若不是,请说明理由。
答:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
3. 设有下列文法:
SàaAd | bBd | aBe | bAe
Aàg
Bàg
说明该文法是LR(1)文法,但不是LALR(1)文法。
答:
4. 设有下列文法:
(1) EàE+T | T
TàTF | T
Fà(E) | F* | a | b
(2) SàAa | bAc | dc | bda
Aàd
说明上述文法是否为SLR(1)文法?是否为LALR(1)文法?并构造相应的分析表。
答:(1)
(2)
5. 设有下列文法:
LàMLb | a
Màe
说明上述文法是否为LR(1)文法,若不是,请说明理由。
答:
第六章
1.试写出下列类型的内部表示:
a.integer
b.ARRAY [1..5] of RECORD i:integer; b:boolean END
c.ARRAY [1..5] of RECORD a:ARRAY [1..10]; r:RECORD i,j:integer END END
d. RECORD r: RECORD x,y:real END;a: ARRAY [1..10] of integer END
2. 设当前层数为l,可用区距为101,且有下列程序段:
CONST mm=333;nn=444;
TYPE atype = ARRAY[1..10] OF real;
rtype = RECORD i,j:integer END;
VAR a,b:atype;
x,y:real
试写出各标识符的内部表示。
3. 设当前层数和区距分别为l和off,且有函数说明首部:
FUNCTION f(A:atype;VAR B:atype;VAR X:real):integer
其中atype的定义见题5,试写出f的内部表示。
4. 要求在下面括号中写上相应ℓ(层数)和区距(off)。
()()PROCEDURE g(A:atype;()()
VAR B:atype;()()
VAR X:real()())()().
5. 给出下面C程序扫描到语句c=a+b+x时相应的全局符号表(采用顺序表结构)。
main()
{
int a=0;
float c=1.0;
{
float a=3.0;
{
float x=1.3;
float b=0.3;
}
{
int b=10;
c=a+b+x;
}
}
}
6. 给出题1中程序扫描到语句c=a+b+x时相应的全局符号表(采用外拉链的散列表结构)。
7. 根据标识符的作用域规则,分别给出图6.5的程序中,过程P、Q、R、S中有效的标识符。
第七章
IF x <0 THEN x:=x+1 ELSE x:=x+1
WHILE y > 0 DO
BEGIN y:=y-x; x:=x-1 END
a:=1;
while a<=10 do
begin if a<>b then
A[a]:=A[b]+2;
else a:=a+1;
b:=b+1;
end
第八章
1. 将下面的程序段划分为基本块并画出其程序流图。
read(A);
read(B);
F:=1;
C:=A*A;
D:=B*B;
if C E:=A*A; F:=F+1; E:=E+F; write(E); goto L3; L1: E:=B*B; F:=F+2; write(E); if E>100 goto L2; goto L3; L2: F:=F-1; goto L1; 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. 写出如下循环语句不变式外提后的四元式中间代码。 while i<=100 do begin u:=A*B; m:=u*u; S:=S+m*m; i:=i+1; end 5. 写出下面循环语句不变式外提后的四元式中间代码,其中数组各下标的类型为1..10。 while i<=100 do begin j:=1; while j<=100 do begin k:=1; while k<=100 do A[i][j][k]:=0; end end 第九章 1.过程活动记录包含哪些信息?各信息的作用?何时填写它们? 2.下面是一个调用递归函数的Pascal程序 program PP(input,output) VAR k:integer; FUNCTION F(n:integer):integer begin if n<=0 then F:=1 else F:=n*F(n-1); end; begin k:=F(10); … end. 当第二次(递归地)进入F后,DISPLAY的内容是什么?当时整个运行栈的内容是什么? 3.对于下面的程序: procedure P(X,Y,Z); begin Y:=Y+1; Z:=Z+X; end P; begin A:=2; B:=3; P(A+B,A,A); print A end 当参数传递的办法分别为(1)传值;(2)传地址;(3)值-结果;(4)传名时,程序执行时输出的A分别是什么? 4.应用Pascal语言的作用域规则,说明下面程序中的名字a和b的每一次出现所应用的声明。 program a(input,output); procedure b(u,v,x,y:integer); var a:record a,b:integer end; b:reocrd b,a:integer end; begin with a do begin a:=u;b:=v end; with b do begin a:=x;b:=y end; writeln(a.a,a.b,b.a,b.b) end; begin b(1,2,3,4) end. 5.为下面的C程序构造一个可能的运行时环境。 int a[10]; char *a=”hello”; int f(int i,int b[]) { int j=1; A: { int i=j; char c=b[I]; … } } void g(char *s) { char c[10]; B: { int a[5]; ... } } main() { int x=1; x=f(x,a); g(s); return 0; } (1)在进入函数f中的块A之后。 (2)在进入函数g中的块B之后。 6.Display表和静态链的作用是什么?试举一个程序例子,并考察其Display表和静态链的内容。 7.过程参数的传递方式有几种?简述"传地址"和"传值"的实现原理。 第十章 IF x > 0 THEN y:=y+1 ELSE IF x < 0 THEN y:=y-1 的目标代码,其中的变量均为非形参实型变量。 WHILE x < y DO BEGIN y :=y + 1; IF y > 0 THEN y :=y-x ELSE WHILE y < 0 DO y := y + x END 的目标代码,其中变量均为非形参实型变量。