词法分析习题Word文档格式.docx

上传人:b****6 文档编号:22144815 上传时间:2023-02-02 格式:DOCX 页数:17 大小:209.38KB
下载 相关 举报
词法分析习题Word文档格式.docx_第1页
第1页 / 共17页
词法分析习题Word文档格式.docx_第2页
第2页 / 共17页
词法分析习题Word文档格式.docx_第3页
第3页 / 共17页
词法分析习题Word文档格式.docx_第4页
第4页 / 共17页
词法分析习题Word文档格式.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

词法分析习题Word文档格式.docx

《词法分析习题Word文档格式.docx》由会员分享,可在线阅读,更多相关《词法分析习题Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。

词法分析习题Word文档格式.docx

因此正规式(00|11)((01|10)(00|11)(01|10)(00|11))描述的是偶数个0和偶数个1构成的串。

可能会提出一个问题,这样的串是否能用更简单的观点来看待,也就是该语言是否能用更简洁的正规式描述。

这是可能的。

我们写出这样的正规式,

(00|11|((01|10)(00|11)(01|10)))

它是基于这样的考虑,满足要求的最简单的串有三种形式(空串除外):

1.00

2.11

3.(01|10)(00|11)(01|10)

它们任意多次的重复构成的串仍然满足要求。

1.2.写出语言“由偶数个0和奇数个1构成的所有0和1的串”的正规定义。

答案even_0_even_1(00|11)((01|10)(00|11)(01|10)(00|11))

even_0_odd_11even_0_even_1|0(00|11)(01|10)even_0_even_1

分析有了上一题的结果,这个问题应该容易解决。

首先给上一题的正规式起个名字:

even_0_even_1(00|11)((01|10)(00|11)(01|10)(00|11))

对于偶数个0和奇数个1构成的串,其第一个字符可能是0或1。

1.如果是1,那么剩下的部分一定是偶数个0和偶数个1。

2.如果是0,那么经过若干个00或11,一定会出现一个01或10,才能保证0的个数是偶数,1的个数是奇数。

若串还没有结束,剩余部分一定是偶数个0和偶数个1。

这样,正确的正规定义是:

even_0_odd_11even_0_even_1|0(00|11)(01|10)even_0_even_1

1.3.写出语言“所有相邻数字都不相同的非空数字串”的正规定义。

答案no_0-89

no_0-7(8|no_0-88)(no_0-88)(no_0-8|)|no_0-8

no_0-6(7|no_0-77)(no_0-77)(no_0-7|)|no_0-7

no_0-5(6|no_0-66)(no_0-66)(no_0-6|)|no_0-6

no_0-4(5|no_0-55)(no_0-55)(no_0-5|)|no_0-5

no_0-3(4|no_0-44)(no_0-44)(no_0-4|)|no_0-4

no_0-2(3|no_0-33)(no_0-33)(no_0-3|)|no_0-3

no_0-1(2|no_0-22)(no_0-22)(no_0-2|)|no_0-2

no_0(1|no_0-11)(no_0-11)(no_0-1|)|no_0-1

answer(0|no_00)(no_00)(no_0|)|no_0

分析刚拿到这个问题,一定不知从哪儿下手。

其实和上面一样,关键是找到一种合适的看待这种句子结构的观点。

我们的观点是这样,每个这样的句子由若干个0把它分成若干段,如

123031357106678035590123

可以看成

123,0,313571,0,6678,0,3559,0,123

由0隔开的每一段,如313571,它不含0,并且又可以看成是由若干个1把它分成若干段。

如此下去,就能找到该语言的正规定义。

按这个思路,上面的正规定义应该逆序看。

表示一个句子由若干个0分成若干段,特殊情况是整个句子不含0。

在这个正规定义中,所引用的no_0表示不含0的串,它的定义和这个定义的形式一样,因为串的形式是一样的,只不过没有数字0。

所以有

其中no_0-1表示不含0和1的串。

依此类推,最后no_0-8是表示不含0,…,8的没有重复数字的串,它只可能是单个9。

1.4.构造一个DFA,它接受={0,1}上0和1的个数都是偶数的字符串。

答案见图1.1。

分析对于这样的问题,不要急于去尝试画DFA,先把问题分析一下,这里要接受的是偶数个0和偶数个1的串,和偶数相对的是奇数,因此,对于任意一个0和1的串,不论其0和1的个数有多少,总归不是偶数个就是奇数个。

因此任意一个串属于下面四种情况之一。

0:

偶数个0和偶数个1;

1:

偶数个0和奇数个1;

2:

奇数个0和偶数个1;

3:

奇数个0和奇数个1。

并且不管一个串是处于上面哪一种情况,该串再添加一个0或1后,总是处于上面另一种情况。

