编译原理第三版答案

 

点此下载

 

 

第一章

1.典型的编译程序在逻辑功能上由哪几部分组成?

答:编译程序主要由以下几个部分组成:词法分析、语法分析、语义分析、中间代码生成、中间代码优化、目标代码生成、错误处理、表格管理。

2. 实现编译程序的主要方法有哪些?

答:主要有:转换法、移植法、自展法、自动生成法。

3. 将用户使用高级语言编写的程序翻译为可直接执行的机器语言程序有哪几种主要的方式?

答:编译法、解释法。

4. 编译方式和解释方式的根本区别是什么?

答:编译方式:是将源程序经编译得到可执行文件后,就可脱离源程序和编译程序单独执行,所以编译方式的效率高,执行速度快;

解释方式:在执行时,必须源程序和解释程序同时参与才能运行,其不产生可执行程序文件,效率低,执行速度慢。

 

 

 

第二章

 

  1. 乔姆斯基文法体系中将文法分为哪几类?文法的分类同程序设计语言的设计与实现关系如何?

答: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}

答:

  1. SàAB

AàaAb | ab

BàcB | e

  1. SàASb |ab

Aàa | e

  1. SàaSd | 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;同时检查源程序中的词法错误。

  1. 试分析分隔符(空格、跳格及回车等)对词法分析的影响。

答:空格、跳格、回车等分隔符号对词法分析不起作用,可以删除。但是回车符号可以用于错误定位,所以在删除回车符号前需要统计回车的个数。

  1. 给出识别C语言全部实型常数的自动机。

答:(+|-|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集。
  2. 该文法是否为LL(1)文法?为什么?

答:(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]等价的LL文法G’[A]。
  2. 构造G’[A]的LL(1)分析表并给出输入串aade#的分析过程。

答:(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)文法。

  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中有效的标识符。

 

 

第七章

  1. 将算术表达式 (a+b)*(c+d)-(a+b+c) 翻译成四元式序列。
  2. 将下列语句翻译成四元式序列:
    1. IF  x>0  THEN x:=0 ELSE x:=1
    2. WHILE  x>0  DO  x:=x-1
    3. IF x>0  THEN  x:=x+1  ELSE

IF x <0  THEN  x:=x+1  ELSE x:=x+1

    1. WHILE x > 0 DO

WHILE y > 0 DO

BEGIN y:=y-x; x:=x-1 END

  1. 给出如下程序段的四元式序列。(四元式的操作符可用自身代替)。其中A:Array of [1..10] of  integer。

  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. 试将FOR语句翻译成四元式序列。
  2. 试将UNTIL语句翻译成四元式序列。
  3. 试将CASE语句翻译成四元式序列。
  4. 试给出4、5、6题中翻译过程的语法制导程序。

 

 

第八章

1. 将下面的程序段划分为基本块并画出其程序流图。

         read(A);

         read(B);

         F:=1;

         C:=A*A;

         D:=B*B;

         if C<D goto L1;

         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

的目标代码,其中变量均为非形参实型变量。

  • 试为FOR循环语句设计目标代码。
  • 试为REPEAT循环语句设计目标代码。
  • 试为CASE语句设计目标代码。

 

 

      

 

 

 

  • 20
    点赞
  • 134
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值