有限自动机
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《编译原理》之有限自动机确定化程序
作者:ninstein 日期:2007-03-28
字体大小: 小中大
这个学期开了《编译原理》,感觉学起来还是有点难度的,因此得多练习练习,在一次作业过程中,发现用子集法求状态转化矩阵的时候,当正规式比较复杂[如
(00|11)*((01|10)(00|11)*(01|10)(00|11)*)*]的时候,手工操作很难保证每步的正确性,于是引发了用程序实现的想法,于是几个工作小时后便有了这么一堆不怎么地道的代码。
如果你想看懂本程序,请事先作好心理准备,不必计较,我不是在怀疑你的代码阅读水平,而是在质疑自己的编码水准:)
F&Q:
F:本程序能用来做什么?
Q:1.用来被你分析,后面有源代码;2.用来作《编译原理》的练习[当然只是与NFA-->DFA相关的题目] F:是不是真正的编译器里有类似本程序的算法?
Q:我也不清楚,因为这个程序的出现完全只是结合几条法则通过笨拙的向量结构实现的,但是编译器应该是有将非确定有限自动机转化为确定有限自动机这一步的
F:如何使用本程序?
A:譬如有正规式1(0|1)*101,要求得到其DFA,那么我们先可以手工划出其NFA状态转换图[如下图所示] 然后运行本程序并对照这张图严格输入相关数据,输入数据结束后将得到运行结果,下面是整个程序运行过程中产生的字符:[小提示:右击程序字符界面选择“全选”然后按回车,这时候字符界面上显示的所有文字将复制到剪切板,你可以将内容粘贴到文本编辑器中]
PS:如果你的NFA状态转化图比较复杂,建议采用专家模式输入,专家模式采用紧奏模式输入数据这样,你可以预先将输入数据编辑好然后粘贴进运行窗口[点运行窗口左上角“编辑”-“粘贴”] 避免中途输错一个数据导致输入的所有数据无效。
//////////////RUN/////////////
采用专家模式输入空格否则输入其他键(如果你是首次使用请不要采用专家模式)
输入终结符总数([1,20]): 2
输入第1 个终结符: 0
输入第2 个终结符: 1
=============================
输入结点总数[包括开始和结束结点]([1,100]): 7
输入第1个结点的代号[只允许数字-2为X -1为Y]: -2
输入这个结点的出度[即有多少条从这个结点出发的弧]([0,8]): 1
输入当前结点的第1 条出发弧所到达的结点: 0
输入当前结点的第1 条出发弧所花费的代价[空弧用#表示]: 1
输入第2个结点的代号[只允许数字-2为X -1为Y]: 0
输入这个结点的出度[即有多少条从这个结点出发的弧]([0,8]): 1
输入当前结点的第1 条出发弧所到达的结点: 1
输入当前结点的第1 条出发弧所花费的代价[空弧用#表示]: #
输入第3个结点的代号[只允许数字-2为X -1为Y]: 1
输入这个结点的出度[即有多少条从这个结点出发的弧]([0,8]): 3
输入当前结点的第1 条出发弧所到达的结点: 1
输入当前结点的第1 条出发弧所花费的代价[空弧用#表示]: 0
输入当前结点的第2 条出发弧所到达的结点: 1
输入当前结点的第2 条出发弧所花费的代价[空弧用#表示]: 1
输入当前结点的第3 条出发弧所到达的结点: 2
输入当前结点的第3 条出发弧所花费的代价[空弧用#表示]: #
输入第4个结点的代号[只允许数字-2为X -1为Y]: 2
输入这个结点的出度[即有多少条从这个结点出发的弧]([0,8]): 1
输入当前结点的第1 条出发弧所到达的结点: 3
输入当前结点的第1 条出发弧所花费的代价[空弧用#表示]: 1
输入第5个结点的代号[只允许数字-2为X -1为Y]: 3
输入这个结点的出度[即有多少条从这个结点出发的弧]([0,8]): 1
输入当前结点的第1 条出发弧所到达的结点: 4
输入当前结点的第1 条出发弧所花费的代价[空弧用#表示]: 0
输入第6个结点的代号[只允许数字-2为X -1为Y]: 4
输入这个结点的出度[即有多少条从这个结点出发的弧]([0,8]): 1
输入当前结点的第1 条出发弧所到达的结点: -1
输入当前结点的第1 条出发弧所花费的代价[空弧用#表示]: 1
输入第7个结点的代号[只允许数字-2为X -1为Y]: -1
通过子集法求得的状态转换矩阵为:
I I0 I1
--------------------------
{X} ---- {0 , 1 , 2}
{0 , 1 , 2} {1 , 2} {1 , 2 , 3}
{1 , 2} {1 , 2} {1 , 2 , 3}
{1 , 2 , 3} {1 , 2 , 4} {1 , 2 , 3}
{1 , 2 , 4} {1 , 2} {Y , 1 , 2 , 3}
{Y , 1 , 2 , 3} {1 , 2 , 4} {1 , 2 , 3}
重命名后的状态转化矩阵为:
I I0 I1
--------------
0 -- 1
1 2 3
2 2 3
3 4 3
4 2 5
5 4 3
Press any key exit.
///////////END RUN///////////
////一个采用专家模式输入数据的实例//////
采用专家模式输入空格否则输入其他键(如果你是首次使用请不要采用专家模式)
输入数据[数据间用一个空格隔开]:
2 0 1 20 -2 1 0 # 0
3 1 0 3 # 2 1 1 1 0 0 2 1 0 1 3 2
4 # -1 # 4 2
5 0
6 1 5 1
7 1 6 1 7 0 7 1
8 # 8 3
9 0 11 # 10 1 9 1 8 0 10 1 8 1 11 2 12 0 14 1 12 1 13 1 13 1 15 # 14 1 13 0 15 3 16 0 3 # 17 1 16 1 15 0 17 1 15 1 -1
通过子集法求得的状态转换矩阵为:
I I0 I1