当前位置:文档之家› 安徽大学编译原理试验斯

安徽大学编译原理试验斯

不确定的有穷自动机的化简2015年11月25日星期三班级:软件工程学号: E21314003 姓名:李世1. 目的与要求通过设计、编写和调试,将不确定的有穷自动机转换为与之等价的确定的有穷自动机的程序,使学生了解子集法。

掌握转换过程中的相关概念和方法。

DFA的表现形式可以是表格或图形。

2. 理论基础有穷自动机(也称有限自动机)作为一种识别装置,它能准确地识别正规集,即识别正规式所表示的集合. 应用有穷自动机这个理论,为词法分析程序的自动构造寻找有效的方法和工具。

有穷自动机分为两类,即,确定的有穷自动机(Deterministic Finite Automata)和不确定的有穷自动机(Nondeterministic Finite Automata) 。

(1) 不确定的有穷自动机的定义:一个不确定的有穷自动机(NFA)M是一个五元组:NFA M={K,Σ,f,S,Z},其中:K为状态的有穷非空集;Σ 为有穷输入字母表;f为K× Σ* 到K的子集(2K)的一种映射, 2K表示K的幂集(f不是一个单值函数);S⊆K是初始状态集;Z ⊆K为终止状态集.例子:NFA M=({S,P,Z},{0,1},f,{S,P},{Z}),其中:f(S,0)={P}//函数的结果为集合f(S,1)={S,Z}f(P,1)={Z}f(Z,0)={P}f(Z,1)={P}状态图表示为:矩阵表示为:(2) 确定的有穷自动机的定义:一个确定的有穷自动机(DFA)M 是一个五元组:M=(K,Σ,f,S,Z)其中:K是一个有穷集,它的每个元素称为一个状态;Σ是一个有穷字母表,它的每个元素称为一个输入符号,所以也称Σ为输入符号表;f是转换函数,是在K×Σ→K上的映射,即,如f(ki,a)=kj,(ki ∈K,kj∈K)就意味着,当前状态为ki,输入符为a时,将转换为下一个状态kj,我们把kj称作ki的一个后继状态;S∈K是唯一的一个初态;Z⊂ K是一个终态集,终态也称可接受状态或结束状态。

例子:DFA M=({S,U,V,Q},{a,b},f,S,{Q}),其中f定义为:f(S,a)=U f(V,a)=Uf(S,b)=V f(V,b)=Qf(U,a)=Q f(Q,a)=Qf(U,b)=V f(Q,b)=Q状态图表示为:矩阵表示为:(3) 确定有限自动机和不确定有限自动机DFA是NFA的特例。

对每个NFA N一定存在一个DFA M,使得L(M)=L(N)。

对每个NFA N存在着与之等价的DFA M。

有一种算法,将NFA转换成接受同样语言的DFA.这种算法称为子集法.子集法的基本思想:让DFA的每一个状态对应NFA的一组状态,也就是让DFA使用它的状态去记录在NFA读入一个输入符号后可能达到的所有状态。

注意:与某一NFA等价的DFA不唯一.a) 定义对状态集合I的几个有关运算:状态集合I的ε-闭包:表示为ε-closure(I),定义为一状态集,是状态集I中的任何状态S经任意条ε弧而能到达的状态的集合。

状态集合I中的任何状态S都属于ε-closure(I)。

状态集合I的a弧转换:表示为move(I, a)定义为状态集合J,其中J是所有那些可从I中的某一状态经过一条a弧而到达的状态的全体。

