编译原理平时作业答案_第1页
编译原理平时作业答案_第2页
编译原理平时作业答案_第3页
编译原理平时作业答案_第4页
编译原理平时作业答案_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

平时作业对于以下语言分别写出它们正规表示式。

(1)

英文字母组成全部符号串,要求符号串中次序包含五个元音。答:

令Letter表示除这五个元音外其它字母。

((letter)*A(letter)*E(letter)*I(letter)*O(letter)*U(letter))*

(2)

英文字母组成全部符号串,要求符号串中字母依照词典次序排列。答:A*B*....Z*(3)

Σ={0,1}上含偶数个1全部串。答:

(0|10*1)*(4)

Σ={0,1}上含奇数个1全部串。答:(0|10*1)*1(5)

具备偶数个0和奇数个1有0和1组成符号串全体。答:设S是符合要求串,|S|=2k+1(k≥0)。则S→S10|S21,|S1|=2k(k>0),|S2|=2k(k≥0)。且S1是{0,1}上串,含有奇数个0和奇数个1。

S2是{0,1}上串,含有偶数个0和偶数个1。 考虑有一个自动机M1接收S1,那么自动机M1以下:和L(M1)等价正规表示式,即S1为:((00|11)|(01|10)(00|11)*(01|10))*(01|10)(00|11)*类似考虑有一个自动机M2接收S2,那么自动机M2以下:和L(M2)等价正规表示式,即S2为:((00|11)|(01|10)(00|11)*(01|10))*所以,S为: ((00|11)|(01|10)(00|11)*(01|10))*(01|10)(00|11)*0|((00|11)|(01|10)(00|11)*(01|10))*1

(6)

不包含子串011由0和1组成符号串全体。答:1*|1*0(0|10)*(1|ε)

(7)

由0和1组成符号串,把它看成二进制数,能被3整除符号串全体。答:假设w自动机以下:对应正规表示式:(1(01*0)1|0)*给出接收以下在字母表{0,1}上语言DFA。

(1)

全部以00结束符号串集合。

(2)

全部具备3个0符号串集合。答:(1)DFA

M=({0,1},{q0,q1,q2},q0,{q2},δ)其中δ定义以下:δ(q0,0)=q1

δ(q0,1)=q0δ(q1,0)=q2

δ(q1,1)=q0δ(q2,0)=q2

δ(q2,1)=q0(2)正则表示式:1*01*01*01*DFA

M=({0,1},{q0,q1,q2,q3},q0,{q3},δ)其中δ定义以下:δ(q0,0)=q1

δ(q0,1)=q0δ(q1,0)=q2

δ(q1,1)=q1δ(q2,0)=q3

δ(q2,1)=q2δ(q3,1)=q3

3下面是用正规式表示变量申明: (int|float)id(,id)*;请改用上下文无关文法表示,也就是写一个上下文无关文法,它和该正规式等价。答:DTL; Tint|float LL,id|id试分析下面给出if-then-else语句文法,它提出原本是为了矫正dangling-else(悬而未决-else)文法二义性:

stmt→ifexprthenstmt

|matched-stmt

matched-stmt→ifexprthenmatched-stmtelsestmt

|other

试说明此文法依然是二义性。答:考虑句子ifethenifethenotherelseifethenotherelseother它具备以下所表示两种分析树stmtexprtheneifstmtifmatched-stmtexprthenmatched-stmteotherifeslestmtmatched-stmtexprthenmatched-stmteothereslestmtmatched-stmtotherstmtmatched-stmtifexprthenmatched-stmteifeslestmteslestmtmatched-stmtexprthenestmtotherexprthenmatched-stmteotherifmatched-stmtother则上面给出if-then-else文法仍是二义性。证实下面文法是SLR(1)文法,并结构其SLR分析表。

E→E+T|T

T→TF|F

