搜档网
当前位置:搜档网 › 编译原理课后习题答案

编译原理课后习题答案

编译原理课后习题答案
编译原理课后习题答案

第一章

1.解答:

程序设计语言:程序设计语言是遵守一定规范的、描述“计算”(Computing)过程的形式语言。一般可以划分为低级语言和高级语言两大类。低级语言是面向机器的语言,它是为特定的计算机系统设计的语言,机器指令、汇编语言是低级语言。高级语言是与具体计算机无关的“通用”语言,它更接近于人类的自然语言和数学表示,例如FORTRAN、Pascal、C等等我们熟悉的语言是高级语言。

语言处理程序:由于目前的计算机只能理解和执行机器语言,因此必须有一个程序将用程序设计语言书写的程序等价(执行效果完全一致)地转换为计算机能直接执行的形式,完成这一工作的程序称为“语言处理程序”。它一般可分为解释程序和翻译程序两大类。

翻译程序:翻译程序(Translator)是一种语言处理程序,它将输入的用程序设计语言书写的程序(称为源程序)转换为等价的用另一种语言书写的程序(称为目标程序)。若源语言是汇编语言,目标程序是机器语言,称这种翻译程序为汇编程序。若源语言是高级语言,目标程序是低级语言,称这种翻译程序为编译程序。

解释程序:解释程序(Interpreter)是一种语言处理程序,它对源程序逐个语句地进行分析,根据每个语句的含义执行语句指定的功能。

2.解答:

编译程序的总框图见图1.2。其中词法分析器,又称扫描器,它接受输入的源程序,对源程序进行词法分析,识别出一个个的单词符号,其输出结果是单词符号。

语法分析器,对单词符号串进行语法分析(根据语法规则进行推导或归约),识别出程序中的各类语法单位,最终判断输入串是否构成语法上正确的“程序”。

语义分析及中间代码产生器,按照语义规则对语法分析器归约出(或推导出)的语法单位进行语义分析并把它们翻译成一定形式的中间代码。编译程序可以根据不同的需要选择不同的中间代码形式,有的编译程序甚至没有中间代码形式,而直接生成目标代码。

优化器对中间代码进行优化处理。一般最初生成的中间代码执行效率都比较低,因此要做中间代码的优化,其过程实际上是对中间代码进行等价替换,使程序在执行时能更快,并占用更小的空间。

目标代码生成器把中间代码翻译成目标程序。中间代码一般是一种机器无关的表示形式,只有把它再翻译成与机器硬件直接相关的机器能识别的语言,即目标程序,才能在机器上运行。

表格管理模块保持一系列的表格,登记源程序的各类信息和编译各阶段的进展状况。编译程序各个阶段所产生的中间结果都记录在表格中,所需要的信息也大多从表格中获取,整个编译过程都在不断地和表格打交道。

出错处理程序对出现在源程序中的错误进行处理。如果源程序有错误,编译程序应设法发现错误,把有关错误信息报告

给用户。编译程序的各个阶段都有可能发现错误,出错处理程序要对发现的错误进行处理、记录,并反映给用户

Chapter 2

1.试写出V T={0,1}上下述集合的正则表达式:

⑴所有以1开始和结束的符号串。

⑵恰含有3个1的所有符号所组成的集合。

⑶集合{01,1}。

⑷所有以111结束的符号串。

解答:⑴1(0|1)*1|1

⑵0*10*10*10*

⑶01|1

⑷(0|1)*111

2.⑴试写出非负整数集的正则表达式。⑵试写出以非5数字为头的所有非负整数集的正则表达式。

解答:⑴0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*

⑵0|(1|2|3|4|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*

3.试将2.8中所示的有限状态自动机M最小化。

分析:只能对确定的有限状态自动机进行最小化,本题的自动机已经是确定的。

最小化采用状态分离法,具体做法如下:

①进行0等价类的划分:Q划分为Q f与Q-Q f

②若已进行了k等价划分,即Q已被划分成(Q1,Q2,…Q n),再进行k+1划分,对Q i(i=1…n),若q、q’∈Q i,使得对某一个a∈V T,δ(q,a)∈Q j和δ(q’,a)∈Q l,j≠l或δ(q,a)存在而δ(q’,a)不存在或反之。则将Q i划分为二个子集Q i1,Q i2,使q∈Q i1,q’ ∈Q i2。

③重复②直至无法进一步划分为止。对最后划分得到的状态子集中每一个子集,选择该子集中任何一个状态作为该状态子集的代表,然后修改原来的有限状态自动机的状态转换函数δ,凡在δ作用下转向某状态子集中任何一个状态的一律改成转向该状态子集的代表。若一个状态子集中某一状态是原来的开始状态,则该状态子集的代表就是新的有限状态自动机的开始状态。同理,若一个状态子集中的状态均是最终状态,则该状态子集的代表就是新的有限状态自动机的最终状态。

④抹去可能存在的无用状态与不可及状态。

解答:此有限状态自动机的状态转换表如表3.1所示:

表2.1 M的状态转换表

由此看出:此有限状态自动机是确定的。

最小化:

初始划分由2个子集组成,即:({A,B,C},{D,E,F,G})

集合{D,E,F,G}不需要进一步划分,考察子集{A,B,C}。由于

δ(B,a)=D∈{D,E,F,G},而δ(A,a)=δ(C,a)=B∈{A,BC},

因此Q可进一步划分为:({A,C},{B},{D,E,F,G})。由于

δ(A,b)=C∈{A,C},而δ(C,b)=E∈{D,E,F,G}。

因此Q可进一步划分为:({A},{C},{B},{D,E,F,G})。

这时不能再划分了,得到的最小化的有限状态自动机如表3.2所示:

表2.2 最小化的有限状态自动机

4.某程序语言的无(正负)符号常数可以用下面正则表达式R来表示:

(D+E|D+.D+E|E|.D+E)((+|-)D|D)D*|D+|D*.D+

⑴试把它转换成确定性有限状态自动机。

⑵把上述有限状态自动机最小化。

⑶在上述有限状态自动机中添加相应动作,取出无(正负)符号常数。

分析:从正则表达式构造有限状态自动机可以分两步进行。

①画一条从结点X到结点Y的有向弧,有向弧上标以正则表达式R。结点X为标以“-”的初始状态,结点Y为标以“+”的最终状态。从这一有向图出发反复应用图3.2所示的替代规则,直至所有有向弧都以V T中的符号或标记ε为止。

图2.2 3条替代规则

②消除应用①所得到的传递图中的ε弧,可以分为两步:首先消除ε环路,其次消除其他ε弧。

a) ε环路的消除方法:

i.将ε环路的诸项合并为一个顶点。

ii.修改各个相关的有向弧。

iii.若ε环路中某一状态是最终(或初始)状态,则新顶点是最终(或初始)状态。

b)其它ε弧的消除有两种方法:

1)子集法:即计算ε-Closure(T),其表示从状态集T中任何一状态沿ε弧可以到达的状态全体。

其要点是:从初始状态q0的X=ε-Closure(q0)开始,按如下方法构造状态集:

i.令Set={X};

ii.若Set中还有未考察过的状态子集X i,则对于每一输入符号a∈V T,求T=ε-Closure(move(X i,a)),Set=Set∪{T}(其中move(X i,a)={q|q∈δ(p,a),p∈X i})。重复执行(2),直至不存在这样的X i。这样得到的Set即为消除ε弧后的确定的有限状态机(DFA)。DFA的初始状态就是ε-Closure(q0),最终状态由那些至少含有一个最终状态的状态子集组成。

2)逐步消除法:

其要点是找到类似于图2.3所示,但从B再无ε弧引出的ε弧。

图2.3 逐步消除法

删除状态A到状态B的ε弧,对每一条从状态B到状态C标记为a i的弧,增加1条从状态A到状态C标记为a i的弧。若B

是最终状态,则让A为最终状态。重复上述过程直至消除全部的ε弧,这样得到的一般是不确定的有限状态自动机(NFA)。解答:⑴图3.4给出了从正则表达式R构造有限状态自动机M的过程。