由此分析可以知道,DFA只需四个状态就够了,并且状态转换也很容易画出来。

答案中的四个状态对应到这儿的四种情况。

空串是属于偶数个0和偶数个1的情况,因此0状态是开始状态。

因为我们接受偶数个0和偶数个1的串,因此它也是接受状态。

1.5.构造一个DFA,它接受={0,1}上能被5整除的二进制数。

答案见图1.2。

分析由上题我们知道,构造DFA之前,首先搞请楚问题的状态空间。

即想明白应该有多少个状态,状态之间的转换条件,以及针对该问题的开始状态和接受状态。

对于本题目,任意一个二进制数除以5时,只有余数为0(即整除),1,2,3和4五种情况。

图中的五个状态也是这样起名字的。

一个二进制数的后面添上一个0意味着其值变成原来的两倍,而后面添上一个1意味着其值变成原来的两倍再加1。

不管是哪一种情况,都很容易从原来的余数决定值变化后的余数。

这样,我们很快可以得出所有的状态转换。

例如,我们考虑状态4。

任何一个余4的数,两倍后一定余3,两倍再加1后一定还是余4。

所以,状态4的0转换到状态3,而1转换到本身。

显然,状态0既是开始状态又是接受状态。

需要注意的是,考虑状态空间时,还要检查我们是否取的是最简情况(即状态数极小)。

例如,对于本题目,假如我们从这样的观点出发,每个二进制数都可以转换成一个十进制数。

十进制数的末位有0到9十种情况,其中末位为0和5是能被5整除的情况。

这样我们很可能会构造十个状态的DFA,接受状态有两个。

这也是一种解,但它不是最简的DFA。

1.6处于/*和*/之间的串构成注解,注解中间没有*/。

画出接受这种注解的DFA的状态转换图。

答案见图1.3。

标记为others的边是指字符集中未被别的边指定的任意其它字符。

分析这个DFA的状态数及含义并不难确定,见下面的五个状态说明。

状态1:

注释开始状态。

状态2:

进入注释体前的中间状态。

状态3:

表明目前正在注释体中的状态。

状态4:

离开注释前的中间状态。

状态5:

注释结束状态,即接受状态。

在这个DFA中,最容易忽略的是状态4到本身的’*’转换。

这个边的含义是:

在离开注释前的中间状态,若下一个字符是’*’,那么把刚才读过的’*’看成是注释中的一个字符,而把这下一个字符看成可能是结束注释的第一个字符。

若没有这个边,那么象

/****Thisisacomment****/

这样的注释就被拒绝。

另外,上面的状态转换图并不完整。

例如,对于状态1,没有指明遇到其它字符怎么办。

要把状态转换图画完整,还需引入一个死状态6,进入这个状态就再也出不去了。

因为它不是接受状态,因此进入这个状态的串肯定不被接受。

完整的状态转换图见下面图1.4,其中all表示任意字符。

在能够说清问题时,通常我们省略死状态和所有到它的边。

1.7某操作系统下合法的文件名为

device:

name.extension

其中第一部分(device:

)和第三部分(.extension)可缺省,若device,name和extension都是字母串,长度不限,但至少为1,画出识别这种文件名的DFA。

答案见图1.5,图中的标记d表示任意字母。

分析这个DFA和一些教材上接受无符号数的DFA有类似的地方。

我们首先考虑device:

和.extension全都出现的情况。

这时的DFA比较容易构造,见图1.6。

然后考虑缺省情况。

因为.extension可缺省,因此把状态4也作为接受状态。

因为name和device一样,都是字母序列,因此在device:

缺省时,把到状态2为止得到的字母序列看成是name,所以从状态2画一条转换边到状态5,标记为’.’。

(如果构成name和device的字符完全不一样,那么可以从状态1到状态4画一条边,其标记同状态3到状态4的标记一样。

)由于device:

和.extension都可缺省,因此把状态2也作为接受状态。

1.8为正规式(a|b)a(a|b)(a|b)构造NFA。

答案该NFA的状态转换图见图1.7。

分析各种教材在介绍有限状态自动机和正规表达式的等价时,都给出了从正规表达式构造等价的NFA的算法。

不同书上的构造算法虽然不一样,但有一个共同的特点,或多或少引入了转换,使状态转换图变得复杂。

尤其是,如果题目还要求你画出DFA,那么状态数的增多,使得手工完成NFA确定化为DFA的过程变得更容易出错。

因此,我们既要会用书上的算法构造NFA,也要会手工构造更简一些的NFA,尽量避免在NFA中出现转换。

这在大多数情况下是可以做到的,本题就是一个例证。

1.9用状态转换图表示接收(a|b)aa的确定的有限自动机。

答案状态转换图见图1.8。

分析和上一题不同的是,现在是直接构造DFA。