F→F*|a|b答:该文法拓广文法G'为(0)E'→E(1)E→E+T(2)E→T(3)T→TF(4)T→F(5)F→F*(6)F→a(7)F→b其LR(0)项目集规范族和goto函数(识别活前缀DFA)以下:I0={E'→·E,E→·E+T,E→·T,T→·TF,T→·F,F→·F*,

F→·a,F→·b}I1={E'→E·,E→E·+T}I2={E→T·,T→T·F,F→·F*,F→·a,F→·b}I3={T→F·,F→F·*}I4={F→a·}I5={F→b·}I6={E→E+·T,T→·TF,T→·F,F→·F*,F→·a,F→·b}I7={T→TF·,F→F·*}I8={F→F*·}I9={E→E+T·,T→T·F,F→·F*,F→·a,F→·b}求FOLLOW集:

FOLLOW(E)={+,$}

FOLLOW(T)={+,$,a,b}FOLLOW(F)={+,$,a,b,*}结构SLR分析表以下:显然,此分析表无多重定义入口,所以此文法是SLR文法。为下面文法结构LALR(1)分析表

S→E

E→E+T|T

T→(E)|a答:其拓广文法G':(0)S'→S(1)S→E(2)E→E+T(3)E→T(4)T→(E)(5)T→a结构其LR(1)项目集规范族和goto函数(识别活前缀DFA)以下:I0={[S’→·S,$],[S→·E,$],[E→·E+T,$/+],[E→·T,$/+],

[T→·(E),$/+],[T→·a,$/+]}I1={[S’→S·,$]}I2={[S→E·,$],[E→E·+T,$/+]}I3={[E→T·,$/+]}I4={[T→(·E),$/+],[E→·E+T,)/+],[E→·T,)/+],

[T→·(E),)/+],[T→·a,)/+]}I5={[T→a·,$/+]}I6={[E→E+·T,$/+],[T→·(E),$/+],[T→·a,$/+]}I7={[T→(E·),$/+],[E→E·+T,)/+]}I8={[E→T·,)/+]}I9={[T→(·E),)/+},[E→·E+T,)/+],[E→·T,)/+],[T→·(E),)/+],[T→·a,)/+]}I10={[T→a·,)/+]}I11={[E→E+T·,$/+]}I12={[T→(E)·,$/+]}I13={[E→E+·T,)/+],[T→·(E),)/+],[T→·a,)/+]}I14={[T→(E·),)/+],[E→E·+T,)/+]}I15={[E→E+T·,)/+]}I16={[T→(E)·,)/+]}合并同心LR(1)项目集,得到LALR项目集和转移函数以下:I0={[S’→·S,$],[S→·E,$],[E→·E+T,$/+],[E→·T,$/+],[T→··(E),$/+],[T→·a,$/+]}I1={[S’→S·,$]}I2={[S→E·,$],[E→E·+T,$/+]}I3,8={[E→T·,$/+/)]}I4,9={[T→(·E),$/+/)],[E→·E+T,)/+],[E→·T,)/+],

[T→·(E),)/+],[T→·a,)/+]}I5,10={[T→a·,$/+/)]}I6,13={[E→E+·T,$/+/)],[T→·(E),$/+/)],[T→·a,$/+/)]}I7,14={[T→(E·),$/+/)],[E→E·+T,)/+]}I11,15={[E→E+T·,$/+/)]}I12,16={[T→(E)·,$/+/)]}LALR分析表以下:(1)经过结构识别活前缀DFA和结构分析表,来证实文法EE+id|id是SLR(1)文法。答:先给出接收该文法活前缀DFA以下:EE·EE·E+idE·idI0EE·EE·+idI1Eid·I2Eid+EE+·idI3EE+id·I4id再结构SLR分析表以下:状态状态动作转移id+$E0s211s3acc2r2r23s44r1r1表中没有多重定义条目,所以该文法是SLR(1)。(2)下面左右两个文法都和(1)文法等价 EE+Mid|id EME+id|id M M请指出其中有几个文法不是LR(1)文法,并给出它们不是LR(1)文法理由。答:只有文法 EME+id|id M不是LR(1)文法。因为对于句子id+id+…+id来说,分析器在面临第一个id时需要做空归约次数和句子中+id个数一样多,而此时句子中+id个数是未知。8 依照自上而下语法分析方法,结构下面文法LL(1)分析表。 DTL Tint|real LidR R,idR|答:先计算FIRST和FOLLOW