三、调试测试四、程序源代码#include<iostream> #include<string>#define MAXS 100using namespace std;string NODE;string CHANGE;int N;struct edge{string first;string change;string last;};struct chan{string ltab;string jihe[MAXS];};void kong(int a){int i;for(i=0;i<a;i++)cout<<' ';}//排序void paixu(string &a){int i,j;char b;for(j=0;j<a.length();j++)for(i=0;i<a.length();i++)if(NODE.find(a[i])>NODE.find(a[i+1])) {b=a[i];a[i]=a[i+1];a[i+1]=b;}}void eclouse(char c,string &he,edge b[]) {int k;for(k=0;k<N;k++){if(c==b[k].first[0])if(b[k].change=="*"){if(he.find(b[k].last)>he.length())he+=b[k].last;eclouse(b[k].last[0],he,b);}}}void move(chan &he,int m,edge b[]){int i,j,k,l;k=he.ltab.length();l=he.jihe[m].length();for(i=0;i<k;i++)for(j=0;j<N;j++)if((CHANGE[m]==b[j].change[0])&&(he.ltab[i]==b[j].first[0]))if(he.jihe[m].find(b[j].last[0])>he.jihe[m].length())he.jihe[m]+=b[j].last[0];for(i=0;i<l;i++)for(j=0;j<N;j++)if((CHANGE[m]==b[j].change[0])&&(he.jihe[m][i]==b[j].first[0]))if(he.jihe[m].find(b[j].last[0])>he.jihe[m].length())he.jihe[m]+=b[j].last[0];}//输出void outputfa(int len,int h,chan *t){int i,j,m;cout<<" I ";for(i=0;i<len;i++)cout<<'I'<<CHANGE[i]<<" ";cout<<endl<<"-------------------------"<<endl;for(i=0;i<h;i++){cout<<' '<<t[i].ltab;m=t[i].ltab.length();for(j=0;j<len;j++){kong(8-m);m=t[i].jihe[j].length();cout<<t[i].jihe[j];}cout<<endl;}}void main(){edge *b=new edge[MAXS];int i,j,k,m,n,h,x,y,len;bool flag;string jh[MAXS],endnode,ednode,sta;cout<<"********************************************"<<endl;cout<<"* 页式地址重定位模拟 *"<<endl;cout<<"* 作者:李世 E21314003 *"<<endl;cout<<"* 13级软件工程 *"<<endl;cout<<"********************************************"<<endl;cout<<"请输入NFA各边信息(起点条件[空为*] 终点),以#结束:"<<endl;for(i=0;i<MAXS;i++){cin>>b[i].first;if(b[i].first=="#") break;cin>>b[i].change>>b[i].last;} N=i; /*for(j=0;j<N;j++) cout<<b[j].first<<b[j].change<<b[j].last<<endl;*/ for(i=0;i<N;i++){if(NODE.find(b[i].first)>NODE.length())NODE+=b[i].first;if(NODE.find(b[i].last)>NODE.length())NODE+=b[i].last;if((CHANGE.find(b[i].change)>CHANGE.length())&&(b[i].change!="*")) CHANGE+=b[i].change;}len=CHANGE.length();cout<<"结点中属于终态的是:"<<endl;cin>>endnode;for(i=0;i<endnode.length();i++)if(NODE.find(endnode[i])>NODE.length()){cout<<"所输终态不在集合中,错误!"<<endl;return;} //cout<<"endnode="<<endnode<<endl;chan *t=new chan[MAXS];t[0].ltab=b[0].first;h=1;eclouse(b[0].first[0],t[0].ltab,b); //求e-clouse//cout<<t[0].ltab<<endl;for(i=0;i<h;i++){for(j=0;j<t[i].ltab.length();j++)for(m=0;m<len;m++)eclouse(t[i].ltab[j],t[i].jihe[m],b); //求e-clousefor(k=0;k<len;k++){ //cout<<t[i].jihe[k]<<"->";move(t[i],k,b); //求move(I,a)//cout<<t[i].jihe[k]<<endl;for(j=0;j<t[i].jihe[k].length();j++)eclouse(t[i].jihe[k][j],t[i].jihe[k],b); //求e-clouse }for(j=0;j<len;j++){paixu(t[i].jihe[j]); //对集合排序以便比较for(k=0;k<h;k++){flag=operator==(t[k].ltab,t[i].jihe[j]);if(flag)break;}if(!flag&&t[i].jihe[j].length())t[h++].ltab=t[i].jihe[j];}}cout<<endl<<"状态转换矩阵如下:"<<endl;outputfa(len,h,t); //输出状态转换矩阵//状态重新命名string *d=new string[h];NODE.erase();cout<<endl<<"重命名:"<<endl;for(i=0;i<h;i++){sta=t[i].ltab;t[i].ltab.erase();t[i].ltab='A'+i;NODE+=t[i].ltab;cout<<'{'<<sta<<"}="<<t[i].ltab<<endl;for(j=0;j<endnode.length();j++)if(sta.find(endnode[j])<sta.length())d[1]=ednode+=t[i].ltab;for(k=0;k<h;k++)for(m=0;m<len;m++)if(sta==t[k].jihe[m])t[k].jihe[m]=t[i].ltab;}for(i=0;i<NODE.length();i++)if(ednode.find(NODE[i])>ednode.length())d[0]+=NODE[i];endnode=ednode;cout<<endl<<"DFA如下:"<<endl;outputfa(len,h,t); //输出DFAcout<<"其中终态为:"<<endnode<<endl; //DFA最小化m=2;sta.erase();flag=0;for(i=0;i<m;i++){//cout<<"d["<<i<<"]="<<d[i]<<endl;for(k=0;k<len;k++){//cout<<"I"<<CHANGE[k]<<endl;y=m;for(j=0;j<d[i].length();j++){for(n=0;n<y;n++){if(d[n].find(t[NODE.find(d[i][j])].jihe[k])<d[n].length()||t[NODE.find(d[i][j])].ji he[k].length()==0){if(t[NODE.find(d[i][j])].jihe[k].length()==0)x=m;elsex=n;if(!sta.length()){sta+=x+48;}elseif(sta[0]!=x+48){d[m]+=d[i][j];flag=1;d[i].erase(j,1); //cout<<d[i]<<endl;j--;}break; //跳出n}}//n}//jif(flag){m++;flag=0;} //cout<<"sta="<<sta<<endl;sta.erase();}//k}//icout<<endl<<"集合划分:";for(i=0;i<m;i++)cout<<"{"<<d[i]<<"} ";cout<<endl; //状态重新命名chan *md=new chan[m];NODE.erase();cout<<endl<<"重命名:"<<endl;for(i=0;i<m;i++){md[i].ltab='A'+i;NODE+=md[i].ltab;cout<<"{"<<d[i]<<"}="<<md[i].ltab<<endl;}for(i=0;i<m;i++)for(k=0;k<len;k++)for(j=0;j<h;j++){if(d[i][0]==t[j].ltab[0]){for(n=0;n<m;n++){if(!t[j].jihe[k].length())break;elseif(d[n].find(t[j].jihe[k])<d[n].length()){md[i].jihe[k]=md[n].ltab;break;}}break;}}ednode.erase();for(i=0;i<m;i++)for(j=0;j<endnode.length();j++)if(d[i].find(endnode[j])<d[i].length()&&ednode.find(md[i].ltab))ednode+=md[i].ltab;endnode=ednode;cout<<endl<<"最小化DFA如下:"<<endl;outputfa(len,m,md);cout<<"其中终态为:"<<endnode<<endl;}。

相关主题