我们仍然坚持这一点,大家既要会按教材上的算法从NFA的确定化得到DFA,也要会手工直接构造DFA。

我们通过本题和下一题来说明,手工直接构造DFA也并不困难。

该正规式表示的语言是,字母表={a,b}上最后两个字符都是a的串的集合。

抓住这个特点,我们首先画出构造过程中的第一步,见图1.9。

它表明最简单的句子是aa。

然后,因为在第一个a前可以有若干个b,因此状态0有到自身的b转换。

在最后两个字符都是a的串的末尾添加若干个a,能够保持串的这个性质,因此状态2有到自身的a转换。

这样我们有图1.10。

最后,在状态1和状态2碰到b时,前面刚读过的a,不管连续有多少个,都不可能作为句子结尾的那两个字符a,因此状态1和状态2的b转换回到状态0。

所有状态的a转换和b转换都已给出,这就得到最后结果。

1.10用状态转换图表示接收(a|b)a(a|b)(a|b)的确定的有限自动机。

答案状态转换图见图1.11。

分析该正规式表示的语言是,字母表={a,b}上倒数第三个字符是a的串的集合。

根据上题的经验,我们首先画出图1.12。

因为最后两个字符任意,因此有这样的分杈,并有四个接受状态。

现在考虑这四个接受状态上的转换。

1.状态4该状态表示最后三个字符是aaa,若再添加一个a,最后三个字符仍是aaa,因此状态4的a转换到本身。

若添加的是b,那么最后三个字符是aab,而状态5表示最后三个字符是aab,因此状态4的b转换到状态5。

2.状态5该状态表示最后三个字符是aab,若再添加一个a,最后三个字符成了aba,而状态6表示最后三个字符是aba,因此状态5的a转换到状态6。

若添加的是b,那么最后三个字符是abb,而状态7表示最后三个字符是abb,因此状态5的b转换到状态7。

3.状态6该状态表示最后三个字符是aba,若再添加一个a,最后三个字符成了baa,其由a开始的后缀是aa,因此状态6的a转换到状态2(因为从状态0出发经aa是到状态2)。

若添加的是b,那么最后三个字符是bab,其由a开始的后缀是ab,因此状态6的b转换到状态3。

4.状态7该状态表示最后三个字符是abb,若再添加一个a,最后三个字符成了bba,其由a开始的后缀是a,因此状态7的a转换到状态1。

若添加的是b,那么最后三个字符是bbb,不存在由a开始的后缀,因此状态7的b转换到状态0。

这样,所有状态的a转换和b转换都已给出,也就得到了最后结果。

1.11将1.8得到的NFA变换成DFA。

答案所求的DFA就是1.10题的结果。

分析我们之所以选这个题目,是为了比较一下,从正规式到NFA,再把NFA确定化,这样得的结果同1.10题直接构造DFA的结果是否一样。

按照教材上的子集构造法,作为结果的DFA并不难得到。

另外由于没有转换,构造过程相对简单了很多。

NFA的开始状态是0,因此首先从NFA的状态集合{0}开始,它是DFA的开始状态,起名叫状态0。

它的a转换和b转换所得到的NFA的状态集合见下面第一行。

根据子集构造法所得的DFA的所有状态和它们的转换函数都列在下面。

状态0:

{0}move({0},a)={0,1}move({0},b)={0}

状态1:

{0,1}move({0,1},a)={0,1,2}move({0,1},b)={0,2}

状态2:

{0,1,2}move({0,1,2},a)={0,1,2,3}move({0,1,2},b)={0,2,3}

状态3:

{0,2}move({0,2},a)={0,1,3}move({0,2},b)={0,3}

状态4:

{0,1,2,3}move({0,1,2,3},a)={0,1,2,3}move({0,1,2,3},b)={0,2,3}

状态5:

{0,2,3}move({0,2,3},a)={0,1,3}move({0,2,3},b)={0,3}

状态6:

{0,1,3}move({0,1,3},a)={0,1,2}move({0,1,3},b)={0,2}

状态7:

{0,3}move({0,3},a)={0,1}move({0,3},b)={0}

状态4,5,6和7中都含原NFA的接受状态3,因此它们都是DFA的接受状态。

不难看出所得的DFA和1.10题的结果是同构的,仅状态名不一样。

1.12将图1.13的DFA极小化。

答案最简DFA见图1.14。

分析本题要注意的是,在使用极小化算法前,一定要检查一下,看状态转换函数是否为全函数,即每个状态对每个输入符号都有转换。

若不是全函数,需加入死状态,然后再用极小化算法。

有些教材上没有强调这一点,有的习题解上的示例甚至忽略了这一点,本题将告诉你,这一点是重要的。

本题加入死状态5后的状态转换图见图1.15。

