编译原理复习资料汇编Word格式.docx
《编译原理复习资料汇编Word格式.docx》由会员分享,可在线阅读,更多相关《编译原理复习资料汇编Word格式.docx(25页珍藏版)》请在冰豆网上搜索。
4、用SLR
(1)文法能定义的语言集合、用LR
(1)文法能定义的语言集合和用LALR
(1)文法能定义的语言集合之间有什么关系?
用SLR
(1)文法能定义的语言集合⊂用LALR
(1)文法能定义的语言集合,
用LALR
(1)文法能定义的语言集合⊂用LR
(1)文法能定义的语言集合。
5、下面是inti,j,k这样的类型声明的两种不同语法:
D→TLD→TL
T→int|realT→int|real
L→L,id|idL→id,L|id
如果用LL
(1)分析方法,应该选择哪个文法?
如果用某种LR分析方法,选择哪个文法更好?
简要说明理由。
对于LL
(1)分析方法,两个文法都不合适,左边的文法是左递归的,右边文法有公共左因子。
修改右边文法来适应LL
(1)分析的要求,相对来说比较容易一些,因为只要提公共左因子。
对于LR的各种分析方法,两个文法都适用,但是采用左边的文法更好一些。
用左边的文法时,分析器一边扫描一边归约,占用分析栈的空间较少。
而用右边的文法时,分析器要把所有的标识符都移进栈后才进行归约,因此使用较多的分析栈空间。
(结合语法制导的翻译,采用左边的文法还有好处:
便于确定T的类型属性在栈中的位置。
)
6、在C语言中,3++和(id+id)++这样的表达式被编译时,编译器都会报告如下的错误:
invalidlvalueinincrement
说明左值不能为数值或表达式。
现有如下简化的C语言表达式文法:
E→E+E|(E)|E++|id|num
请写一个语法制导定义或翻译方案,检查++的运算对象是否合法。
给非终结符E一个综合属性v,其值可取lvalue或rvalue,分别表示E是左值标识符和右值表达式,那么语法制导定义如下(无输出则表示无错):
E'
→E
E→E1+E2E.v:
=rvalue
E→(E1)E.v:
=E1.v
E→E1++ifE1.v=rvaluethenprintf(“invalidlvalueinincrement”);
E.v:
E→idE.v:
=lvalue
E→numE.v:
7、E→E+T|T
T→num.num|num
给出一个语法制导定义以确定每个子表达式的类型int/real。
E→E1+T{if(E1.type=realorT.type=real)
thenE.type=realelseE.type=integer}
E→T{E.type=T.type;
}
T→num.num{T.type=real;
T→num{T.type=integer;
8、把下列C语言程序的可执行语句翻译为:
main()
{inti;
inta[10];
while(i<
=10)a[i]=0;
}
(a)三地址代码
(b)后缀式
(a)L0:
ifi<
=10gotoL1
gotoL2
L1:
a[i]:
=0
gotoL0
L2:
(b)后缀式:
i10<
=a[i]0assignwhile
9、试构造下面的程序的流图,并找出其中所有回边及循环。
readP
x:
=1
c:
=P*P
ifc<
100gotoL1
B:
=x+1
=B+x
writex
halt
B:
=10
=x+2
writeB
ifB<
100gotoL2
gotoL1
答:
程序的流图如下
10、对本题中所示的流图,求出其各结点n的控制结点集D(n)、回边及循环(n0为首结点)。
各结点n的控制结点集D(n)如下:
D(n0)={n0}
D(n1)={n0,n1}
D(n2)={n0,n1,n2}
D(n3)={n0,n1,n2,n3}
D(n4)={n0,n1,n2,n4}
D(n5)={n0,n1,n2,n5}
D(n6)={n0,n1,n2,n5,n6}
D(n7)={n0,n1,n2,n5,n6,n7}
回边和循环:
因为D(n5)={n0,n1,n2,n5},且n5->
n2,所以n5->
n2为一条回边。
根据它求出的循环L1={n2,n5,n3,n4}。
因为D(n6)={n0,n1,n2,n5,n6},且n6->
n1,所以n6->
n1为一条回边。
根据这条回边,求出的循环L2={n6,n1,n5,n3,n4,n2}。
11、考虑下面求矩阵A、B成绩的程序片段:
BEGIN
FORi:
=1TOnDO
FORj:
FORk=1TOnDO
c[i,j]:
=c[i,j]+A[i,k}*B[k,j]
END
(1)假定对数组A、B、C采用静态存储分配,每个字占用4个字节,存储器以字节为单位编址。
给出该程序的三地址代码序列。
(2)构造该程序相应的流图。
(3)删除流图中各基本块内的公共子表达式
(4)指出流图中所有回边及其相应循环,并且进行循环优化。
(1)设数组元素按行存放,A、B、C数组都是n*n的二维数组,各维的下界均为0,每个元素占一个字(4个字节),则数组元素(如A[i,j])的地址计算公式为:
D(A[i,j])=addr(A)+((i-0)*n+(j-0))*4
=addr(A)+4*(i*n+j)
该程序的三地址代码序列被划分成基本块后如下:
(2)程序流图如下:
(3)仅基本块B7中有公共子表达式,删除公共子表达式后基本块B7变换成:
(4)根据
(2)的程序流图,每个结点的控制结点集如下:
D(B1)={B1}
D(B2)={B1,B2}
D(B3)={B1,B2,B3}
D(B4)={B1,B2,B3,B4}
D(B5)={B1,B2,B3,B4,B5}
D(B6)={B1,B2,B3,B4,B5,B6}
D(B7)={B1,B2,B3,B4,B5,B6,B7}
D(B8)={B1,B2,B3,B4,B5,B6,B8}
D(B9)={B1,B2,B3,B4,B9}
根据回边B7->
B6,循环L1为:
L1={B7,B6}
根据回边B8->
B4,循环L2为:
L2={B8,B6,B7,B5,B4}
根据回边B9->
B2,循环L3为:
L3={B9,B4,B5,B6,B7,B8,B3,B2}
经循环优化后三地址代码序列变为:
12、试求出如下四元式程序中的循环并进行循环优化.
I:
readJ,K
L:
A:
=K*I
=J*I
C:
=A*B
writeC
=I+1
ifI<
100gotoL
halt
把本题的三地址代码划分成基本块并画出其程序流图显示在图9.4
(1)中,其中有三个基本块B1,B2,B3,有一条回边B2->
B2,相应的循环是{B2}。
(1)代码外提:
由于循环中没有不变运算,故不做此项优化
(2)强度削弱:
B2中A和B都是I的归纳变量。
优化结果显示在图9.4
(2)中。
(3)删除归纳变量:
变换循环控制条件,删除归纳变量I后的流图显示在图9.4(3)中
13、下面是应用筛法求2到N之间素数的程序:
begin
readN;
fori:
=2toNdo
A[i]:
=true;
/*置初值*/
=2toN**0.5do
/*运算符**代表幂乘*/
ifA[i]then
/*i是一个素数*/
forj:
=2*itoNbyido
A[j]:
=false
/*j可被i除尽*/
end
(1)试写出其四元式中间代码,假设对数组A用静态分配存储单元,且下届为0;
(2)作出流图并求出其中的循环;
(3)进行代码外提;
(4)进行强度削弱和删除归纳变量;
答:
采用字节地址,两个字节作为一个机器字。
(1)程序的四元式中间代码如下:
B1:
readN
/*置初值*/
i:
=2
B2:
ifi>
NgotoB4
/*第一个for语句*/
B3:
T1:
=i
T2:
=addr(A)
/*数组A的基地址*/
=2*T1
T2[T1]:
=true
=i+1
gotoB2
B4:
T3:
=N**0.5
=[T3]+1
/*[T3]是对T3的值取整*/
B5:
T3gotoB12
B6:
T4:
T5:
=addr(A)
T4:
=2*T4
ifT5[T4]gotoB8
B7:
gotoB11
B8:
j:
=2*i
B9:
ifj>
NgotoB11
/*第三个for语句*/
B10:
T6:
=j
T7:
=2*T6
T7[T6]=false
=j+i
gotoB9
B11:
gotoB5
B12:
(2)根据四元式的中间代码,可划分成基本块B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11。
其程序流图如下:
考察上面的程序流图:
D(B3)={B1,B2,B3}又有B3->
B2,因此B3->
B2是一条回边。
根据它找到的循环L1={B2,B3}。
D(B10)={B1,B2,B4,B5,B6,B9,B10},又有B10->
B9,所以B10->
B9是一条回边。
根据这条回边找到循环L2={B9,B10}。
D(B11)={B1,B2,B4,B5,B6,B9,B11},又有B11->
B5,因此B11->
B5是一条回边。
根据这条回边找到循环L3={B11,B9,B10,B8,B7,B6,B5}
(3)进行代码外提
把在循环中不随循环变化的操作提到循环外的前置结点中,且在基本块中作复写传播和删除无用赋值。
结果程序流图如下:
(4)进行强度削弱和删除归纳变量后,其程序流图如下:
14、对下面的程序片段作出其程序流图并计算:
(1)各基本块的到达_定值集IN[B];
(2)各基本块中各变量引用点的ud链;
(3)各基本块出口的活跃变量集V_OUT[B];
(4)各基本块中变量定值点的du链。
J:
=0
=J+I
readI
writeJ
L2:
=I*I
本题程序的程序流图如图9.6
(1)所示。
(1)计算各基本块的到达-定值集IN[B]。
公式为:
IN[B]
=∪OUT[P]
P∈P[B]
OUT[B]=GEN[B]∪(IN[B]-KILL[B])
GEN[B]和KILL[B]由程序流图直接求出,显示在表9.6
(1)中。
表9.6
(1)
基本块
GEN[B]
位向量
KILL[B]
B1
{d1,d2}
11000000
{d3,d4,d6}
00110100
B2
{d3,d4}
00110000
{d1,d2,d6}
11000100
B3
{d6}
00000100
{d1,d4}
10010000
B4
(二)上海的人口环境对饰品消费的影响{}
体现市民生活质量状况的指标---恩格尔系数,上海也从1995年的53.4%下降到了2003年的37.2%,虽然与恩格尔系数多在20%以下的发达国家相比仍有差距,但按照联合国粮农组织的划分,表明上海消费已开始进入富裕状态(联合国粮农组织曾依据恩格尔系数,将恩格尔系数在40%-50%定为小康水平的消费,20%-40%定为富裕状态的消费)。
00000000
为此,装潢美观,亮丽,富有个性化的店面环境,能引起消费者的注意,从而刺激顾客的消费欲望。
这些问题在今后经营中我们将慎重考虑的。
{}
求各基本块到达-定值的初值及各遍的执行结果显示在表9.6
(2)中。
(3)优惠多表9.6
(2)
附件
(一):
初值
市场环境所提供的创业机会是客观的,但还必须具备自身的创业优势,才能使我们的创业项目成为可行。
作为大学生的我们所具有的优势在于:
第一遍后
(1)位置的优越性第二遍后
(二)上海的人口环境对饰品消费的影响第三遍后
IN[B]
OUT[B]
据调查统计,有近94%的人喜欢亲戚朋友送给自己一件手工艺品。
无论是送人,个人兴趣,装饰还是想学手艺,DIY手工制作都能满足你的需求。
下表反映了同学们购买手工艺制品的目的。
如图(1-4)IN[B]
11100100
00100100
(2)求各基本块中各变量引用点的ud链:
假设在程序中某点u引用了变量a,则把能到达u的a的所有定值点,称为a在引用点u的引用-定值链(简称ud链)。
可以利用到达-定值信息来计算各个变量在任何引用点的ud链。
由图9.6
(1)的程序流图可知,I的引用点是d3、d5和d6,J的引用点是d3和d8。
B2中I和J的引用点d3前面没有对I和J的定值点,其ud链在IN[B2]={d1,d2,d3,d6}中,所以I在引用点d3的ud链是{d1,d6};
J在引用点d3的ud链是{d2,d3}。
在B2中I的引用点d5前面有I的定值点d4,且在d4定值后到达d5,所以I在引用点d5的ud链是{d4}。
B3中I的引用点d6前面没有I的定值点,其ud链是IN[B3]中I的所有定值点,所以是{d4}。
B4中J的引用点d8前面没有对J的定值点,其ud链是IN[B4]中J的所有定值点。
已知IN[B4]={d3,d4},所以,J的引用点d8的ud链是{d3}。
(3)各基本块出口的活跃变量集v-OUT[B]:
对程序中某变量a和某点P,如果存在一条从P开始的道路,其中引用了a在P点的值,则称a在点P是活跃的。
计算公式如下:
V_IN[B]
=USE[B]∪(V_OUT[B]-DEF[B])
V_OUT[B]=∪V_IN[S]
S∈S[B]
其中,S[B]是B的所有后继块组成的集合。
DEF[B]和USE[B]可以从给定流图直接求出。
从图9.6
(1)的流图中求出的各基本块的DEF[B]和USE[B]显示在表9.6(3)中。
表9.6(3)
USE[B]
DEF[B]
Φ
{I,J}
{I}
{J}
计算次序为B4,B3,B2,B1,各次迭代结果显示在表9.6(4)中。
表9.6(4)
第一次迭代后
第二次迭代后
第三次迭代后
V_IN[B]
V_OUT[B]
(4)各基本块变量定值点的du链
一个变量a在某点P定值后该定值到达a的那些引用点成为该定值点的定值-引用链(简称du链)。
使用下面的方程式进行计算:
D_IN[B]
=D_USE[B]∪(D_OUT[B]-D_DEF[B])
D_OUT[B]=∪D_IN[S]
其中S[B]是B的后继基本块集。
D_USE[B]和D_DEF[B]根据程序流图可直接求出。
本题根据图9.6
(1)的程序流图求出的D_USE[B]和D_DEF[B]显示在表9.6(5)中。
表9.6(6)
D_DEF[B]
D_USE[B]
{(d3,I),(d5,I),(d6,I),(d3,J),(d8,J)}
{(d6,I),(d8,J)}
{(d3,I)