图2.4替代规则的应用过程

应用子集法消除?弧:

ε-Closure(x)={x,2},令A1={x,2},计算:

ε-Closure(move(A1,D))=ε-Closure({7,10,2,1})={7,10,2,1,y}

ε-Closure(move(A1,·))=ε-Closure({5,3})={5,3}

ε-Closure(move(A1,E))=ε-Closure({4})={4}

令A2={7,10,2,1,y},A3={5,3},A4={4},计算:

ε-Closure(move(A2,D))={7,10,2,1,y}

ε-Closure(move(A2,·))={8,3}

ε-Closure(move(A2,E))={4}

ε-Closure(move(A3,D))={5,6,3,y}

ε-Closure(move(A4,D))={12,y}

ε-Closure(move(A4,+))={11}

ε-Closure(move(A4,-))={11}

令A5={8,3},A6={5,6,3,y},A7={12,y},A8={11},计算:

ε-Closure(move(A5,D)={8,9,3,y}

ε-Closure(move(A6,D)={5,6,3,y}

ε-Closure(move(A6,E)={4}

ε-Closure(move(A7,D)={12,y}

ε-Closure(move(A8,D)={12,y}

令A9={8,9,3,y},计算:

ε-Closure(move(A9,D)={8,9,3,y}

ε-Closure(move(A9,E)={4}

得到的DFA M’的初始状态是A1,最终状态集由A2,A6,A7,A9组成。

图2.5是M’的状态转换图,M’的状态转换表如表2.3所示。

表2.3 M’的状态转换表

图2.5 M’的状态转换图

⑵采用状态分离法:

初始时分成2个子集,即:({A1,A3,A4,A5,A8},{A2,A6,A7,A9})

考察子集{ A2,A6,A7,A9},它进一步可分成:({A6,A9},{A2},{A7})

考察子集{ A1,A3,A4,A5,A8},它进一步分成:({A4},{A1},{A8},{A3,A5})

不能再进一步划分了,得到的最小化的有限状态自动机如图2.6所示:

图2.6 最小化的有限状态自动机

⑶由于数的表示和具体的机器有着内在联系,这里仅将此无(正负)符号常数的十进制数部分和指数部分分别存入2个工作

单元。设立下述工作单元:

此常数的十进制数部分 number

此常数的指数部分 exp

小数点位数 n

此常数指数部分正负号 expsign

这4个工作单元进入有限状态自动机的模拟程序时被初始化为0。

函数过程getchar,其功能是读入下一个字符到工作单元char中。

函数过程value,其功能是求出存放在工作单元char中数字字符的值。

经过加工后的状态矩阵如表2.4所示:

表2.4 加工后的状态矩阵

矩阵中元素A1,A2,….,A7表示应该转换的下一个状态。#1,#2,….,#12表示应该执行的语义子程序。各语义子程序的代码归结如下:

#1:number:=value(char);getchar;

#2:getchar;

#3:number:=number*10+value(char);getchar;

#4:n:=n+1; number:=number*10+value(char);getchar;

#5:expsign:=1;exp:=value(char);getchar;

#6:expsign:=1;getchar;

#7:expsign=-1;getchar;

#8:exp:=exp*10+value(char);getchar;

#9:exp:=value(char);getchar;

#10:按硬件要求构造无(正负)符号数;

#11:exp:=-n; 按硬件要求构造无(正负)符号数;

#12:if expsign=-1 then exp:=-exp;exp=exp-n; 按硬件要求构造无(正负)符号数;

5.设要识别的单词有限集是{STEP,SWITCH,STRING},相应正则表达式是STEP|SWITCH|STRING,试把它转换成确定性有限

状态自动机。

解答:

6.设VT={a,b},试构造下述正则表达式的确定性有限状态自动机:

⑴a(a|b)*baa

⑵(a|b)*bbb*

解答:⑴由此正则表达式构造的有限状态自动机M1的状态转换图如图2.7所示:

图2.7 有限状态自动机M1的转换图

确定化(表3.5):

表3.5 M1的确定化

对应的状态转换图如图3.8所示:

图2.8 DFA M1的状态转换图⑵由正则表达式构造的有限状态自动机M2的状态转换图如图2.9所示:

图2.9 M2的状态图

确定化(表2.6):

表2.6 M2的确定化

对应的状态转换图如图2.10所示:

图2.10 DFA M2的状态转换图9.对于下列的状态转换矩阵:

⑴ 分别画出相应的状态转换图。

⑵ 用自然语言分别描述它们所识别的输入串的特征。

解答:⑴表1所对应的状态转换图如图2.11所示:

图2.11 表3.6对应的状态转换图

表2所对应的状态转换图如图2.12所示:

图2.12 表3.7对应的状态转换图

⑵表1所识别的输入串是:以b*aa*b开头的后接任意多个a或b的{a,b}上的字符串。表2所识别的输入串是:仅含有一个a的{a,b}上的字符串。

10. 将习题图2.1所示的非确定的有限状态自动机确定化和最小化。

习题图2.1 非确定的有限状态自动机M

解答:确定化(表2.8):

表2.8 M的确定化

令B=[B,C]对应的状态转换图如图2.14所示:

图2.14 DFA M的状态转换图

确定化的M已是最小化的。

11.消除传递图T(习题图2.2)中的 ε 弧。

习题图2.2传递图T

解答:i)先消除ε环路,合并状态2和3,得到的传递图T’如图3.16所示:

图2.16 消除?环路的传递图T’

ii)采用逐步消除法去除其他ε弧,最终得到的传递图T’’如图2.17所示:

图2.17 消除所有ε弧的传递图

Chapter 3

2.设有文法G1[]:

|

试写出028和4321的最左推导和最右推导过程。

分析:在每一步的推导中,都是对最左的那个非终结符用相应的产生式的右部来替换,这样的推导称为最左推导。类似地,如果每一步的推导中都是对最右的那个非终结符用相应的产生式的右部来替换,这样的推导称为最右推导,最右推导又称规范推导。

解答:028的最左推导:

?????0?02?028

028的最右推导:

???8?8?28?28?028

4321的最左推导:

??????4?43?432?4321 4321的最右推导:

???1?1?21?21?321?321?4321

3.证明文法G[]是二义性文法:

→ifthenelse|ifthen|s

→0|1

分析:只要找出该文法的一个二义性句子即可证明。

解答:句子if 0 then if 1 then s else s 对应如下两棵不同的推导树:

图3.1 句子if 0 then if 1 then s else s的推导树(1)

图3.1 句子if 0 then if 1 then s else s的推导树(2)

4.设有文法G[]:

-|

/|

→i|()

⑴试写出i/(i-i-i)的推导树。

⑵试写出(-i)/的短语、简单短语和句柄。

分析:只要给出句型(句子)对应的推导树就容易求出短语、简单短语和句柄。

解答:⑴ i/(i-i-i)的推导树如下:

图3.3 句子i/(i-i-i)的推导树⑵(-i)/的推导树如下:

图3.4 句子(-i)/的推导树短语:,i,-i,(-i),(-i)/

简单短语:,i

句柄:

5.对布尔矩阵

求B+。

解答:利用Warshall算法求解的结果如下:

7.对表结构语言G[]:

→a|∧|()

,|

⑴试给出(a,(a,a))的最左和最右推导。

⑵指出(((a,a),∧,(a)),a)的最右推导,以及规约的每一步的句柄。

⑶给出(((a,a),∧,(a)),a)的推导树自下而上的构造过程。

分析:本题是要让读者明确,自下而上构造推导树的过程是最右推导(规范推导)的逆过程,这一过程正是自底向上句法分析的过程,其要点是找句柄、归约。

解答:⑴句子(a,(a,a))的最左推导为:

?()?(,)?(,)?(a,)?(a,())?(a,(,))?(a,(,)?(a,(a ,)?(a,(a,a))

最右推导为:

?()?(,)?(,())?(,(,))?(,(,a))?(,(,a))?(, (a,a))?(,(a,a))?(a,(a,a)) ⑵句子(((a,a),∧,(a)),a)的最右推导及归约的每一步句柄如表3.1所示:

表3.1 句子(((a,a),∧,(a)),a)的最右推导过程

⑶句子(((a,a),∧,(a)),a)的推导树如图3.5所示:

图3.5 句子(((a,a),∧,(a)),a)的推导树

构造过程如图3.6所示:

图3.6 句子(((a,a),∧,(a)),a)的推导树自下而上的构造过程

Chapter 4(略)

Chapter 5

1.考察算术表达式翻译文法T1:

T1=({+,*,(,),C},{,,

},{C,ADD,MUL},R,)

其中R由下面规则组成:

+,ADD

,

*

,

MUL

,

→(),

→C,C

其相应输入文法是LR(1)。试对该输入文法的下推自动机控制表作适当改动,构造翻译下推自动机的控制表,使该翻译下推自动机把任何一个由C,+,*组成的中缀表达式翻译成后缀表达式。

分析:设翻译文法中的翻译规则形如:→x,y

把自底向上的下推自动机改造成相应的下推翻译自动机的方法很简单:只需规定,当下推自动机应用产生式i进行规约的同时,输出y中的输出符号。

解答:输入文法的LR(1)状态集如表5.1。

表5.1 输入文法的LR(1)状态集

翻译下推自动机的控制表如表5.2所示:

表5.2 翻译下推自动机的控制表

2.考察下述文法G[]:

→i:=

+

*

→()

→i

试写出各产生式的语义子程序。

解答:让非终结符带有属性.type指出数据类型,属性.val存放运算结果。→i:=

{if i.type=.type then

GEN(:=,.val,i.val);

else if i.type=real AND .type=int then

begin

T:=NEWTEMP;

GEN(float,.val,T);

GEN(:=,T,i.val);

end.

else if i.type=int AND .type=real then

begin

T:=NEWTEMP;

GEN(int,.val,T);

GEN(:=,T,i.val);

end.

else error.

}

→E1>+

{.val:=NEWTEMP;

if .type=int AND .type=int then

begin

.type:=int;

GEN(int+,.val, .val,.val);

end.

else if .type=real AND .type=real then

begin

.type:=real;

GEN(real+,.val, .val,.val);

end.

else if .type=int AND .type=real then

begin

.type:=real;

T:=NEWTEMP;

GEN(float, .val,T);

GEN(real+,T, .val,.val);

end.

else if .type=real AND .type=int then

begin

.type:=real;

T:=NEWTEMP;

GEN(float, .val,T);

GEN(real+, .val,T,.val);

end.

else error.

}

*

{.val:=NEWTEMP;

if .type=int AND .type=int then

begin

.type:=int;

GEN(int*,.val, .val,.val);

end.

else if .type=real AND .type=real then

begin

.type:=real;

GEN(real*,.val, .val,.val);

end.

else if .type=int AND .type=real then

begin

.type:=real;

T:=NEWTEMP;

GEN(float, .val,T);

GEN(real*,T, .val,.val);

end.

else if .type=real AND .type=int then

begin

.type:=real;

T:=NEWTEMP;

GEN(float, .val,T);

GEN(real*, .val,T,.val);

end.

else error.

}

→()

{.val:= .val;

.type:= .type;

}

→i

{.val:= i.val;

.type:=i.type;

}

Chapter 6(略)

Chapter 7

1.考察下面程序段:

procedure p(x,y,z)

begin

y:=y+1;

z:=z+x;

end;

begin

a:=2;

b:=3;

p(a+b,a,a);

write(a);

end;

若参数通信分别是:

⑴按名

⑵按值

方式,上述程序执行后,输出a的值分别是多少?

解答:⑴按名调用的特点是:在被调用过程执行时,用实参替换形参,然后执行替换后的程序,因此本程序相当于执行如下程序段:

a:=2;

b:=3;

a:=a+1;

a:=a+a+b;

输出a的值是9。

⑵按值调用的特点是:传送的是实在参数的当时值,该值成为形参的初值,是一种单向的行为,它并不改变实参的值。所以a的值不变,仍是2。

2.考察下面C程序:

main()

int …;

P1(…)

{ …

P2(…);

}

P2(…)

{ …

P3(…);

}

P3(…)

{ … }

{ …

P1(…);

}

试说明,该程序执行时,运行栈中调用记录的变化情况。

解答:程序流进入过程P1时,栈空间中各调用记录的布局如图7.2所示。

图7.2 程序流进入过程P1时各调用记录的布局

程序流进入过程P2时,栈空间中各调用记录的布局如图7.3所示。

图7.3 程序流进入过程P2时各调用记录的布局

程序流进入过程P3时,栈空间中各调用记录的布局如图7.4所示。

图7.4 程序流进入过程P3时各调用记录的布局

3.下标变量地址计算可以采用另一种方法:直接生成计算下标变量地址的中间代码。考察下述和下标变量有关的产生式:

→i[

1,

]

试写出相应求下标变量地址的语义子程序。

解答:由于在处理数组定义时,已经将数组的维数n,每一维的上下界Ui、Li,长度di以及数组元素存贮首地址stp,address(a[0,…,0])均存放在数组的信息向量表中。为得到这些数据,用属性id.dim表示数组的维数,函数limit(id,j)返回d j,函数getaddr(id)返回假头地址address(a[0,…,0]),过程Mark_indirect(T)表示在T中添加间址标记。

各产生式的语义子程序为:

→i[

{.dim:=1;

.array:=i.array;/* i.array表示数组名*/

.val:=.val;

}

1,

{.dim:= 1.dim+1;

D:=Newtemp;

GEN(*,1.val,limit(.array,.dim),D);

GEN(+,D,.val,D);

.val:=D;

.array:= 1.array;

}

]

{Checkdim(.dim,.array.dim);/*检查维数的正确性*/

L:=Newtemp;

GEN(+,getaddr(.array),.val,L);

Mark_indirect(L);

.val:=L;

}

4.过程语句:

→call i()

1,

的中间代码采用下面形式:

(call,i.VAL,.VAL,…,.VAL)

试写出生成上述形式的中间代码的语义子程序。

解答:让带有属性:.que(队头)和.tail(队尾)。

#1的语义子程序为:

fetch(.que, .tail);

Gen(call,i.V AL,.VAL,…,.VAL);

#2的语义子程序为:

.que= 1.que;

.tail= 1.tail;

Append(.tail,.val);

#3的语义子程序为:

MakeQueue(.que, .tail);

Append(.tail,.val);

5. 考察下面Pascal程序:

Program P(input,output);

var a,b:integer;

c1:array[1…10] of real;

Procedure f1(x,y:integer);

var d,e:integer;

c2:arr ay[1…20] of real;

Procedure f2;

var u,v:real;

begin

end;

begin

f2;

end;

Procedure f3;

var h1,h2:integer;

begin

f1(h1,h2);

end;

begin

f3;

end.

⑴给出程序流进入过程f1和f2时区头地址表的内容。

⑵给出程序流进入f2时运行栈中的主要内容。

解答:本题中过程的嵌套和调用关系可示意性地由图7.5表示。

图7.5 过程的嵌套和调用关系⑴当程序流进入f1时,区头地址表的内容有以下两项:

当程序流进入f2时,区头地址表的内容有以下三项:

(2)程序流进入f2时,运行栈的主要内容如图7.6所示。

图7.6 程序流进入f2时运行栈的情形

Chapter 8

1.考察下述文法G[]:

→i:=

+

*

→()

→i

试写出各产生式的语义子程序。

解答:让非终结符带有属性.type指出数据类型,属性.val存放运算结果。→i:=

{if i.type=.type then

GEN(:=,.val,i.val);

else if i.type=real AND .type=int then

begin

T:=NEWTEMP;

GEN(float,.val,T);

GEN(:=,T,i.val);

end.

else if i.type=int AND .type=real then

begin

T:=NEWTEMP;

GEN(int,.val,T);

GEN(:=,T,i.val);

end.

else error.

编译原理课后习题答案(第三版)

精品文档 第二章 P36-6 (1) L G ()1是0~9组成的数字串 (2) 最左推导: N ND NDD NDDD DDDD DDD DD D N ND DD D N ND NDD DDD DD D ??????????????????0010120127334 556568 最右推导: N ND N ND N ND N D N ND N D N ND N ND N D ??????????????????77272712712701274434 886868568 P36-7 G(S) O N O D N S O AO A AD N →→→→→1357924680||||||||||| P36-8 文法: E T E T E T T F T F T F F E i →+-→→|||*|/()| 最左推导: E E T T T F T i T i T F i F F i i F i i i E T T F F F i F i E i E T i T T i F T i i T i i F i i i ?+?+?+?+?+?+?+?+??????+?+?+?+?+?+********()*()*()*()*()*()*() 最右推导: E E T E T F E T i E F i E i i T i i F i i i i i E T F T F F F E F E T F E F F E i F T i F F i F i i i i i ?+?+?+?+?+?+?+?+?????+?+?+?+?+?+?+**********()*()*()*()*()*()*()*() 语法树:/********************************

编译原理期末考试习题及答案

一、填空题|(每题4分,共20分) 1. 乔母斯基定义的3型文法(线性文法)产生式形式 A→Ba|a,或A→aB|a,A,B∈Vn, a,b∈Vt 。 2.语法分析程序的输入是单词符号,其输出是语法单位。 3 型为 B → .aB 的LR(0)项目被称为移进项目,型为 B → a.B 的LR(0) 项目被称为待约项目, 4.在属性文法中文法符号的两种属性分别为继承属性和综合属性。 5、运行时存贮管理方案有静态存储分配、动态存储分配和堆式存储分配和方案。 二.已知文法 G(S) (1) E → T | E+T (2) T → F | F*F (3) F →(E)| i (1)写出句型(T*F+i)的最右推到并画出语法树。(4分) (2)写出上述句型的短语,直接短语和句柄。(4分) 答:(1)最右推到(2分) E ==> T ==> F ==> (E) ==> (E+T) ==> (E+F) ==> (E+i) ==> (T+i) ==> (T*F+i) (2) 语法树(2分) (3)(4分) 短语:(T*F+i),T*F+i ,T*F , i 直接短语:T*F , i 句柄:T*F 三. 证明文法G(S) :S → SaS |ε是二义的。(6分) 答:句子aaa对应的两颗语法树为:

因此,文法是二义文法 四.给定正规文法G(S): (1) S → Sa | Ab |b (2) A → Sa 请构造与之等价的DFA。(6分) 答:对应的NFA为:(6分) 状态转换表: a b {F} Φ{S} {S} {S,A} Φ {S,A} {S,A} {S} 五. 构造识别正规语言b*a(bb*a)*b* 最小的DFA(要求写出求解过程)。(15分)答:(1)对应的NFA(5分) a b {0} {1,3} {0} {1,3} Φ{2,3} {2,3} {1,3} {2,3} (5分) 六. 已知文法G(S) : (1) S → ^ | a | (T) (2) T → T,S | S 试:(1)消除文法的左递归;(4分) (2)构造相应的first 和 follow 集合。(6分) 答:(1)消除文法的左递归后文法 G’(S)为: (1) S → ^ | a | (T)

编译原理教程课后习题答案——第六章

第六章运行时存储空间组织 6.1 完成下列选择题: (1) 过程的DISPLAY表中记录了。 a. 过程的连接数据 b. 过程的嵌套层次 c. 过程的返回地址 d. 过程的入口地址 (2) 过程P1调用P2时,连接数据不包含。 a. 嵌套层次显示表 b. 老SP c. 返回地址 d. 全局DISPLAY地址 (3) 堆式动态分配申请和释放存储空间遵守原则。 a. 先请先放 b. 先请后放 c. 后请先放 d. 任意 (4) 栈式动态分配与管理在过程返回时应做的工作有。 a. 保护SP b. 恢复SP c. 保护TOP d. 恢复TOP (5) 如果活动记录中没有DISPLAY表,则说明。 a. 程序中不允许有递归定义的过程 b. 程序中不允许有嵌套定义的过程 c. 程序中既不允许有嵌套定义的过程,也不允许有递归定义的过程 d. 程序中允许有递归定义的过程,也允许有嵌套定义的过程 【解答】 (1) b (2) a (3) d (4) b (5) b 6.2 何谓嵌套过程语言运行时的DISPLAY表?它的作用是什么? 【解答】当过程定义允许嵌套时,一个过程在运行中应能够引用在静态定义时包围它的任一外层过程所定义的变量或数组。也就是说,在栈式动态存储分配方式下的运行中,一个过程Q可能引用它的任一外层过程P的最新活动记录中的某些数据。因此,过程Q运行时必须知道它的所有(静态)外层过程的最新活动记录的地址。由于允许递归和可变数组,这些外层过程的活动记录的位置也往往是变迁的。因此,必须设法跟踪每个(静态)外层的最新活动记录的位置,而完成这一功能的就是DISPLAY嵌套层次显示表。 也即,每当进入一个过程后,在建立它的活动记录区的同时也建立一张DISPLAY表,它自顶而下每个单元依次存放着现行层、直接外层等,直至最外层(主程序层)等每一层过程的最新活动记录的起始地址。 6.3 (1) 写出实现一般递归过程的活动记录结构以及过程调用、过程进入与过程返回的指令; (2) 对以return(表达式)形式(这个表达式本身是一个递归调用)返回函数值的特殊函数过程,给出不增加时间开销但能节省存储空间的实现方法。假定语言中过程参数只有传值和传地址两种形式,为便于理解,举下例说明这种特殊的函数调用: int gcd (int p,int q) { if (p % q ==0) return q; else return gcd (q, p % q) } 【解答】(1) 一般递归过程的活动记录如图6-1所示。

编译原理作业答案

《编译原理》第一次作业参考答案 一、下列正则表达式定义了什么语言(用尽可能简短的自然语言描述)? 1.b*(ab*ab*)* 所有含有偶数个a的由a和b组成的字符串. 2.c*a(a|c)*b(a|b|c)* | c*b(b|c)*a(a|b|c)* 答案一:所有至少含有1个a和1个b的由a,b和c组成的字符串. 答案二:所有含有子序列ab或子序列ba的由a,b和c组成的字符串. 说明:答案一要比答案二更好,因为用自然语言描述是为了便于和非专业的人员交流,而非专业人员很可能不知道什么是“子序列”,所以相比较而言,答案一要更“自然”. 二、设字母表∑={a,b},用正则表达式(只使用a,b, ,|,*,+,?)描述下列语言: 1.不包含子串ab的所有字符串. b*a* 2.不包含子串abb的所有字符串. b*(ab?)* 3.不包含子序列abb的所有字符串. b*a*b?a* 注意:关于子串(substring)和子序列(subsequence)的区别可以参考课本第119页方框中的内容. ~\(≧▽≦)/~ ~\(≧▽≦)/~ ~\(≧▽≦)/~ ~\(≧▽≦)/~ ~\(≧▽≦)/~ ~\(≧▽≦)/~ ~\(≧▽≦)/~ ~\(≧▽≦)/~ 《编译原理》第二次作业参考答案 一、考虑以下NFA: 1.这一NFA接受什么语言(用自然语言描述)? 所有只含有字母a和b,并且a出现偶数次或b出现偶数次的字符串. 2.构造接受同一语言的DFA. 答案一(直接构造通常得到这一答案):

答案二(由NFA构造DFA得到这一答案): 二、正则语言补运算 3.画出一个DFA,该DFA恰好识别所有不含011子串的所有二进制串. 1.画出一个DFA,该DFA恰好识别所有不含011子串的所有二进制串.

(完整版)编译原理课后习题答案

第一章 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→ε | 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={a n b n c i |n>=1,i>=0 } (2)L2={a i b j|j>=i>=1} (3)L3={a n b m c m d n |m,n>=0} 答: (1)S→AB A→aAb | ab B→cB | ε (2)S→ASb |ab

编译原理教程课后习题答案——第七章

第七章目标代码生成 7.1 对下列四元式序列生成目标代码: T=A-B S=C+D W=E-F U=W/T V=U*S 其中,V是基本块出口的活跃变量,R0和R1是可用寄存器。 【解答】简单代码生成算法依次对四元式进行翻译。我们以四元式T=a+b为例来说明其翻译过程。 汇编语言的加法指令代码形式为 ADD R, X 其中,ADD为加法指令;R为第一操作数,第一操作数必须为寄存器类型;X为第二操作数,它可以是寄存器类型,也可以是内存型的变量。ADD R,X指令的含意是:将第一操作数R与第二操作数相加后,再将累加结果存放到第一操作数所在的寄存器中。要完整地翻译出四元式T=a+b,则可能需要下面三条汇编指令: MOV R, a ADD R, b MOV T, R 第一条指令是将第一操作数a由内存取到寄存器R中;第二条指令完成加法运算;第三条指令将累加后的结果送回内存中的变量T。是否在翻译成目标代码时都必须生成这三条汇编指令呢?从目标代码生成的优化角度考虑,即为了使生成的目标代码更短以及充分利用寄存器,上面的三条指令中,第一条和第三条指令在某些情况下是不必要的。这是因为,如果下一个四元式紧接着需要引用操作数T,则第三条指令就不急于生成,可以推迟到以后适当的时机再生成。 此外,如果必须使用第一条指令,即第一操作数不在寄存器而是在内存中,且此时所有可用寄存器都已分配完毕,这时就要根据寄存器中所有变量的待用信息(也即引用点)来决定淘汰哪一个寄存器留给当前的四元式使用。寄存器的淘汰策略如下: (1) 如果某寄存器中的变量已无后续引用点且该变量是非活跃的,则可直接将该寄存器作为空闲寄存器使用。 (2) 如果所有寄存器中的变量在基本块内仍有引用点且都是活跃的,则将引用点最远的变量所占用寄存器中的值存放到内存与该变量对应的单元中,然后再将此寄存器分配给当前的指令使用。 因此,本题所给四元式序列生成的目标代码如下: MOV R0, A SUB R0, C /*R0=T*/ MOV R1, C ADD R1, D /*R1=S*/ MOV S, R1 /*S引用点较T引用点远,故将R1的值送内存单元S*/ MOV R1, E SUB R1, F /*R1=W*/ SUB R1, R0 /*R1=U*/ MUL R1, S /*R1=V*/ 7.2 假设可用的寄存器为R0和R1,且所有临时单元都是非活跃的,试将以下四元式基本

编译原理作业参考答案

第1章引言 1、解释下列各词 源语言:编写源程序的语言(基本符号,关键字),各种程序设计语言都可以作为源语言。 源程序: 用接近自然语言(数学语言)的源语言(基本符号,关键字)编写的程序,它是翻译程序处理的对象。 目标程序: 目标程序是源程序经过翻译程序加工最后得到的程序。目标程序 (结果程序)一般可由计算机直接执行。 低级语言:机器语言和汇编语言。 高级语言:是人们根据描述实际问题的需要而设计的一个记号系统。如同自然语言(接近数学语言和工程语言)一样,语言的基本单位是语句,由符号组和一组用来组织它们成为有确定意义的组合规则。 翻译程序: 能够把某一种语言程序(源语言程序)改变成另一种语言程序(目 标语言程序),后者与前者在逻辑上是等价的。其中包括:编译程序,解释程序,汇编程序。 编译程序: 把输入的源程序翻译成等价的目标程序(汇编语言或机器语言), 然后再执行目标程序(先编译后执行),执行翻译工作的程序称为编译程序。 解释程序: 以该语言写的源程序作为输入,但不产生目标程序。按源程序中语句动态顺序逐句的边解释边执行的过程,完成翻译工作的程序称为解释程序。 2、什么叫“遍” 指对源程序或源程序的中间形式(如单词,中间代码)从头到尾扫描一次,并作相应的加工处理,称为一遍。

3、简述编译程序的基本过程的任务。 编译程序的工作是指从输入源程序开始到输出目标程序为止的整个过程,整个过程可以划分5个阶段。 词法分析:输入源程序,进行词法分析,输出单词符号。 语法分析:在词法分析的基础上,根据语言的语法规则把单词符号串分解成各类语法单位,并判断输入串是否构成语法正确的“程序”。 中间代码生成:按照语义规则把语法分析器归约(或推导)出的语法单位翻译成一定形式的中间代码。 优化:对中间代码进行优化处理。 目标代码生成:把中间代码翻译成目标语言程序。 4、编译程序与解释程序的区别 编译程序生成目标程序后,再执行目标程序;然而解释程序不生成目标程序,边解释边执行。 5、有人认为编译程序的五个组成部分缺一不可,这种看法正确吗 编译程序的5个阶段中,词法分析,语法分析,语义分析和代码生成生成是必须完成的。而中间代码生成和代码优化并不是必不可少的。优化的目的是为了提高目标程序的质量,没有这一部分工作,仍然能够得到目标代码。 6、编译程序的分类 目前基本分为:诊断编译程序,优化编译程序,交叉编译程序,可变目标编译程序。

编译原理期末考试题目及答案

一、填空题(每空2分,共20分) 1.编译程序首先要识别出源程序中每个单词,然后再分析每个句子并翻译其意义。 2.编译器常用的语法分析方法有自底向上和自顶向下两种。 3.通常把编译过程分为分析前端与综合后端两大阶段。词法、语法和语义分析是对源程序的分析,中间代码生成、代码优化与目标代码的生成则是对源程序的综合。 4.程序设计语言的发展带来了日渐多变的运行时存储管理方案,主要分为两大类,即静态存储分配方案和动态存储分配方案。 5.对编译程序而言,输入数据是源程序,输出结果是目标程序。 1.计算机执行用高级语言编写的程序主要有两种途径:解释和编译。 2.扫描器是词法分析器,它接受输入的源程序,对源程序进行词法分析并识别出一个个单词符号,其输出结果是单词符号,供语法分析器使用。 3.自下而上分析法采用移进、归约、错误处理、接受等四种操作。 4.一个LL(1)分析程序需要用到一张分析表和符号栈。 5.后缀式abc-/所代表的表达式是a/(b-c)。 二、单项选择题(每小题2分,共20分) 1.词法分析器的输出结果是__C。 A.单词的种别编码B.单词在符号表中的位置 C.单词的种别编码和自身值D.单词自身值 2.正规式M 1 和M 2 等价是指__C_。 A.M1和M2的状态数相等 B.M1和M2的有向边条数相等 C.M1和M2所识别的语言集相等D.M1和M2状态数和有向边条数相等 3.文法G:S→xSx|y所识别的语言是_C____。 A.xyx B.(xyx)* C.xnyxn(n≥0) D.x*yx* 4.如果文法G是无二义的,则它的任何句子α_A____。 A.最左推导和最右推导对应的语法树必定相同B.最左推导和最右推导对应的语法树可能不同 C.最左推导和最右推导必定相同D.可能存在两个不同的最左推导,但它们对应的语法树相同5.构造编译程序应掌握____D__。 A.源程序B.目标语言C.编译方法D.以上三项都是 6.四元式之间的联系是通过__B___实现的。 A.指示器B.临时变量C.符号表D.程序变量 7.表达式(┐A∨B)∧(C∨D)的逆波兰表示为__B___。 A.┐AB∨∧CD∨B.A┐B∨CD∨∧ C.AB∨┐CD∨∧D.A┐B∨∧CD∨ 8. 优化可生成__D___的目标代码。 A.运行时间较短 B.占用存储空间较小 C.运行时间短但占用内存空间大D.运行时间短且占用存储空间小 9.下列___C___优化方法不是针对循环优化进行的。 A. 强度削弱B.删除归纳变量C.删除多余运算D.代码外提 10.编译程序使用_B_区别标识符的作用域。 A. 说明标识符的过程或函数名B.说明标识符的过程或函数的静态层次 C.说明标识符的过程或函数的动态层次 D. 标识符的行号 三、判断题(对的打√,错的打×,每小题1分,共10分) 2.一个有限状态自动机中,有且仅有一个唯一的终态。x

编译原理_第三版_课后答案.docx

编译 原理 课后题答案 第二章 P36-6 (1) L ( G 1 ) 是 0~9 组成的数字串 (2) 最左推导 : N ND NDD NDDD DDDD 0DDD 01DD 012D 0127 N ND DD 3D 34 N ND NDD DDD 5DD 56D 568 最右推导 : N ND N 7 ND 7 N 27 ND 27 N 127 D127 0127 N ND N 4 D 4 34 N ND N 8 ND 8 N 68 D68 568 P36-7 G(S) O 1|3|5|7|9 N 2|4|6|8|O D 0|N S O| AO A AD | N P36-8 文法: E T| E T|E T T F |T * F |T / F F ( E)|i 最左推导 : E E T T T F T i T i T * F i F * F i i * F i i * i E T T * F F * F i * F i *( E ) i *( E T) i *( T T ) i *( F T ) i *( i T ) i *( i F ) i *( i i ) 最右推导 :

E E T E T * F E T * i E F * i E i * i T i * i F i * i i i * i E T F * T F * F F *( E) F *( E T) F *( E F ) F *( E i ) F *( T i ) F *( F i ) F *( i i ) i *( i i ) 语法树: /******************************** E E+T E+T F T F i F i i i+i+i *****************/ P36-9 句子 iiiei有两个语法树: S iSeS iSei iiSei iiiei S iS iiSeS iiSei iiiei E E E+T E-T T T*F E-T F F F i T F i i i F i i i-i-i i+i*i P36-10 /************** S TS | T T( S) | ( ) ***************/ P36-11 /*************** L1: S AC A aAb | ab C cC | L2:

编译原理复习题及参考答案

中南大学网络教育课程考试复习题及参考答案 编译原理 一、判断题: 1.一个上下文无关文法的开始符,可以是终结符或非终结符。 ( ) 2.一个句型的直接短语是唯一的。 ( ) 3.已经证明文法的二义性是可判定的。 ( ) 4.每个基本块可用一个DAG表示。 ( ) 5.每个过程的活动记录的体积在编译时可静态确定。 ( ) 6.2型文法一定是3 型文法。 ( ) 7.一个句型一定句子。 ( ) 8.算符优先分析法每次都是对句柄进行归约。 ( ) 9.采用三元式实现三地址代码时,不利于对中间代码进行优化。 ( ) 10.编译过程中,语法分析器的任务是分析单词是怎样构成的。 ( ) 11.一个优先表一定存在相应的优先函数。 ( ) 12.目标代码生成时,应考虑如何充分利用计算机的寄存器的问题。 ( ) 13.递归下降分析法是一种自下而上分析法。 ( ) 14.并不是每个文法都能改写成 LL(1)文法。 ( ) 15.每个基本块只有一个入口和一个出口。 ( ) 16.一个 LL(1)文法一定是无二义的。 ( ) 17.逆波兰法表示的表达试亦称前缀式。 ( ) 18.目标代码生成时,应考虑如何充分利用计算机的寄存器的问题。 ( ) 19.正规文法产生的语言都可以用上下文无关文法来描述。 ( ) 20.一个优先表一定存在相应的优先函数。 ( ) 21.3型文法一定是 2型文法。 ( ) 22.如果一个文法存在某个句子对应两棵不同的语法树,则文法是二义性的。 ( ) 二、填空题: 1.( )称为规范推导。 2.编译过程可分为(),(),(),()和()五个阶段。 3.如果一个文法存在某个句子对应两棵不同的语法树,则称这个文法是()。 4.从功能上说,程序语言的语句大体可分为()语句和()语句两大类。 5.语法分析器的输入是(),其输出是()。 6.扫描器的任务是从()中识别出一个个()。 7.符号表中的信息栏中登记了每个名字的有关的性质,如()等等。 8.一个过程相应的DISPLAY表的内容为()。 9.一个句型的最左直接短语称为句型的()。 10.常用的两种动态存贮分配办法是()动态分配和()动态分配。 11.一个名字的属性包括( )和( )。 12.常用的参数传递方式有(),()和()。 13.根据优化所涉及的程序范围,可将优化分成为(),()和()三个级别。 14.语法分析的方法大致可分为两类,一类是()分析法,另一类是()分析法。 15.预测分析程序是使用一张()和一个()进行联合控制的。 16.常用的参数传递方式有(),()和()。 17.一张转换图只包含有限个状态,其中有一个被认为是()态;而且实际上至少要有一个()态。 18.根据优化所涉及的程序范围,可将优化分成为(),()和()三个级别。 19.语法分析是依据语言的()规则进行。中间代码产生是依据语言的()规则进行的。 20.一个句型的最左直接短语称为句型的()。 21.一个文法G,若它的预测分析表M不含多重定义,则该文法是()文法。 22.对于数据空间的存贮分配, FORTRAN采用( )策略, PASCAL采用( )策略。

编译原理课后答案

第二章 2.3叙述由下列正规式描述的语言 (a) 0(0|1)*0 在字母表{0, 1}上,以0开头和结尾的长度至少是2的01 串 (b) ((ε|0)1*)* 在字母表{0, 1}上,所有的01串,包括空串 (c) (0|1)*0(0|1)(0|1) 在字母表{0, 1}上,倒数第三位是0的01串 (d) 0*10*10*10* 在字母表{0, 1}上,含有3个1的01串 (e) (00|11)*((01|10)(00|11)*(01|10)(00|11)*)* 在字母表{0, 1}上,含有偶数个0和偶数个1的01串 2.4为下列语言写正规定义 C语言的注释,即以 /* 开始和以 */ 结束的任意字符串,但它的任何前缀(本身除外)不以 */ 结尾。 [解答] other → a | b | … other指除了*以外C语言中的其它字符 other1 → a | b | … other1指除了*和/以外C语言中的其它字符 comment → /* other* (* ** other1 other*)* ** */ (f) 由偶数个0和偶数个1构成的所有0和1的串。 [解答]由题目分析可知,一个符号串由0和1组成,则0和1的个数只能有四种情况: x 偶数个0和偶数个1(用状态0表示); x 偶数个0和奇数个1(用状态1表示); x 奇数个0和偶数个1(用状态2表示); x 奇数个0和奇数个1(用状态3表示);所以, x 状态0(偶数个0和偶数个1)读入1,则0和1的数目变为:偶数个0和奇数个1(状态1) x 状态0(偶数个0和偶数个1)读入0,则0和1的数目变为:奇数个0和偶数个1(状态2) x 状态1(偶数个0和奇数个1)读入1,则0和1的数目变为:偶数个0和偶数个1(状态0) x 状态1(偶数个0和奇数个1)读入0,则0和1的数目变为:奇数个0和奇数个1(状态3) x 状态2(奇数个0和偶数个1)读入1,则0和1的数目变为:奇数个0和奇数个1(状态3) x 状态2(奇数个0和偶数个1)读入0,则0和1的数目变为:偶数个0和偶数个1(状态0) x 状态3(奇数个0和奇数个1)读入1,则0和1的数目变为:奇数个0和偶数个1(状态2) x 状态3(奇数个0和奇数个1)读入0,则0和1的数目变为:偶数个0和奇数个1(状态1) 因为,所求为由偶数个0和偶数个1构成的所有0和1的串,故状态0既为初始状态又为终结状态,其状态转换图: 由此可以写出其正规文法为: S0 → 1S1 | 0S2 | ε S1 → 1S0 | 0S3 | 1 S2 → 1S3 | 0S0 | 0 S3 → 1S2 | 0S1 在不考虑S0 →ε产生式的情况下,可以将文法变形为: S0 = 1S1 + 0S2 S1 = 1S0 + 0S3 + 1 S2 = 1S3 + 0S0 + 0 S3 = 1S2 + 0S1 所以: S0 = (00|11) S0 + (01|10) S3 + 11 + 00 (1) S3 = (00|11) S3 + (01|10) S0 + 01 + 10 (2) 解(2)式得: S3 = (00|11)* ((01|10) S0 + (01|10)) 代入(1)式得: S0 = (00|11) S0 + (01|10) (00|11)*((01|10) S0 + (01|10)) + (00|11) => S0 = ((00|11) + (01|10) (00| 11)*(01|10))S0 + (01|10) (00|11)*(01|10) + (00|11) => S0 = ((00|11)|(01|10) (00|11)*(01|10))*((00|1

编译原理试题及答案3

编译原理复习题 一、填空题: 1、编译方式与解释方式的根本区别在于(是否生成目标代码)。 2、对编译程序而言,输入数据是(源程序),输出结果是(目标程序)。 3、如果编译程序生成的目标程序是机器代码程序,则源程序的执行分为两大阶段:(编译阶段)和(运行阶段)。 4、如果编译程序生成的目标程序是汇编语言程序,则源程序的执行分成三个阶段:(编译阶段)、(汇编阶段)和(运行阶段)。 5、自顶向下语法分析方法会遇到的主要问题有(回溯)和((左递归带来的)无限循环)。 6、LL(k)分析法中,第一个L的含义是(从左到右进行分析),第二个L的含义是(每次进行最左推导),“k”的含义是(向输入串中查看K个输入符号)。 7、LL(1)分析法中,第一个L的含义是(从左到右进行分析),第二个L的含义是(每次进行最左推导),“1”的含义是(向输入串中查看1个输入符号)。 8、自顶向下语法分析方法的基本思想是:从(识别符号)出发,不断建立(直接推导),试图构造一个推导序列,最终由它推导出与输入符号相同的(符号串)。 9、自底向上语法分析方法的基本思想是:从待输入的符号串开始,利用文法的规则步步向上进行(直接归约),试图(归约)到文法的(识别符号|开始符号)。 10、LR(0)分析法的名字中,“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“0”的含义是(向貌似句柄的符号串后查看0个输入符号)。 11、LR(1)分析法的名字中,“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“1”的含义是(向貌似句柄的符号串后查看1个输入符号)。 12、SLR(1)分析法的名字中,“S”的含义是(简单的),“L”的含义是(从左到右进行分析),“R”的含义是(采用最右推导的逆过程---最左归约),“1”的含义是(向貌似句柄的符号串后查看1个输入符号)。 13、在编译过程中,常见的中间语言形式有(逆波兰表示)、(三元式)、(四元式)和(树形表示)。 14、在编译程序中安排中间代码生成的目的是(便于代码优化)和(便于目标程序的移植)。 15、表达式-a+b*(-c+d)的逆波兰表示为(a-bc-d+*+ )。 16、表达式a+b*(c+d/e)的逆波兰表示为(abcde/+*+ )。 17、表达式a:=a+b*c↑(d/e)/f的逆波兰表示为(aabcde/↑*f/+:= )。 18、文法符号的属性有(继承属性)和(综合属性)两种。 19、一个文法符号的继承属性是通过语法树中它的(兄弟结点与父)结点的相应文法符号的属性来计算的。 20、一个文法符号的综合属性是通过语法树中它的(子)结点的属性来计算的。

编译原理教程课后习题答案——第四章

第四章语义分析和中间代码生成 4.1 完成下列选择题: (1) 四元式之间的联系是通过实现的。 a. 指示器 b. 临时变量 c. 符号表 d. 程序变量 (2) 间接三元式表示法的优点为。 a. 采用间接码表,便于优化处理 b. 节省存储空间,不便于表的修改 c. 便于优化处理,节省存储空间 d. 节省存储空间,不便于优化处理 (3) 表达式(┐A∨B)∧(C∨D)的逆波兰表示为。 a. ┐AB∨∧CD∨ b. A┐B∨CD∨∧ c. AB∨┐CD∨∧ d. A┐B∨∧CD∨ (4) 有一语法制导翻译如下所示: S→bAb {print″1″} A→(B {print″2″} A→a {print″3″} B→Aa) {print″4″} 若输入序列为b(((aa)a)a)b,且采用自下而上的分析方法,则输出序列为。a. 32224441 b. 34242421 c. 12424243 d. 34442212 【解答】 (1) b (2) a (3) b (4) b 4.2 何谓“语法制导翻译”?试给出用语法制导翻译生成中间代码的要点,并用一简例予以说明。 【解答】语法制导翻译(SDTS)直观上说就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并且在语法分析的同时执行这些子程序。也即在语法分析过程中,当一个产生式获得匹配(对于自上而下分析)或用于归约(对于自下而上分析)时,此产生式相应的语义子程序进入工作,完成既定的翻译任务。 用语法制导翻译(SDTS)生成中间代码的要点如下: (1) 按语法成分的实际处理顺序生成,即按语义要求生成中间代码。 (2) 注意地址返填问题。 (3) 不要遗漏必要的处理,如无条件跳转等。 例如下面的程序段: if (i>0) a=i+e-b*d; else a=0; 在生成中间代码时,条件“i>0”为假的转移地址无法确定,而要等到处理“else”时方可确定,这时就存在一个地址返填问题。此外,按语义要求,当处理完(i>0)后的语句(即“i>0”为真时执行的语句)时,则应转出当前的if语句,也即此时应加入一条无条件跳转指令,并且这个转移地址也需要待处理完else之后的语句后方可获得,就是说同样存在着地址返填问题。对于赋值语句a=i+e-b*d,其处理顺序(也即生成中间代码顺序)是先生成i+e的代码,再生成b*d的中间代码,最后才产生“-”运算的中间代码,这种顺序不能颠倒。 4.3 令S.val为文法G[S]生成的二进制数的值,例如对输入串101.101,则S.val= 5.625。按照语法制导翻译方法的思想,给出计算S.val的相应的语义规则,G(S)如下: G[S]: S→L.L|L

编译原理课后习题答案

第1 章 1、编译过程包括哪几个主要阶段及每个 阶段的功能。 答案:编译过程包括词法分析、语法分析、语义分析和中间代码生成、优化、目标代码生成5 个阶段。词法分析的功能是对输入的高级语言源程序进行词法分析,识别其中的单词符号,确定它们的种类,交给语法分析器,即把字符串形式的源程序分解为单词符号串形式。语法分析的功能是在词法分析结果的基础上,运用语言的语法规则,对程序进行语法分析,识别构成程序的各类语法范畴及它们之间的层次关系,并把这种层次关系表达成语法树的形式。词义分析和中间代码生成的功能是在语法分析的基础上,对程序进行语义分析,“理解”其含义,产生出表达程序语义的内部表达形式(中间代码)。优化的功能是按照等价变换的原则,对语义分析器产生的中间代码序列进行等价变换,删除其中多余的操作,对耗时耗空间的代码进行优化,以期最后得到高效的可执行代码。目标代码生成的功能是把优化后的中间代码变换成机器指令代码,得到可在目标机器上执行的机器语言程序。 第2 章 1、写一上下文无关文法G,它能产生配 对的圆括号串(如:(),(()),()(())等,甚至 包括0 对括号) 文法为:S→(L)|LS|L L→S| ε 2 、已知文法G :E→E+T|E-T|T T→T*F|T/F|F F→(E) |i (1)给出i+i*i,i*(i-i)的最左推导,最右推导以及语法树。 (2)i-i+i 哪个算符优先。 【解答】 (1)最左推导:E?E+T?T+T? F+T ? i+T ? i+T*F ? i+F*F ?i+i*F ?i+i*i E?T?T*F? F*F ? i*F ? i*(E) ? i*(E-T) ? i*(T-T) ? i*(F-T) ? i*(i-T) ? i*(i-F) ?i*(i-i) 最右推导:E?E+T?E+T*F? E+T*i ? E+F*i ? E+i*i ? T+i*i ? F+i*i ? i+i*i E?T?T*F? T*(E) ? T*(E-T) ? T*(E-F) ? T*(E-i) ? T*(T-i) ? T*(F-i) ?T*(i-i) ? F*(i-i) ?i*(i-i) i+i*i 以及i*(i-i)的语法树如下所示: (2)i-i+i 的语法树如下图所示。 从上图的语法树可知:“-”的位置位 于“+”的下层,也就是前面两个i 先进 行“-”运算,再与后面的i 进行“+” 运算,所以“-”的优先级高于“+”的 优先级。 3 、文法G: E→ET+|T T→TF*|F F→FP↑|P P→E|i (1)试证明符号串TET+*i↑是G 的一 个句型(要求画出语法树). (2)写出该句型的所有短语,直接短语和句柄. 【解答】(1)采用最右推导: E?T?F? FP↑? Fi↑? Pi↑? Ei↑ ? Ti↑? TF*i↑? TP*i↑? TE*i↑? TET+*i↑ 语法树如下图所示。 从文法G 的起始符号出发,能够推导 出符号串TET+*i↑,所以给定符号串是文法G的句型。 (2) 该句型的短语有: ET+,TET+*,i ,TET+*i↑ 直接短语有:ET+, i 句柄是:ET+ 4、已知文法G:S→iSeS|iS|i ,该文法 是二义文法吗?为什么? 【解答】该文法是二义文法。 因为对于句子iiiei 存在两种不同的最 左推导: 第 1 种推导:S? iSeS? iiSeS? iiieS? iiiei 第2种推导:S?iS?iiSeS?iiieS?iiiei 第3 章 1、用正规式描述下列正规集: (1)C 语言的十六进制整数; (2)以ex 开始或以ex 结束的所有小写字母构成的符号串; (3)十进制的偶数。 【解答】 (1)C 语言十六进制整数以0x 或者0X 开头,所以一般形式应该为(+|-|ε) (0x|0X)AA*,其中前面括号表示符号, 可以有正号、负号,也可以省略(用ε表示)默认是正数,A 表示有资格出现在十六进制整数数位上的数字,AA*表示一位或者多位(一个或者多个数字的

编译原理第8章作业及习题参考答案

第八章 语法制导翻译和中间代码生成 1.给出下面表达式的逆波兰表示(后缀式): (1) a*(-b+c) (4) (A ∧B) ∨(?C ∨ D) (7) if(x+y)*z=0 then s ∶=(a+b)*c else s ∶=a*b*c 解(1) ab-c+* (4) AB ∧C ?D ∨∨ (7) xy+z*0=sab+c*:=sab*c*:=¥(注:¥表示if-then-else 运算) 2. 请将表达式-(a+b)*(c+d)-(a+b+c)分别表示成三元式、间接三元式和四元式序列。 答案:三元式 (1) (+ a, b) (2) (+ c, d) (3) (* (1), (2)) (4) (- (3), /) (5) (+ a, b) (6) (+,(5),c) (7) (- (4), (6)) 间接三元式 间接三元式序列 间接码表 (1) (+ a, b) (1) (2) (+ c, d) (2) (3) (* (1), (2)) (3) (4) (- (3), /) (4) ¥ = := * := + x y z s + c x a b s * c * a b

(5) (- (4), (1)) (1) (6) (- (4), (5)) (5) (6) 四元式 (1) (+, a, b, t1) (2) (+, c, d, t2) (3) (*, t1, t2, t3) (4) (-, t3, /, t4) (5) (+, a, b, t5) (6) (+, t5, c, t6) (6) (-, t4, t6, t7) 3. 采用语法制导翻译思想,表达式E 的"值"的描述如下: 产生式 语义动作 (0) S ′→E {print E.VAL} (1) E →E1+E2 {E.VAL ∶=E1.VAL+E2.VAL} (2) E →E1*E2 {E.VAL ∶=E1.VAL*E2.VAL} (3) E →(E1) {E.VAL ∶=E1.VAL} (4) E →n {E.VAL ∶=n.LEXVAL} 如果采用LR 分析法,给出表达式(5 * 4 + 8) * 2的语法树并在各结点注明语义值VAL 。 4. 假如习题3中表达式E 的“值”有两种类型:整型和实型。语义处理增加"类型匹配检查",请给出相应的语义描述。 S ’ * E1 E2 E0 E3 2 E5.V AL=5 8 5 * E5 E6 + E4 4 E6.V AL=4 E4.V AL=8 E3.V AL=20 E1.V AL=28 E2.V AL=2 E0.V AL=56 Print(56)

编译原理试题及答案

参考答案 一、单项选择题(共10小题,每小题2分,共20分) 1.语言是 A .句子的集合 B .产生式的集合 C .符号串的集合 D .句型的集合 2.编译程序前三个阶段完成的工作是 A .词法分析、语法分析和代码优化 B .代码生成、代码优化和词法分析 C .词法分析、语法分析、语义分析和中间代码生成 D .词法分析、语法分析和代码优化 3.一个句型中称为句柄的是该句型的最左 A .非终结符号 B .短语 C .句子 D .直接短语 4.下推自动机识别的语言是 A .0型语言 B .1型语言 C .2型语言 D .3型语言 5.扫描器所完成的任务是从字符串形式的源程序中识别出一个个具有独立含义的最小语法单位即 A . 字符 B .单词 C .句子 D .句型 6.对应Chomsky 四种文法的四种语言之间的关系是 A .L 0?L 1?L 2?L 3 B .L 3?L 2?L 1?L 0 C .L 3=L 2?L 1?L 0 D .L 0?L 1?L 2=L 3 7.词法分析的任务是 A .识别单词 B .分析句子的含义 C .识别句子 D .生成目标代码 8.常用的中间代码形式不含 A .三元式 B .四元式 C .逆波兰式 D .语法树 9. 代码优化的目的是 A .节省时间 B .节省空间 C .节省时间和空间 D .把编译程序进行等价交换 10.代码生成阶段的主要任务是 A .把高级语言翻译成汇编语言 B .把高级语言翻译成机器语言 C .把中间代码变换成依赖具体机器的目标代码 装 订 线

D.把汇编语言翻译成机器语言 二、填空题(本大题共5小题,每小题2分,共10分) 1.编译程序首先要识别出源程序中每个(单词),然后再分析每个(句子)并翻译其意义。2.编译器常用的语法分析方法有(自底向上)和(自顶向下)两种。 3.通常把编译过程分为分析前端与综合后端两大阶段。词法、语法和语义分析是对源程序的(分析),中间代码生成、代码优化与目标代码的生成则是对源程序的(综合)。 4.程序设计语言的发展带来了日渐多变的运行时存储管理方案,主要分为两大类,即(静态存储分配)方案和(动态存储分配)方案。 5.对编译程序而言,输入数据是(源程序),输出结果是(目标程序)。 三、名词解释题(共5小题,每小题4分,共20分) 1.词法分析 词法分析的主要任务是从左向右扫描每行源程序的符号,按照词法规则 从构成源程序的字符串中识别出一个个具有独立意义的最小语法单位, 并转换成统一的内部表示(token),送给语法分析程序。 2.LL(1)文法 若文法的任何两个产生式A →α | β都满足下面两个条件: (1)FIRST(α) ? FIRST(β ) = φ; (2)若β?* ε,那么FIRST(α) ? FOLLOW( A ) = φ。 我们把满足这两个条件的文法叫做LL(1)文法,其中的第一个L代表从左 向右扫描输入,第二个L表示产生最左推导,1代表在决定分析器的每步 动作时向前看一个输入符号。除了没有公共左因子外,LL(1)文法还有一 些明显的性质,它不是二义的,也不含左递归。 3.语法树 句子的树结构表示法称为语法树(语法分析树或语法推导树)。 给定文法G=(V N,V T,P,S),对于G的任何句型都能构造与之关联的 语法树。这棵树具有下列特征: (1)根节点的标记是开始符号S。 (2)每个节点的标记都是V中的一个符号。 (3)若一棵子树的根节点为A,且其所有直接子孙的标记从左向右的排列 次序为A1A2…A R,那么A→A1A2…A R一定是P中的一条产生式。