FIRST(D)=FIRST(T)={int,real}

FIRST(L)={id}

FIRST(R)={,,ε}

FOLLOW(D)=FOLLOW(L)={$}

FOLLOW(T)={id}

FOLLOW(R)={$}LL(1)分析表以下:intrealid,$DD->TLD->TLTT->intT->realLL->idRRR->,idRR->ε9下面文法产生表示式是对整型和实型常数应用算符+形成。当两个整数相加时,结果仍为整数,不然就是实数。

E→E+T|T

T→num.num|num

(a)给出一个语法制导定义以确定每个子表示式类型。

(b)扩充(a)中语法制导定义把表示式翻译成前缀形式,而且决定类型。使用一元算符inttoreal把整型值转换成相等实型值,以使得前缀形式中+两个操作对象是同类型。答:(a):产生式语义规则EE1+TIF(E1.type=integer)and(T.type=integer)THENE.type:=integerELSEE.type:=realETE.type:=T.typeTnum.numT.type:=realTnumT.type:=integer(b):产生式语义规则EE1+TIF(E1.type=integer)and(T.type=integer)THENBEGINE.type:=integerPrint(‘+’,E1.val,T.val)ENDELSEBEGINE.type:=realIFE1.type=integerTHENBeginE1.type:=realE1.val:=inttoreal(E1.val)EndIFT.type:=integerTHENBeginT.type:=realT.val:=inttoreal(T.val)EndPrint(‘+’,E1.val,T.val)ENDETE.type:=T.typeE.val:=T.valTnum.numT.type:=realT.val:=num.num.lexvalTnumT.type:=integerT.val:=num.lexval10假设说明是由以下文法产生:

D→idL

L→,idL|:T

T→integer|real

(a)建立一个翻译模式,把每一个标识符类型加入到符号表中。

(b)从(a)中翻译模式结构一个预翻译程序。答:(a):产生式翻译模式DidL{D.Type:=L.Type}{addtype(id.entry,D.type)}L,idL1{L.Type:=L1.Type}{addtype(id.entry,L.type)}L:T{L.type:=T.type}Tinteger{T.type:=integer}Treal{T.type:=real}(b): ProcedureD; begin Iflookahead=idthenBeginMatch(id);D.type=L;addtype(id.entry,D.type)endelseerror endFunctionL:DataType;BeginIflookahead=’,’thenBeginMatch(‘,’);Iflookahead=idthenbeginmatch(id);L.Type=L;addtype(id.entry,L.type);return(L.type)endElseerrorEndElseiflookahead=’:’thenBeginMatch(‘:’);L.Type=T;return(L.Type)endelseerrorEnd FunctionT:DataType;BeginIflookahead=integerthenBeginMatch(integer);return(integer)endelseIflookahead=realthenBeginMatch(real);return(real)endelseerrorend11 为下面算术表示式文法写一个语法制导翻译方案,它将每个子表示式E符号(即值大于零还是小于零)统计在属性E.sign中(属性值分别用POS或NEG表示)。你能够假定全部整数都不为零,这么就不用担心零符号。EE*E|+E|E|unsigned_integer答: EE1*E2{ifE1.sign=E2.signthenE.sign:=POSelseE.sign:=NEG}E+E1{E.sign:=E1.sign}EE1{ifE1.sign=POSthenE.sign:=NEGelseE.sign:=POS}Eunsigned_integer{E.sign:=POS}12 为下面文法写一个语法制导定义,用S综合属性val给出下面文法中S产生二进制数值。比如,输入101.101时,S.val:=5.625。(不得修改文法。) SL.R|L LLB|B RBR|B B0|1答: SL.R S.val:=L.val+R.valSL S.val:=L.val LL1B L.val:=L1.val2+B.valLB L.val:=B.val RBR1 R.val:=(R1.val+B.val)/2RB R.val:=B.val/2 B0 B.val:=0B1 B.val:=113试问下面程序将有怎样输出?分别假定:

