编译原理复作业集Word文件下载.docx
《编译原理复作业集Word文件下载.docx》由会员分享,可在线阅读,更多相关《编译原理复作业集Word文件下载.docx(21页珍藏版)》请在冰豆网上搜索。
12•写出字母表刀={a,b}上语言L={w|w的最后两个字母是aa或bb}的正规式,并画出接受该语言的最简DFA残骛楼諍锩瀨濟溆塹籟。
13•有穷自动机M接受字母表刀={0,1}上所有满足下述条件的串:
串中至少包含两个连续的0或两个连续的1。
请写出与M等价的正规式。
酽锕极額閉镇桧猪訣锥。
14.有正规式b*abb*(abb*)*,
(1)构造该正规式所对应的NFA(画出状态转换图)。
(2)将所求的NFA确定化(画出确定化的状态转换图)。
(3)将所求的NFA最小化.(画出最小化后的状态转换图)。
15.求出下列文法所产生语言对应的正规式.
SbS|aA
AaA|bB
BaA|bC|b
CbS|aA
18.下面两个文法中哪一个不是LR
(1)文法?
对非LR
(1)的那个文法。
给出那个有移进一归约冲突的规范的LR
(1)项目集
aAc
写一个LR
(1)文法,不准超过6个产生式。
21•写一个文法,使其语言是奇数集,且每个奇数不以0开头。
22.考查文法G(s):
S—(T)|a+S|a
T—T,S|S
(1)消除文法的左递归;
(2)提取公共左因子;
(3)对每个非终结符,写出不带回朔的递归子程序。
23•设文法G(S):
S—(L)|aS|a
L—L,S|S
(1)消除左递归和回溯;
(2)计算每个非终结符的FIRST和FOLLOW
(3)构造预测分析表。
24•消除下列文法的左递归.
SSaP|Sf|P
PQbP|Q
QcSd|e
25.已知文法G:
AaABe|a
BBb|d
给出与上述文法等价的LL
(1)文法G'
。
26.已知文法G[A]:
A—aAB|a
B—Bb|d
(1)构造与G[A]等价的LL
(1)文法;
(2)构造G'
[A]的预测分析表。
27.程序的文法如下:
PtD
D>
D;
D|id:
T|procid;
S
(1)写一个语法制导定义,打印该程序一共声明了多少个id
(2)写一个翻译方案,打印该程序每个变量id的嵌套深度。
28.构造下面文法的LL
(1)分析表。
TL
T“int|real
L>
idR
R>
idR|;
29.考虑下文法:
DTV
Tint|float
Vid,V|id
a.在该文法中提取左公因子。
b.为所得文法的非终结符构造First和Follow集合。
c.说明所得的文法是LL
(1)文法。
d.为所得文法构造LL
(1)分析表。
e.假设有输入串
intx,y,z
写出相应LL⑴分析程序的动作。
30•说明如下文法是否是LL
(1)文法,若不是,将其转换为LL
(1)文法。
最后给出该文法的LL
(1)分析表。
謀养抟箧飆鐸怼类蒋薔。
ABe
BBb|a
31•设有文法:
P—beginXYend
X—Xd;
X—d;
Y—Y;
s
Y—s
(1)该文法含有左递归吗?
若有,消除它。
⑵改造后的文法是LL
(1)文法吗?
若是,给出其预测分析表。
(3)写出句子begind;
send的分析过程。
32•已给文法G[S]:
S—SaP|Sf|PP—qbP|q
将G[S]改造成LL
(1)文法,并给出LL
(1)分析表。
33•设文法G(S):
S—(L)|aS|aL—L,S|S
(2)计算每个非终结符的FIRST和FOLLOW;
34•给定文法G[S]:
S—Aa|dAb|Bb|dBa
A—c
B—c
构造文法G[S]的LR
(1)分析表。
35•已知文法G(S)
S—a|A|(T)T—T,S|S写出句子((a,a),a)的规范归约过程及每一步的句柄。
36•已知文法G(E)
E—T|E+T
T—F|T*FF—(E)|i
给出句型(T*F+i)的最右推导及画出语法树;
37•说明下面的文法不是SLR
(1)文法,并重写一个等价的SLR
(1)文法。
SMa|bMc|dc|bdaMd
S'
SS>
Ma|bMc|dc|bdaM>
d
厦礴恳蹒骈時盡继價骚。
T.S
St.Ma
Stb.Mc
St.bMc
b一.
Stb.da
d.
Stbd.a
*
St.dc
Mt.d
MTd.
St.bda
-归约冲突
因为a是M的后继符号之一,因此在上面最右边一个项目集中有移进
等价的SLR
(1)文法是
S>
da|bdc|dc|bda
38.在PASCAL语言中,简单类型的变量的声明例举如下:
m,n:
integerp,q,r:
real
为这样的声明写一个LR
(1)文法(为简单起见,变量标识符都用id表示),并根据你的文法写一个语法制导定义(或叫做为你的文法加上语义动作),它将变量的
类型填入符号表。
茕桢广鳓鯡选块网羈泪。
39.—个非LR
(1)的文法如下:
MLb|a
MTg
请给出所有有移进一归约冲突的LR
(1)项目集,以说明该文法确实不是LR
(1)的。
40.若有文法G(S)的产生式如下:
SL=R
SR
L*R
Li
RL,
构造识别所有项目集规范族的DFA.,判断该文法是否是SLR
(1)文法,说明理由。
41.现有句型和产生式A>
b,分别指出LL
(1)方法和LR
(1)方法在扫描到此句型的什么位置决定用此产生式?
鹅娅尽損鹤惨歷茏鴛賴。
42.为下面的算术表达式文法写一个语法制导的翻译方案,它将每个子表达式E的符号
(即值大于零还是小于零)记录在属性E.sign中(属性值分别用POS或NEG表示)。
你可以假定所有的整数都不为零,这样就不用担心零的符号。
籟丛妈羥为贍债蛏练淨。
EtE*E|+E|-E|unsigne(_integer
43.一个文法如下:
(S)
STa
请给出该文法中对活前缀(((有效的LR
(1)项目。
44.为下面文法添加语义规则(或叫动作子程序),输出S产生的二进制数的值,如输入是101时,输出5。
預頌圣鉉儐歲龈讶骅籴。
SB|BB>
0|1
45.写出表达式(a+b*c)/(a+b)—d的逆波兰表示及三元式序列。
46.把表达式
-(a+b)*(c+d)+(a+b+c)
翻译成三地址码序列。
47.设布尔表达式的文法为
EfE1vE2
EfE/E2
Efi
假定它们将用于条件控制语句中,请
(1)改写文法,使之适合进行语法制导翻译;
(2)写出改写后的每个产生式的语义动作。
48.将语句if(A<
XB>
0)while(C>
0)C=C+D;
渗釤呛俨匀谔鱉调硯錦。
49.设有基本块如下:
T仁S+R
T2=3
T3=12/T2
T4=S/R
A=T1-T4
T5=S+R
B=T5
T6=T5*T3
B=T6
(1)画出中间代码的流图;
(2)设A、B是出基本块后的活跃变量,请给出优化后的三地址码序列。
50.设已构造出文法G(S):
(1)S>
BB
(2)B>
aB
(3)B>
b
的LR分析表如下
状态
ACTION
GOTO
a
b
#
S
B
s3
s4
1
2
acc
s6
s7
r51
3
8
4
r3
5
r1
6
9
7
r2
假定输入串为abab,请给出LR分析过程(即按照步骤给出状态,符号,输入串的变化过程)。
51.给出活动记录空间结构。
并给出各部分的存储对象。
52.将下面程序段翻译成四元式序列。
while(A<
CAB<
D){if(A==1)C=C+1;
elsewhile(A<
D){
A=A+2;
}
53.有一语法制导翻译如下所示:
S—bAb{print(1”}
A—(B{print(2”}
A—a{print(“3”)}
B—Aa){print(“4”)}
若对输入序列b(((aa)a)a)b进行自底向上分析,请写出输出序列。
54.画出IFa>
0THENx:
=x+1ELSEx:
=4*(x-1)的翻译方案图。
铙誅卧泻噦圣骋贶頂廡。
55.下面是一个C语言程序:
main(){longi;
longa[0][4];
longj;
i=4;
j=8;
printf(“%d,n%”d,sizeof(a),a[0][0];
)
虽然出现longa[0][4]这样的声明,在X86/Linux机器上该程序还是能通过编译并生成目标代码。
请回答下面两个问题:
擁締凤袜备訊顎轮烂蔷。
(1)sizeof(a)的值是多少,请说明理由。
(2)a[0][0]的值是多少,请说明理由。
(1)按照数组size的计算公式,sizeof(a)的值一定是0。
(2)a[0][0]的值是4。
虽然a的size是0,但它仍然有起始地址,并且a[0][0]的地址等于a的起始地址。
由于X86/Linux机器上,活动记录栈向低地址方向增长,另外由于低地址放低位字节,因此a[0][0]的地址和i的地址一致,其值和i的值一样,等于4。
贓熱俣阃歲匱阊邺镓騷。
56.将下面的条件语句表示成三地址码序列:
if(a>
b)x=a+b*c;
elsex=b-a;
57.考虑下面的三地址语句序列:
b:
=1
=2
ifw<
=xgotoL2
e:
=b
gotoL2
L1:
gotoL3
L2:
c:
=3
=4
c:
=6
L3:
ify<
=zgotoL4
gotoL5
L4:
g:
=g+1
h:
=8
gotoL1
L5:
h:
=9
(1)在该代码中用水平的横线将代码分成基本块,并给每个基本块一个序号。
(2)画出该代码的控制流图,每个基本块就用
(1)的序号表示。
(3)若有循环的话,列出构成每个循环的结点
(1)
(2)
坛搏乡囂忏蒌
蜡變黲癟報伥
買鯛鴯譖昙膚遙
綾镝鯛駕櫬鹕踪
3个局部
gotoL1(7)
=9(8)
(3)结点5、7和3构成一个循环,其中5是入口结点
58•—个C语言程序如下:
func(i1,i2,i3)
longi1,i2,i3;
{
longj1,j2,j3;
printf("
Addressesofi1,i2,i3=%o,%o,%o\n"
&
i1,&
i2,&
i3);
鍥铃氈淚。
printf("
Addressesofj1,j2,j3=%o,%o,%o\n"
j1,&
j2,&
j3);
铉锚鈰赘。
main()
func(i1,i2,i3);
该程序在SUNT作站上的运行结果如下:
Addressesofi1,i2,i3=35777773634,35777773640,35777773644闫撷凄。
Addressesofj1,j2,j3=35777773524,35777773520,35777773514韦辚糴。
从上面的结果可以看出,func函数的3个形式参数的地址依次升高,变量的地址依次降低。
试说明为什么会有这个区别。
驅踬髏彦浃绥譎饴憂锦
由于实参表达式是反序进入活动记录,而局部变量是顺序在活动记录中分配。
59•—个C语言程序如下:
voidfun(struct{intx;
doubler;
}val){}
struct{intx;
}val;
fun(val);
该程序在X86/Linux机器上的用cc命令编译时,报告的错误信息如下:
1:
warning:
structuredefinedinsideparms
anonymousstructdeclaredinsideparameterlist猫虿驢绘燈鮒诛髅貺庑。
itsscopeisonlythisdefinitionordeclaration,锹籁饗迳琐筆襖鸥娅薔。
whichisprobablynotwhatyouwant.
7:
incompatibletypeforargument1of‘fun'
请问,报告最后一行的错误的原因是什么?
如何修改程序,使得编译时不再出现这个错误信息。
60.一个C语言程序如下:
main(){func();
printf("
Returnfromfunc\n"
);
func()
{chars[4];
strcpy(s,"
12345678"
%s\n"
s);
该程序在PC机linux操作系统上的运行结果如下:
12345678Segmentationfault(coredumped)试分析为什么会出现这样的运行错误。
61.一个C语言函数如下:
func(i)longi;
{longj;
j=i-1;
func(j);
该函数在PC机linux操作系统上编译生成的汇编代码如下:
.file"
stack.c"
gcc2_compiled.:
__gnu_compiled_c:
.text.align2
.globl_func
.type_func,@function
_func:
pushl%ebpmovl%esp,%ebpsubl$4,%espmovl8(%ebp),%edxdecl%edxmovl%edx,-4(%ebp)movl-4(%ebp),%eaxpushl%eaxcall_funcaddl$4,%esp
leave
ret
Lfe1:
.size_func,Lfe1-_func试画出该函数的一个活动记录的内容,包括活动记录的每个单元存放什么东西、执行movl8(%ebp),%edx指令时栈顶指针所指的的位置、与活动记录有关的另一个指针所指的位置和地址增长方向。
構氽頑黉碩饨荠龈话骛。
62.一个C语言的函数如下:
func(c,l)charc;
longl;
{func(c,l);
在X86/Linux机器上编译生成的汇编代码如下:
parameter.c"
.version"
01.01"
.text
.align4
.globlfunc
.typefunc,@function
func:
pushl%ebp——将老的基地址指针压栈
movl%esp,%ebp——将当前栈顶指针作为基地址指针
subl$4,%esp——分配空间
movl8(%ebp),%eax
movb%al,-1(%ebp)
movl12(%ebp),%eaxpushl%eaxmovsbl-1(%ebp),%eaxpushl%eaxcallfuncaddl$8,%esp
.L1:
leave——和下一条指令一起完成恢复老的基地址指针,将栈顶
ret——指针恢复到调用前参数压栈后的位置,并返回调用者
.Lfe1:
.sizefunc,.Lfe1-func
.ident"
GCC:
(GNU)egcs-2.91.6619990314/Linux(egcs-1.1.2release)"
輒峄陽檉簖疖網儂號泶。
(a)请指出对应源程序第5行的函数调用func(c,l)的汇编指令是哪几条。
(b)请说明字符型参数和长整型参数在参数传递和存储分配方面有什么区别。
(小于长整型size的整型参数的处理方式和字符型参数的处理方式是一样的。
)尧侧閆繭絳闕绚勵蜆贅。
63.一个C语言程序及其在某种机器linux操作系统上的编译结果如下。
根据所生成的汇编程序来解释程序中四个变量的作用域、生存期和置初值方式等方面的区别。
识饒鎂錕缢灩筧嚌俨淒。
staticlongaa=10;
shortbb=20;
func(){staticlongcc=30;
shortdd=40;
}编译生成的汇编代码如下:
static.c"
.data
.typeaa,@object
.sizeaa,4
aa:
.long10
.globlbb
.align2
.typebb,@object
.sizebb,2
bb:
.value20
.typecc.2,@object
.sizecc.2,4
cc.2:
.long30.text
.typefunc,@function
pushl%ebp
movl%esp,%ebp
subl$4,%esp
movw$40,-2(%ebp)
丄1:
.sizefunc,.Lfe1-func
.ident"
(GNU)egcs-2.91.6619990314/Linux(egcs-1.1.2release)"
凍鈹鋨劳臘错痫婦胫籴。
aa是静态外部变量,而bb是外部变量,它们都分配在静态数据区(由.data伪指令开始),但是bb由伪指令.globl指明为全局的,用来解决其它文件中对bb的外部引用,而aa只能由本文件引用。
cc是静态局部变量,同aa和bb一样,它的生存期是整个程序并分配在静态数据区。
由于cc在源
程序中的作用域是函数func的体,而在目标文件中,它的作用域至少已是整个文件了,为避免同源
文件中外部变量和其它函数的静态局部变量的名字冲突,所以要对它进行改名,成了cc.2。
由于cc
不是全局的,因此cc.2前面没有伪指令.globl。
dd是自动变量,其作用域是函数func的体,其生
存期是该函数激活期间,因此它分配在栈区,并且置初值是用运行时的赋值来实现。
恥諤銪灭萦欢煬鞏
鹜錦。
64.C语言是一种类型语言,但它不是强类型语言,因为编译时的类型检查不能保证所接受的程序没有运行时的类型错误。
例如,编译时的类型检查一般不能保证运行
时没有数组越界。
请你再举一个这样的例子说明C语言不是强类型语言。
鯊腎鑰诎漣鉀
沩懼統庫。
例如联合体的类型检查一般也不可能在编译时完成,虽然下面例子是可静态判断类型错误的。
unionU{intu1;
int*u2;
}u;
intp;
u.u1=10;
p=u.u2;
p=0;
65.下面程序在SUNX作站上运行时陷入死循环,试说明原因。
如果将第8行的long*p改成short*p,并且将第23行longk改成shortk后,loop中的循环体执行一次便停止了。
试说明原因。
硕癘鄴颃诌攆檸攜驤蔹。
addr();
loop();
long*p;
loop()
longi,j;
j=0;
for(i=0;
i<
10;
i++){
(*p)--;
j++;
addr()
longk;
k=0;
p=&
k;
66.下面程序的结果是120。
但是如果把第10行的abs
(1)改成1的话,则程序结果是
1,试分析为什么会有这不同的结果。
阌擻