使用极小化算法,先把状态集分成非接受状态集{0,1,2,3,5}和接受状态集{4}这两个子集。

1.集合{4}不能再分解,我们看集合{0,1,2,3,5}。

move({0,1,2,3,5},a)={1,2,5}move({0,1,2,3,5},b)={3,4,5}

由于b转换的结果{3,4,5}不是最初划分的某个集合的子集,因此{0,1,2,3,5}需要再分,由于状态1和状态2的b转换都到状态4。

因此状态集合的进一步划分是:

{1,2},{0,3,5}和{4}

2.由于

move({1,2},a)={2,5}move({1,2},b)={4}

move({0,3,5},a)={1,5}move({0,3,5},b)={3,5}

显然{1,2}和{0,3,5}需要再分,分别分成:

{1}和{2}以及{0,3}和{5}

3.由于

move({0,3},a)={1}move({0,3},b)={3}

因此不需要再分。

这样状态0和状态3合并成一个状态,我们取0为代表,再删去死状态5,就得到该题的结果。

如果不加死状态,我们来看一下极小化算法的结果。

最初的划分是{0,1,2,3}和{4}。

1.状态集合的进一步划分是:

{1,2},{0,3}和{4}

2.忽略了死状态的影响,会认为它们都不需要再分,此时得到的DFA如图1.16。

显然,它和原来的DFA不等价。

1.13将习题1.10结果的DFA极小化。

答案化简的结果仍是习题1.10结果的DFA,即该DFA已是最简DFA。

这说明手工构造最简DFA是完全可能的。

分析我们简要说明执行过程。

初始时将状态集分成两组:

{0,1,2,3}和{4,5,6,7}。

1.由于

move({0,1,2,3},a)={1,2,4,6}move({0,1,2,3},b)={0,3,5,7}

move({4,5,6,7},a)={1,2,4,6}move({4,5,6,7},b)={0,3,5,7}

因此进一步分成{0,1}、{2,3}、{4,5}和{6,7}四组。

move({0,1},a)={1,2}move({0,1},b)={0,3}

因此{0,1}还要进一步分,其它几组也是这样。

因此最终分成了每个集合中都只有一个状态。

3.所以原来的DFA已经是最简形式了。

1.14若L是正规语言,证明下面L语言也是正规语言。

L语言的定义是

L={x|xRL}

xR表示x的逆。

答案若我们能定义出接受语言L的一个NFA,那么L是正规语言。

因为L是正规语言,那么一定存在接受L的DFAM,我们就基于M来构造接受L的NFAM,并且我们基于M的状态转换图来叙述。

1.将状态转换图上的所有边改变方向,边上的标记不变。

2.将原来的开始状态改成接受状态。

3.增添一个状态作为开始状态,从它有转换到原来的每一个接受状态,并把原来的这些接受状态都改成普通的状态。

所得到的新状态转换图就是M的状态转换图。

分析简单说,判断一个串是否为L的句子,只要在原来的状态转换图上逆行就可以了。

由于M可能有多个接受状态,而不管是DFA还是NFA都只有唯一的开始状态,因此有上面的第3步。

注意经过上面的改造后,得到的可能不是一个DFA的状态转换图。

除了上面第3步有可能引入不确定性外,第1步也可能引入不确定性。

本题介绍的证明语言的正规性的方法在下一题表现得更加充分,叙述也比本题严格。

1.15.若L是正规语言,证明下面

L语言也是正规语言。

L={x|y.xyL&

|x|=|y|}

答案因为L是正规语言,那么存在一个DFAM=(S,,,s,F),它接受语言L。

接受语言

L的DFAM=(S,,,s,F)可如下构造。

1.S的每个状态是一个二元组s1,S1,其中s1S,S1S。

2.(s1,S1,a)=s2,S2,其中

s2=(s1,a)

S2={s2|s1S1b(s2,b)=s1}

3.s=s,F

4.F={s1,S1|s1S1}

可以证明这是接受语言

L的DFA,因此

L是正规语言(证明比较复杂,我们在此略去)。

分析这个题目超出的编译课程的范围。

但是如果理解了这儿的解答,那就掌握了证明正规语言的一种很重要的技巧。

下面我们说明,为什么这样定义DFAM。

长度为n的串w,若它是语言L的某个句子的前缀,那么从M的开始状态s,经n步转换,到达某个状态sn。

该串是否属于

L,取决于是否存在从sn开始到某个接受状态的路径,其长度为n。

怎样判断是否存在这样的到某个接受状态的路径呢?

我们可以在M的状态转换图上按下面的步骤办。

1.首先找出从任意接受状态逆向任意走一步能到达的所有状态,把这个状态集合称做R1。

2.再找出从R1的任意状态逆向任意走一步能到达的所有状态,把这个状态集合

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1