(a)传值调用(call-by-value);

(b)引用调用(call-by-reference);

(c)复制恢复(copy-restore);

(d)传名调用(call-by-name)。

programmain(input,output);

procedurep(x,y,z);

begin

y:=y+1;

z:=z+x;

end;

begin

a:=2;

b:=3;

p(a+b,a,a);

printa

end.答:1).传地址:所谓传地址是指把实在参数地址传递给对应形式参数。在过程段中每个形式参数都有一对应单元,称为形式单元。形式单元将用来存放对应实在参数地址。当调用一个过程时,调用段必须领先把实在参数地址传递到一个为被调用段能够拿得到地方。当程序控制转入被调用段之后,被调用段首先把实参地址捎进自己对应形式单元中,过程体对形式参数任何引用1或赋值都被处理成对形式单元间接访问。当调用段工作完成返回时,形式单元(它们都是指示器)所指实在参数单元就持有所指望值。2).传结果:和“传地址”相同(但不等价)另一个参数传递力法是所谓“传结果”。这种方法实质是,每个形式参数对应有两个申元,第1个单元存放实参地址,第2个单元存放实参值。在过程体中对形参任何引用或赋值都看成是对它第2个单元直接访问。但在过程工作完成返回前必须把第2个单元内容行放到第1个单元所指那个实参单元之中。3).传值:所谓传值,是一个简单参数传递方法。调用段把实在参数值计算出来并存放在一个被调用段能够拿得到地方。被调用段开始丁作时,首先把这些值抄入形式中元中,然后就好像使用局部名一样使用这些形式单元。假如实在参数不为指示器,那末,在被调用段中无法改变实参值。4).传名:所谓传名,是一个特殊形——实参数结合方式。解释“传名”参数意义:过程调用作用相当于把被调用段过程体抄到调用出现地方,但把其中任一出现形式参数都替换成对应实在参数(文字替换)。它与采取“传地址”或“传值”方式所产生结果均不相同。(a)2;(b)8;(c)7; (d)9。14对以下Pascal程序画出过程c第二次被激活时运行栈,控制链和访问链。说明在c中怎样访问变量x。programenv;

procedurea;

varx:integer;

procedureb;

procedurec;

beginx:=2;bend;{procedurec}

begincend;{procedureb}

beginbend;{procedurea}

beginaend.{main}

