收藏 分销(赏)

c语言编程NFA确定化.doc

上传人:Fis****915 文档编号:551785 上传时间:2023-12-06 格式:DOC 页数:8 大小:69KB 下载积分:6 金币
下载 相关 举报
c语言编程NFA确定化.doc_第1页
第1页 / 共8页
c语言编程NFA确定化.doc_第2页
第2页 / 共8页


点击查看更多>>
资源描述
NFA确定化为DFA 1.实验目的 设计并实现将NFA确定化为DFA的子集构造算法,从而更好地理解有限自动机之间的等价性,掌握词法分析器自动产生器的构造技术。该算法也是构造LR分析器的基础。 2.实验要求 设计并实现计算状态集合I的ε闭包的算法ε_Closure(I)和转换函数Move(I,a),并在此基础上实现子集构造算法Subset_Construction。利用该从NFA到DFA的转换程序Subset_Construction,任意输入一个NFA N=(S,Σ,δ,s0,F),输出一个接收同一语言的DFA M=(S’,Σ,δ’,s0’,F’)。 3.实验内容 (1) 令I是NFA N的状态集S的一个子集,I的ε闭包的ε_Closure(I)构造规则如下: (a) 若s∈I,则s∈ε_Closure(I); (b) 若s∈ε_Closure(I)且δ(s, ε)=s’而s’ ∉ε_Closure(I) ,则s’∈ε_Closure(I) 根据上面的规则,下面给出了一个计算I的ε闭包的算法ε_Closure(I)。 SET S; SETε_Closure(input) SET *input; { S=input; /* 初始化 */ push(); /* 把输入状态集中的全部状态压入栈中 */ while(栈非空){ Nfa_state i; pop(); /* 把栈顶元素弹出并送入i */ if(存在δ(i, ε)=j) if(j不在S中) { 把i加到S中; 把j压入栈中; } } return S; /* 返回ε_Closure(input)集合 */ } 完成上述算法的设计。 (2) 令I是NFA N的状态集S的一个子集,a∈Σ, 转换函数Move(I,a)定义为: Move(I,a)= ε_Closure(J) 其中,J={s’|s∈I且δ(s,a)=s’} 转换函数Move(I,a)的设计通过调用ε_Closure(input)实现,完成该函数的设计。 (3) 从NFA N构造一个与其等价的DFA M的子集构造算法,就是要为DFA M构造状态转换表Trans,表中的每个状态是NFA N状态的集合,DFA M将“并行”地模拟NFA N面对输入符号串所有可能的移动。下面给出了子集构造算法Subset_Construction的框架,请完成其设计过程。 有关数据结构: States[] 是一个M的数组,每个状态有两个域,set域存放N的状态集合,flg域为一标识。 Trans[] 是M的转移矩阵(输入字母表Σ元素个数×最大状态数),Trans[i][a]=下一状态。 i M的当前状态号 a 输入符号,a∈Σ Nstates[] M的下一新状态号 S 定义M的一个状态的N的状态集 初始化: States[0].set=ε_Closure({N的初态}) States[0].flg=FALSE Nstates=1 i=0 S=Ф Trans初始化为无状态’-’ while(States[i]的flg为FALSE){ States[i].flg=TRUE; for(每个输入符号a∈Σ){ S=ε_Closure(Move(States[i].set,a)); if(S非空) if(States中没有set域等于 S的状态){ States[Nstates].set=S; States[Nstates].flg=FALSE; Trans[i][a]= Nstates++; } else Trans[i][a]= States中一个set域为S的下标; } } 此算法的输出M主要由Trans矩阵描述,其中省略了每个状态是否为终态的描述,应加以完善。 4.实验程序; #include<iostream> #include<string> #define MAXS 100 using namespace std; string NODE; //结点集合 string CHANGE; //终结符集合 int N; //NFA边数 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<<"请输入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-clouse for(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); //输出DFA cout<<"其中终态为:"<<endnode<<endl; } 5.. 实验截图:
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服