答:envenvcontrollinkaccesslinkcontrollinkaccesslinkaacontrollinkcontrollinkaccesslinkxaccesslinkxbbcontrolcontrollinkaccesslinkaccesslinkcccontrolcontrollinkaccesslinkaccesslinkbbcontrolcontrollinkaccesslinkaccesslinkccaccesslinkcontrollinkaccesslinkcontrollink说明:c中沿着存取链向前走两步,到过程a活动统计中就能够访问到变量x。15下面给出一个C语言程序及其在SPARC/SUN工作站上经某编译器编译后运行结果。从运行结果看,函数func中4个局部变量i1,j1,f1,e1地址间隔和它们类型大小是一致,而4个形式参数i,j,f,e地址间隔和它们类型大小不一致,试分析不一致原因。注意,输出数据是八进制。func(i,j,f,e)shorti,j;floatf,e;{shorti1,j1;floatf1,e1;printf("Addressofi,j,f,e=%o,%o,%o,%o\n",&i,&j,&f,&e);printf("Addressofi1,j1,f1,e1=%o,%o,%o,%o\n",&i1,&j1,&f1,&e1);printf("Sizesofshort,int,long,float,double=%d,%d,%d,%d,%d\n",sizeof(short),sizeof(int),sizeof(long),sizeof(float),sizeof(double));}main(){shorti,j;floatf,e;func(i,j,f,e);}运行结果是:Addressofi,j,f,e=,,,Addressofi1,j1,f1,e1=,,,Sizesofshort,int,long,float,double=2,4,4,4,8,请问为何?答:C语言编译器是不做实在参数和形式参数个数和类型是否一致检验,由程序员自己确保它们一致性。不过对于形式参数和实在参数是不一样整型(如一个是short型,另一个是long型),或者是不一样实型,编译器则试图确保目标代码运行时能得到正确结果,条件是,当需要高级别类型数据向低级别类型数据转换时,不出现溢出。这么,C编译器作约定是,当整型或实型数据作为实在参数时,分别将它们提升到long和double类型数据传递到被调用函数。被调用函数依照形式参数所申明类型,决定是否要将实在参数向低级别类型转换。低地址放高位高地址放低位shortlong图5.2长整型和短整型 在本例中,long低地址放高位高地址放低位shortlong图5.2长整型和短整型注意,对于SUN工作站来说,低地址存放整型数据高位。floatfloatdoublee图5.3双精度型和浮点型 对于实型来说。double类型是8个字节,而float类型4个字节。被调用函数把实在参数前4个字节作为自己所需数据,因为double后面4个字节内容都是为了增加精度用,见图5.3。ee,8个字节在main函数中参数压栈时观点在func函数中存取形式参数时观点4个字节,起始地址4个字节,起始地址2个字节,起始地址2个字节,起始地址f,8个字节j,4个字节i,4个字节栈增加方向图5.4参数在栈中情况 这么在main函数中依次将参数提升后反序进栈,大小分别为8,8,4,4。在func函数中,按形式参数类型,把这些存放单元一部分看成是形式参数存放单元,见图5.4。从这个图不难了解为何形式参数地址间隔和它们类型大小不一致了。 注意,现在编译器将需要进行类型转换形式参数(类型是char、short、float等)另行分配在局部数据区,当控制进入被调用过程时,首先将调用过程压栈需要进行类型转换实在参数取出,把它们存入所分配局部数据区存放单元,并同时完成必要数据类型转换。在这种情况下,不会出现本题所碰到现象。 另外,在SPARC工作站上,整型数据高位存放在低地址,而低位存放在高地址。假如是X86机器,数据高低位不是按这么次序存放,那也不会出现本题所碰到现象。 下面是某个编译器类型提升函数,供读者了解用(备注:int和long大小一样)。 Typepromote(Typety) { switch(ty->op){ caseENUM: returninttype; caseINT: if(ty->size<inttype->size) returninttype; break; caseUNSIGNED: if(ty->size<inttype->size) returninttype; break; caseFLOAT: if(ty->size<doubletype->size) returndoubletype; } returnty; }16试把以下C语言程序可执行语句翻译为

(a)一棵语法树,

(b)后缀式,

(c)三地址代码。main(){inti;inta[10];while(i<=10)a[i]=0;while}while答:(a).一棵语法树赋值表示式布尔表示式赋值表示式布尔表示式表示式表示式表示式数组元素表示式<=表示式数组元素表示式<=下标表示式110a0下标表示式110a011(b)后缀式为:i10<=ai[]0=while从理论上能够说while(i<=10)a[i]=0;后缀式如上面表示。但若这么表示,在执行while操作时,赋值语句已经执行,这显然与语义不符,所以改为: i10<=<下一个语句开始地址>BMai[]0=<本语句地址>BRL其中BM操作为当表示式为假时转向<下一个语句开始地址>,BRL是一个一目运算,无条件转向<本语句始址>。(c)三地址代码序列为:100ifi<=10got102101goto106102t1:=4*i103t2:=a104t2[t1]:=0105goto10010617 Pascal语言中,语句:forv:=initialtofinaldostmt 与以下代码序列有相同含义begint1:=initial;t2:=final;ift1<=t2thenbeginv:=t1;stmtwhilev<>t2dobeginv:=succ(v);stmtendendend(a)试考虑下述Pascal程序programforloop(input,output);vari,initial,final:integer;beginread(initial,final);fori:=initialtofinaldowrite(i)end对于initial=MAXINT-5和final=MAXINT,问此程序将做些什么?其中MAXINT为目标机器允许最大整数。(b)试结构一个翻译pascalfor语句为三地址代码语法制导定义。答:(a)程序将显示以下六个整数:MAXINT-5MAXINT-4MAXINT-3MAXINT-2MAXINT-1MAXINT(b)为简单起见,for语句三地址代码以下:t1:=initialt2:=finalift1>t2gotoS.nextv:=t1stmt.codeS.begin:ifv>t2gotoS.nextv:=succ(v)stmt.codegotoS.begin语法制导定义以下:产生式动作S→forEdoS1S.begin:=newlabelS.first:=newtempS.last:=newtempS.curr:=newtempS.code:=gen(S.first“:=”E.init)||gen(S.last“:=”E.final)||gen(“if”S.first“>”S.last“goto”S.next)||gen(S.curr“:=”S.first)||gen(S.begin“:”)||gen(“if”S.curr“>”S.Last“goto”S.next)||S1.code||gen(S.curr:=succ(S.curr))||gen(“goto”S.begin)E→v:=initialtofinalE.init:=initial.placeE.final:=final.place18 对于下面C语言文件s.c f1(intx) { longx; x=1; } f2(intx) { { longx; x=1; } }某编译器编译时报错以下: s.c:Infunction‘f1’: s.c:3:warning:declarationof‘x’shadowsaparameter请回答,对函数f2为何没有类似警告错误。答: 对于函数f1,局部变量x申明作用域是整个函数体,造成在函数体中不可能访问形式参数x。因为这是一个正当C语言函数,所以编译器给出警告错误。对于函数f2,因为局部变量x作用域只是函数体一部分,不会出现上述问题,因而编译器不报错。19 考虑一个简单语言,其中全部变量都是整型(不需要显式申明),而且仅包含赋值语句、读语句和写语句。下面产生式定义了该语言语法(其中lit表示整型常量;OP产生式没有给出,因为它和下面讨论问题无关)。 Program StmtList StmtList StmtStmtList|Stmt Stmt id:=Exp;|read(id);|write(Exp); Exp id|lit|ExpOPExp 我们把不影响write语句输出值赋值(包含经过read语句来赋值)称为无用赋值,写一个语法指导定义,它确定一个程序中出现过赋予无用值变量集合(不需要知道无用赋值位置)和没有置初值变量集合(不影响write语句输出值未置初值变量不在考虑之中)。 非终止符StmtList和Stmt用下面3个属性(你依照需要来定义其它文法符号属性): (1)uses_in:在本语句表或语句入口点引用变量集合,它们值影响在该程序点后输出。 (2)uses_out:在本语句表或语句出口点引用变量集合,它们值影响在该程序点后输出。 (3)useless:本语句表或语句中出现无用赋值变量集合。答:Exp属性uses表示它引用变量集合。Programuseless和no_initial分别表示程序无用赋值变量集合和未置初值变量集合。 Program StmtList StmtList.uses_out:=; Program.useless:=StmtList.useless; Program.no_initial:=StmtList.uses_in; StmtList StmtStmtList1 StmtList1.uses_out:=StmtList.uses_out; Stmt.uses_out:=StmtList1.uses_in; StmtList.uses_in:=Stmt.uses_in StmtList.useless:=StmtList1.uselessStmt.useless; StmtList Stmt Stmt.uses_out:=StmlList.uses_out; StmlList.uses_in:=Stmt.uses_in; StmtList.useless:=Stmt.useless Stmt id:=Exp; Stmt.useless:=ifid.lexemeStmt.uses_outthenelse{id.lexeme}; Stmt.uses_in:=ifid.lexemeStmt.uses_out then(Stmt.uses_out–{id.lexeme})Exp.useselseStmt.uses_out Stmt read(id); Stmt.useless:=ifid.lexemeStmt.uses_outthenelse{id.lexeme}; Stmt.uses_in:=Stmt.uses_out–{id.lexeme} Stmt write(Exp); Stmt.useless:=,Stmt.uses_in:=Stmt.uses_outExp.uses Exp id Exp.uses:={id.lexeme} Exp lit Exp.uses:= Exp Exp1OPExp2 Exp.uses:=Exp1.usesExp2.uses20为以下C程序生成目标代码。

main()

{

inti;

inta[10];

while(i<=10)

a[i]=0;

}答:21试结构下面程序流图,并找出其中全部回边及循环。

readP

x:=1

c:=P*P

ifc<100gotoL1

B:=P*P

x:=x+1

B:=B+x

writex

halt

L1:B:=10

x:=x+2

B:=B+x

writeB

ifB<100gotoL2

halt

L2:x:=x+1

gotoL1答:程序流图以下

22试求出以下四元式程序中循环并进行循环优化.I:=1readJ,KL:A:=K*IB:=J*IC:=A*BwriteCI:=I+1ifI<100gotoLhalt答:把本题三地址代码划分成基本块并画出其程序流图显示在图9.4(1)中,其中有三个基本块B1,B2,B3,有一条回边B2->B2,对应循环是{B2}。(1)代码外提:因为循环中没有不变运算,故不做此项优化(2)强度减弱:B2中A和B都是I归纳变量。优化结果显示在图9.4(2)中。(3)删除归纳变量:变换循环控制条件,删除归纳变量I后流图显示在图9.4(3)中23考虑下面三地址语句序列: b:=1 b:=2 ifw<=xgotoL2 e:=b gotoL2 L1: gotoL3 L2: c:=3 b:=4 c:=6 L3: ify<=zgotoL4 gotoL5 L4: g:=g+1 h:=8 gotoL1 L5: h:=9(1)在该代码中用水平横线将代码分成基本块,并给每个基本块一个序号。 (2)画出该代码控制流图,每个基本块就用(1)序号表示。 (3)若有循环话,列出组成每个循环结点。答:(1) (2)114237865 b:=1 b:=2 ifw<=xgotoL2 (1) e:=b gotoL2 (2) L1: gotoL3 (3) L2: c:=3 b:=4 c:=6 (4) L3: ify<=zgotoL4 (5) gotoL5 (6) L4: g:=g+1 h:=8 gotoL1 (7) L5: h:=9 (8)结点5、7和3组成一个循环,其中5是入口结点。24对下面程序片段作出其程序流图并计算:

(1)各基本块抵达_定值集IN[B];

(2)各基本块中各变量引用点ud链;

(3)各基本块出口活跃变量集V_OUT[B];

(4)各基本块中变量定值点du链。

I:=1

J:=0

L1:J:=J+I

readI

ifI<100gotoL2

writeJ

halt

L2:I:=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}00110100B2{d3,d4}00110000{d1,d2,d6}11000100B3{d6}00000100{d1,d4}10010000B4{}00000000{}00000000

求各基本块抵达-定值初值及各遍执行结果显示在表9.6(2)中。表9.6(2)基本块初值第一遍后第二遍后第三遍后IN[B]OUT[B]IN[B]OUT[B]IN[B]OUT[B]IN[B]OUT[B]B10000000011000000000000001100000000000000110000000000000011000000B20000000000110000110001000011000011100100001100001110010000110000B30000000000000100001100000010010000110000001001000011000000100100B40000000000000000001100000011000000110000001100000011000000110000(2)求各基本块中各变量引用点ud链:

假设在程序中某点u引用了变量a,则把能抵达ua全部定值点,称为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在引用点d3ud链是{d1,d6};J在引用点d3ud链是{d2,d3}。

在B2中I引用点d5前面有I定值点d4,且在d4定值后抵达d5,所以I在引用点d5ud链是{d4}。

B3中I引用点d6前面没有I定值点,其ud链是IN[B3]中I全部定值点,所以是{d4}。

B4中J引用点d8前面没有对J定值点,其ud链是IN[B4]中J全部定值点。已知IN[B4]={

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论