头文件。。。。 #ifndef dfanfa_h #define dfanfa_h #include <stdio.h> #include <stdlib.h> #include <string.h> /*定义特殊值*/ #define BUF_SIZE 4096 //定义每行读取最大字节数 #define EXPRESSION_SIZE 1024 //定义表达式最大长度 #define NFA_LEN 64 //NFA状态数 #define NFA_SYMBOLS 32 //NFA字符数 #define NFA_TRANS 8 //NFA最多状态转换数 #define Ee 0 //空状态 #define NOSTATE -1 //定义NFA无状态转换值 #define SIMBOLS_MAX 256 //定义最大字符集 #define DFA_LEN 64 //DFA状态数 #define DFA_SYMBOLS 32 //DFA字符数 #define NFASTACK_SIZE 512 //定义NFA栈的长度 #define AND '^' //定义NFA并操作符 #define OR '|' //定义NFA与操作符 #define ECLOSURE '*' //定义NFA e闭包操作符 #define CLOSURE '~' //定义NFA正闭包操作符 #define ONECLOSURE '?' //0个或1个实例 /*定义类型*/ typedef enum{FALSE,TRUE} BOOL; //定义BOOL类型 typedef int NFAstate; //定义NFA状态类型 typedef NFAstate NFAMatrixItem[NFA_TRANS]; //定义NFA矩阵元素类型,也就是NFAstate[NFA_TRANS]数组 typedef struct nfa //定义NFA { NFAstate *states; //状态集 int states_len; //状态数 char *symbols; //字符集 int symbols_len; //字符数 NFAMatrixItem **matrix; //转换矩阵 NFAstate start; //开始状态 NFAstate *finals; //定义终结状态集 int finals_len; //终结状体数 int symbols_index[SIMBOLS_MAX]; //字符映射表 }NFA; typedef int DFAstate; //定义DFA状态类型 typedef int DFAStateId; //定义状态标号,即状态数组的下标 typedef DFAStateId DFAMatrixItem; //定义DFA矩阵元素类型,也就是DFAstate typedef struct dfa //定义DFA { DFAstate *states; //状态集 int states_len; //状态数 char *symbols; //字符集 int symbols_len; //字符数 DFAMatrixItem **matrix; //转换矩阵 DFAstate start; //开始状体 DFAstate *finals; //定义终结状态集 int finals_len; //终结状体数 int symbols_index[SIMBOLS_MAX]; //字符映射表 }DFA; typedef struct dnfastate //定义DNFA状态 { int len; //所含NFA状态数 NFAstate *NFAstates; //所含NFA数组 DFAstate id; //NFA的标号 }DNFAstate; typedef struct dividedstate //定义 dividedstate { //记录dfa->states被划分的情况 DFAstate *states; //DFAstate数组 int states_len; //数组长度 DFAStateId *ids; //记录 DFAstate数组的分割点 int ids_len; //数组DFAstate被分为段数 }DividedState; typedef struct nfawithexpr //定义带正则式的NFA { char expr[EXPRESSION_SIZE]; //正则表达式 NFA *nfa; }NFAwithExpr; typedef struct dfawithexpr //定义带正则式的DFA { char expr[EXPRESSION_SIZE]; //正则表达式 DFA *dfa; }DFAwithExpr; /*函数列表*/ static BOOL in_symbols(char ch,char *symbols,int len); void destroy_NFA(NFA *nfa); void NFA_addState(NFA *nfa,NFAstate state); BOOL NFA_execute(NFA *nfa,char *expr); int in_NFAstates(NFAstate state,NFAstate *p_states,int len); void destroy_DFA(DFA *dfa); BOOL DFA_execute(DFA *dfa,char *expr); int in_DFAstates(DFAstate state,DFAstate *p_states,int len); DFAstate in_DNFAstates(DNFAstate *dnstate,DNFAstate *Dnstates,int dnfalen); void add_DNFAState(DNFAstate *dnstate,DNFAstate *Dnstates,int *states_len,NFA *nfa); DNFAstate* get_DNFAstates(NFA *nfa,DNFAstate *Dnstates,int *states_len); DFAstate* get_DFAfinals(NFA *nfa,DNFAstate *Dnstates,int dfalen,DFAstate *Dfinals,int *flen); DFAstate get_DFAstart(NFA *nfa,DNFAstate *Dnstates,int dfalen); DFAMatrixItem** get_DFAMatrix(NFA *nfa,DNFAstate *Dnstates,int states_len,DFAMatrixItem** DFAmatrix,int *DFAsymbols_index); DFA* NFAtoDFA(NFA *nfa); DFAStateId get_dividedID(DFAstate state,DividedState* Divided); BOOL insertID(DFAStateId id,DFAStateId* ids,int len,int pos); BOOL states_dividedable(DFA *dfa,DFAstate *states,int len,int symbol_index,DividedState* Divided); void divide_DFAstates(DFA *dfa,DividedState* Divided,DFAStateId cur,int index); DividedState* get_DividedState(DFA *dfa); void destroy_DividedState(DividedState *divided); DFA* DFA_simplify(DFA *dfa); NFA* NFA_Eclosure(NFA *nfa1); NFA* NFA_closure(NFA *nfa1); NFA* NFA_or(NFA *nfa1,NFA *nfa2); NFA* NFA_and(NFA *nfa1,NFA *nfa2); BOOL is_letter(char ch); BOOL is_digit(char ch); BOOL is_NFAoperator(char ch); BOOL is_delim(char ch); char to_upper(char ch); void term(char **lookahead); void term_rest(char **lookahead); void expr(char **lookahead); void expr_rest(char **lookahead); void factor(char **lookahead); void factor_rest(char **lookahead); void atom(char **lookahead); void expr_traverse(char **lookahead); void expr_insert(char ch,char *s,int len,int pos); char expr_delete(char *s,int len,int pos); void trim_delim(char *s); void expr_trans(char *expr); BOOL is_LegalExpression(char *expr); static BOOL in_NFAs(NFA* n,NFA** ns,int len); NFA* create_singleNFA(char ch); NFA* ExprtoNFA(char *exp); void print_NFAwithExpr(NFAwithExpr *nfawe,FILE *fp); void destroy_NFAwithExpr(NFAwithExpr *nfawe); NFAwithExpr* get_NFAwithExpr(FILE *fp); void print_DFAwithExpr(DFAwithExpr *dfawe,FILE *fp); void destroy_DFAwithExpr(DFAwithExpr *dfawe); DFAwithExpr* get_DFAwithExpr(FILE *fp); void DFANFA_Menu(void); int get_Choice(void); char get_ChoiceYN(void); char* get_Expression(void); void System_ExprToNfa(void); void DFANFA_System(void); void print_direction(FILE *fp); void System_direction(void); void System_ExprToNfa(void); void System_NFAtoDFA(void); void System_DFAsimplify(void); void System_NFAsimulate(void); void System_DFAsimulate(void); void System_Exit(void); #endif 实现文件 #include "dfanfa.h" /*定义全局变量*/ static BOOL *NFA_alreadyOn; //记录NFA状态是否被添加情况 static char *GlobalPost_Expr; //后缀表达式 static int GlobalExpr_Index; //记录后缀表达式长度 /*----------------------------------------------------------------------------*/ /* 判断当前字符是否在字符集中*/ /*----------------------------------------------------------------------------*/ static BOOL in_symbols(char ch,char *symbols,int len) { int i; for(i=0;i<len;++i) { if(symbols[i]==ch) return TRUE; } return FALSE; } /*----------------------------------------------------------------------------*/ /* 销毁NFA*/ /*----------------------------------------------------------------------------*/ void destroy_NFA(NFA *nfa) { if(nfa->states!=NULL) { free(nfa->states); nfa->states=NULL; nfa->states_len=0; } if(nfa->symbols!=NULL) { free(nfa->symbols); nfa->symbols=NULL; nfa->symbols_len=0; } if(nfa->finals!=NULL) { free(nfa->finals); nfa->finals=NULL; nfa->finals_len=0; } if(nfa->matrix!=NULL) { free(nfa->matrix); nfa->matrix=NULL; } if(nfa!=NULL) { free(nfa); nfa=NULL; } } /*----------------------------------------------------------------------------*/ /*添加状态 ,令 alreadyOn[state]为 TRUE,表示添加状态state */ /*----------------------------------------------------------------------------*/ void NFA_addState(NFA *nfa,NFAstate state) { NFAstate *T,t; NFA_alreadyOn[state]=TRUE; if(nfa->symbols_index[Ee]==-1) return; T=nfa->matrix[state][nfa->symbols_index[Ee]]; while((t=*T++)!=NOSTATE) { if(!NFA_alreadyOn[t]) NFA_addState(nfa,t); } } /*----------------------------------------------------------------------------*/ /* 判断state是否在NFA状态集states中 state为NFA状态 p_states状态集 len为状态数*/ /*----------------------------------------------------------------------------*/ int in_NFAstates(NFAstate state,NFAstate *states,int len) { int i; for(i=0;i<len;++i) { if(states[i]==state) return i; } return NOSTATE; } /*----------------------------------------------------------------------------*/ /* 模拟NFA,如果字符串能到达终结状态返回TRUE expr为输入字符串 */ /*----------------------------------------------------------------------------*/ BOOL NFA_execute(NFA *nfa,char *expr) { NFAstate *newstate,*oldstate,*temp; NFAstate s0=nfa->start; int i,states=nfa->states_len,index=0; char ch; NFA_alreadyOn=(BOOL*)malloc(nfa->states_len*sizeof(BOOL)); memset(NFA_alreadyOn,FALSE,nfa->states_len*sizeof(BOOL)); if(*expr==0) { NFA_addState(nfa,nfa->start); for(i=nfa->start;i<nfa->states_len;++i)//结果保存到newstate { if(NFA_alreadyOn[i]) { if(in_NFAstates(i,nfa->finals,nfa->finals_len)!=NOSTATE) { free(NFA_alreadyOn); return TRUE; } } } free(NFA_alreadyOn); return FALSE; } newstate=(NFAstate *)malloc(states*sizeof(NFAstate)); oldstate=(NFAstate *)malloc(states*sizeof(NFAstate)); memset(newstate,NOSTATE,states*sizeof(NFAstate)); memset(oldstate,NOSTATE,states*sizeof(NFAstate)); NFA_addState(nfa,nfa->start); for(i=nfa->start;i<nfa->states_len;++i) { if(NFA_alreadyOn[i]) { newstate[index++]=i; NFA_alreadyOn[i]=FALSE; } } while((ch=*expr++) !='/0') { if(!in_symbols(ch,nfa->symbols,nfa->symbols_len)) { return FALSE; } for(i=0;i<index;++i) { oldstate[i]=newstate[i]; newstate[i]=NOSTATE; } for(i=0;i<index;++i) { temp=(nfa->matrix) [oldstate[i]][nfa->symbols_index[ch]]; while(*temp!=NOSTATE) NFA_addState(nfa,*temp++); } for(i=0,index=0;i<states;++i) { if(NFA_alreadyOn[i]) { newstate[index++]=i; NFA_alreadyOn[i]=FALSE; } } } for(i=0;i<nfa->states_len;++i) { if(in_NFAstates(newstate[i],nfa->finals,nfa->finals_len)!=NOSTATE) { free(newstate); free(oldstate); return TRUE; } } free(newstate); free(oldstate); free(NFA_alreadyOn); return FALSE; } /*----------------------------------------------------------------------------*/ /* 销毁DFA*/ /*----------------------------------------------------------------------------*/ void destroy_DFA(DFA *dfa) { if(dfa->states!=NULL) { free(dfa->states); dfa->states=NULL; dfa->states_len=0; } if(dfa->symbols!=NULL) { free(dfa->symbols); dfa->symbols=NULL; dfa->symbols_len=0; } if(dfa->finals!=NULL) { free(dfa->finals); dfa->finals=NULL; dfa->finals_len=0; } if(dfa->matrix!=NULL) { free(dfa->matrix); dfa->matrix=NULL; } if(dfa!=NULL) { free(dfa); dfa=NULL; } } /*----------------------------------------------------------------------------*/ /* 判断state是否在DFA状态集states中 state为DFA状态 states状态集 states_len为状态数*/ /*----------------------------------------------------------------------------*/ int in_DFAstates(DFAstate state,DFAstate *states,int states_len) { int i; for(i=0;i<states_len;++i) { if(states[i]==state) return i; } return NOSTATE; } /*----------------------------------------------------------------------------*/ /* 模拟DFA,如果字符串能到达终结状态返回TRUE expr为输入字符串 */ /*----------------------------------------------------------------------------*/ BOOL DFA_execute(DFA *dfa,char *expr) { DFAstate state=dfa->start; char ch; DFAMatrixItem state_index=0; if((state_index=in_DFAstates(state,dfa->states,dfa->states_len))==NOSTATE) return FALSE; while((ch=*expr++) !='/0') { if(!in_symbols(ch,dfa->symbols,dfa->symbols_len)) return FALSE; if(dfa->symbols_index[ch]==-1) return FALSE; state_index=(dfa->matrix)[state_index][dfa->symbols_index[ch]]; if(state_index==NOSTATE) return FALSE; } state=dfa->states[state_index]; if(in_DFAstates(state,dfa->finals,dfa->finals_len)!=NOSTATE) return TRUE; else return FALSE; } /*----------------------------------------------------------------------------*/ /* 判断DFA dnstate状态是否在 Dnstates数组里 dnstate为一个DNFAstate状态 Dnstates 为DNFAstate状态集合 dfalen 为 Dnstates数组长度 */ /*----------------------------------------------------------------------------*/ DFAstate in_DNFAstates(DNFAstate *dnstate,DNFAstate *Dnstates,int states_len) { int i,j=0; for(i=0;i<states_len;++i) { if(dnstate->len==Dnstates[i].len) { for(j=0;j<dnstate->len;++j) if(dnstate->NFAstates[j]!=Dnstates[i].NFAstates[j]) break; } else continue; if(j==dnstate->len) return i; } return NOSTATE; } /*----------------------------------------------------------------------------*/ /* 添加状态 dnstate到DNFAstate状态数组 Dnstates dnstate为要添加的DFA状态 Dnstates为状态数组 这里要用到nfa符号集和转换矩阵*/ /*----------------------------------------------------------------------------*/ void add_DNFAState(DNFAstate *dnstate,DNFAstate *Dnstates,int *states_len,NFA *nfa) { DNFAstate newDNstate; NFAstate *temp; int i,j,index=0,dfaid; newDNstate.NFAstates=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); memset(newDNstate.NFAstates,NOSTATE,nfa->states_len*sizeof(NFAstate)); for(i=0;i<dnstate->len;++i) Dnstates[*states_len].NFAstates[i]=dnstate->NFAstates[i]; Dnstates[*states_len].len=dnstate->len; Dnstates[*states_len].id=dnstate->id; ++(*states_len); for(j=0;j<nfa->symbols_len;++j) { if(nfa->symbols[j]==Ee) continue; for(i=0;i<dnstate->len;++i) { temp=(nfa->matrix)[dnstate->NFAstates[i]][j]; while(*temp!=NOSTATE) { NFA_addState(nfa,*temp++); } } for(index=0,i=nfa->start;i<nfa->states_len;++i) { if(NFA_alreadyOn[i]) { newDNstate.NFAstates[index++]=i; NFA_alreadyOn[i]=FALSE; } } newDNstate.len=index; if(index==0) continue; if((dfaid=in_DNFAstates(&newDNstate,Dnstates,*states_len))==NOSTATE ) { newDNstate.id=*states_len; add_DNFAState(&newDNstate,Dnstates,states_len,nfa); } newDNstate.id=NOSTATE; newDNstate.len=0; memset(newDNstate.NFAstates,NOSTATE,nfa->states_len*sizeof(NFAstate)); } free(newDNstate.NFAstates); } /*----------------------------------------------------------------------------*/ /* 由NFA获取DNFAstate数组,即建立每个DFA状态 到一个NFA状态集合 的映射 */ /* Dnstates为DNFAstate状态数组,states_len为数组长度 */ /* 这里要用到nfa开始状态*/ /*----------------------------------------------------------------------------*/ DNFAstate* get_DNFAstates(NFA *nfa,DNFAstate *Dnstates,int *states_len) { DNFAstate dnstate; int i,index=0; dnstate.NFAstates=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); memset(dnstate.NFAstates,NOSTATE,nfa->states_len*sizeof(NFAstate)); NFA_addState(nfa,nfa->start); for(i=nfa->start;i<nfa->states_len;++i) { if(NFA_alreadyOn[i]) { dnstate.NFAstates[index++]=i; NFA_alreadyOn[i]=FALSE; } } dnstate.len=index; dnstate.id=*states_len; add_DNFAState(&dnstate,Dnstates,states_len,nfa); free(dnstate.NFAstates); return Dnstates; } /*----------------------------------------------------------------------------*/ /* 返回DFA状态集的终结状态集 Dnstates为DNFAstate状态数组 dfalen为数组长度 Dfinals为DFA终结状态数组,flen为其长度 这里要用到nfa终结状态集*/ /*----------------------------------------------------------------------------*/ DFAstate* get_DFAfinals(NFA *nfa,DNFAstate *Dnstates,int states_len,DFAstate *finals,int *finals_len) { int i,j; for(i=0;i<states_len;++i) { for(j=0;j<Dnstates[i].len;++j) { if(in_NFAstates(Dnstates[i].NFAstates[j],nfa->finals,nfa->finals_len)!=NOSTATE) { *finals++=i; ++(*finals_len); break; } } } return finals; } /*----------------------------------------------------------------------------*/ /* 返回DFA状态集的初始状态 Dnstates为DFA状态数组 dfalen为数组长度 这里要用到nfa开始状态*/ /*----------------------------------------------------------------------------*/ DFAstate get_DFAstart(NFA *nfa,DNFAstate *Dnstates,int states_len) { int i,j; for(i=0;i<states_len;++i) { for(j=0;j<Dnstates[i].len;++j) { if(Dnstates[i].NFAstates[j]==nfa->start) { return i; } } } return NOSTATE; } /*----------------------------------------------------------------------------*/ /* 获取DFA转换矩阵 Dnstates为DFA状态数组,states_len为数组长度 DFAmatrix为转换的矩阵 DFAsymbols_index为DFA字符映射表 这里要用到nfa字符集,转换矩阵等*/ /*----------------------------------------------------------------------------*/ DFAMatrixItem** get_DFAMatrix(NFA *nfa,DNFAstate *Dnstates,int states_len,DFAMatrixItem** DFAmatrix,int *DFAsymbols_index) { DNFAstate newDNstate; DNFAstate *dnfa_temp; NFAstate *nfa_temp; char *s=nfa->symbols,ch; int i,j,k,index=0,dfaid,state_index,symbol_index; newDNstate.NFAstates=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); memset(newDNstate.NFAstates,NOSTATE,nfa->states_len*sizeof(NFAstate)); for(state_index=0;state_index<states_len;++state_index) { dnfa_temp=Dnstates+state_index; for(symbol_index=0;symbol_index<nfa->symbols_len;++symbol_index) { if(nfa->symbols[symbol_index]=='/0') continue; for(i=0;i<dnfa_temp->len;++i) { nfa_temp=(nfa->matrix)[dnfa_temp->NFAstates[i]][symbol_index]; while(*nfa_temp!=NOSTATE) NFA_addState(nfa,*nfa_temp++); } for(index=0,i=nfa->start;i<nfa->states_len;++i) { if(NFA_alreadyOn[i]) { newDNstate.NFAstates[index++]=i; NFA_alreadyOn[i]=FALSE; } } newDNstate.len=index; if(index==0) continue; dfaid=in_DNFAstates(&newDNstate,Dnstates,states_len); DFAmatrix[state_index][DFAsymbols_index[nfa->symbols[symbol_index]]]=dfaid; } } free(newDNstate.NFAstates); return DFAmatrix; } /*----------------------------------------------------------------------------*/ /* NFA转化为DFA(子集构造法)*/ /*----------------------------------------------------------------------------*/ DFA* NFAtoDFA(NFA *nfa) { DFA *dfa; int i,j,index=0; DNFAstate *DNstates; int states_len=0; char symbol; DNstates=(DNFAstate*)calloc(nfa->states_len,sizeof(DNFAstate)); for(i=0;i<nfa->states_len;++i) { DNstates[i].NFAstates=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); memset(DNstates[i].NFAstates,NOSTATE,nfa->states_len*sizeof(NFAstate)); } NFA_alreadyOn=(BOOL*)malloc(nfa->states_len*sizeof(BOOL)); memset(NFA_alreadyOn,FALSE,nfa->states_len*sizeof(BOOL)); if((dfa=(DFA*)malloc(sizeof(DFA)))==NULL) return NULL; dfa->start=states_len; get_DNFAstates(nfa,DNstates,&states_len); dfa->states=(DFAstate*) malloc(states_len*sizeof(DFAstate)); dfa->states_len=states_len; for(i=0;i<states_len;++i) dfa->states[i]=i; dfa->finals=(DFAstate*)malloc(nfa->states_len*sizeof(DFAstate)); dfa->finals_len=0; get_DFAfinals(nfa,DNstates,states_len,dfa->finals,&(dfa->finals_len)); dfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(dfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); for(i=0,index=0;i<nfa->symbols_len;++i) { symbol=nfa->symbols[i]; if(symbol!=Ee && !in_symbols(symbol,dfa->symbols,index)) { dfa->symbols[index]=symbol; dfa->symbols_index[symbol]=index; ++index; } } dfa->symbols_len=index; dfa->matrix=(DFAMatrixItem**)malloc(dfa->states_len*sizeof(DFAMatrixItem*)+dfa->states_len*dfa->symbols_len*sizeof(DFAMatrixItem)); for(i=0;i<states_len;++i) { (dfa->matrix)[i]=(DFAMatrixItem*)(dfa->matrix+dfa->states_len)+i*dfa->symbols_len; } memset(dfa->matrix+dfa->states_len,NOSTATE,dfa->states_len*dfa->symbols_len*sizeof(DFAMatrixItem)); get_DFAMatrix(nfa,DNstates,states_len,dfa->matrix,dfa->symbols_index); for(i=0;i<nfa->states_len;++i) free(DNstates[i].NFAstates); free(DNstates); free(NFA_alreadyOn); return dfa; } /*----------------------------------------------------------------------------*/ /* 获取DFA状态state在Divided->states数组中的分段号 */ /*----------------------------------------------------------------------------*/ DFAStateId get_dividedID(DFAstate state,DividedState* Divided) { int i,j,id=0; for(i=1;i<Divided->ids_len;++i) { for(j=Divided->ids[i-1]+1;j<=Divided->ids[i];++j) if(Divided->states[j]==state) return i-1; } return -1; } /*----------------------------------------------------------------------------*/ /* 判断DFA状态数组states对字符ch是否能分割 判断标准为:states中的每个状态面对ch的转换是否都在同一段中 这里需要dfa转换关系 states为DFA状态数组 len为其长度 symbol_index是字符在字符集中的位置 Divided记录分段状态*/ /*----------------------------------------------------------------------------*/ BOOL states_dividedable(DFA *dfa,DFAstate *states,int len,int symbol_index,DividedState* Divided) { int i=0,j; DFAStateId id; if(symbol_index>=dfa->symbols_len || symbol_index<0) return FALSE; if(1==len) return FALSE; id=get_dividedID((dfa->matrix)[states[i]][symbol_index],Divided); for(++i;i<len;++i) { if(get_dividedID((dfa->matrix)[states[i]][symbol_index],Divided)!=id) return TRUE; } return FALSE; } /*----------------------------------------------------------------------------*/ /* 判断DFA状态数组states对字符ch是否能分割 判断标准为:states中的每个状态面对ch的转换是否都在同一段中 这里需要dfa转换关系 states为DFA状态数组 len为其长度 symbol_index是字符在字符集中的位置 Divided记录分段状态*/ /*----------------------------------------------------------------------------*/ int is_dividedable(DFA *dfa,DividedState* Divided,int *index) { int symbol_index,i,states_len; DFAstate *states; for(symbol_index=0;symbol_index<dfa->symbols_len;++symbol_index) { for(i=1;i<Divided->ids_len;++i) { states=Divided->states+Divided->ids[i-1]+1; states_len=Divided->ids[i]-Divided->ids[i-1]; if(states_dividedable(dfa,states,states_len,symbol_index,Divided)) { *index=symbol_index; return i; } } } return -1; } /*----------------------------------------------------------------------------*/ /* 插入ID,到数组ids pos位置 len为ids数组长度 pos为要插入位置 */ /*----------------------------------------------------------------------------*/ BOOL insertID(DFAStateId id,DFAStateId* ids,int len,int pos) { int i; if(pos<0 || pos>len) return FALSE; for(i=len+1;i>pos;--i) { ids[i]=ids[i-1]; } ids[i]=id; return TRUE; } /*----------------------------------------------------------------------------*/ /* 分割DFA状态,一次只分两段 这里需要dfa转换关系 Divided记录分段状态 cur是要分的段 index是字符在字符集中的位置*/ /*----------------------------------------------------------------------------*/ void divide_DFAstates(DFA *dfa,DividedState* Divided,DFAStateId cur,int index) { int i,j,symbol_index; DFAstate *states; DFAstate *left,*right; int left_index=0,right_index=0,states_index=0,states_len; DFAStateId id; if(index>=dfa->symbols_len || index<0) return; if(cur>0 && cur<Divided->ids_len) { left=(DFAstate*)malloc(dfa->states_len*sizeof(DFAstate)); right=(DFAstate*)malloc(dfa->states_len*sizeof(DFAstate)); i=Divided->ids[cur-1]+1; states_index=i; states=Divided->states; left[left_index++]=states[i]; id=get_dividedID((dfa->matrix)[states[i]][index],Divided); for(++i;i<=Divided->ids[cur];++i) { if(get_dividedID((dfa->matrix)[states[i]][index],Divided)==id) { left[left_index++]=states[i]; } else right[right_index++]=states[i]; } for(i=0;i<left_index;++i) states[states_index++]=left[i]; for(i=0;i<right_index;++i) states[states_index++]=right[i]; if(cur>1) left_index=left_index+Divided->ids[cur-1]-Divided->ids[0]; insertID(left_index-1,Divided->ids,Divided->ids_len,cur); ++(Divided->ids_len); for(symbol_index=0;symbol_index<dfa->symbols_len;++symbol_index) { for(i=cur;i<Divided->ids_len;++i) { states=Divided->states+Divided->ids[i-1]+1; states_len=Divided->ids[i]-Divided->ids[i-1]; if(states_dividedable(dfa,states,states_len,symbol_index,Divided)) { divide_DFAstates(dfa,Divided,i,symbol_index); } } } free(left); free(right); } } /*----------------------------------------------------------------------------*/ /* 获取最初分段,记录在divided中 */ /* 初始化分为2段:终结状态 和 余下状态 */ /*----------------------------------------------------------------------------*/ DividedState* get_DividedState(DFA *dfa) { DFAstate *left,*right; int i,left_index=0,right_index=0; DividedState *divided; left=(DFAstate*)malloc(dfa->states_len*sizeof(DFAstate)); right=(DFAstate*)malloc(dfa->states_len*sizeof(DFAstate)); divided=(DividedState*) malloc(sizeof(DividedState)); divided->states_len=dfa->states_len; divided->states=(DFAstate*)malloc(dfa->states_len*sizeof(DFAstate)); divided->ids=(DFAStateId*)malloc((dfa->states_len+2)*sizeof(DFAStateId)); for(i=0;i<dfa->states_len;++i) { if(in_DFAstates((dfa->states)[i],dfa->finals,dfa->finals_len)!=NOSTATE) right[right_index++]=(dfa->states)[i]; else divided->states[left_index++]=(dfa->states)[i]; } if(left_index==0) { divided->ids_len=2; divided->ids[0]=-1; divided->ids[1]=right_index-1; for(i=0;i<right_index;++i) divided->states[i]=right[i]; free(left); free(right); return divided; } divided->ids_len=3; divided->ids[0]=-1; divided->ids[1]=left_index-1; divided->ids[2]=dfa->states_len-1; for(i=0;i<right_index;++i) divided->states[left_index++]=right[i]; free(left); free(right); return divided; } /*----------------------------------------------------------------------------*/ /* 销毁divided */ /*----------------------------------------------------------------------------*/ void destroy_DividedState(DividedState *divided) { if(divided->states!=NULL) { free(divided->states); divided->states=NULL; } if(divided->ids!=NULL) { free(divided->ids); divided->ids=NULL; } if(divided!=NULL) { free(divided); divided=NULL; } } /*----------------------------------------------------------------------------*/ /* 简化DFA(分割法)*/ /*----------------------------------------------------------------------------*/ DFA* DFA_simplify(DFA *dfa) { DFA *simpledfa; DividedState *divided; int symbol_index,i,j; int finalids_index=0,states_len; DFAStateId id,fid,currentID=1,indexID; DFAstate *states; char symbol; int cur; divided=get_DividedState(dfa); while((cur=is_dividedable(dfa,divided,&symbol_index))!=-1) { divide_DFAstates(dfa,divided,cur,symbol_index); } simpledfa=(DFA*) malloc(sizeof(DFA)); simpledfa->states=(DFAstate*)malloc((divided->ids_len-1)*sizeof(DFAstate)); simpledfa->states_len=divided->ids_len-1; for(i=0;i<simpledfa->states_len;++i) { simpledfa->states[i]=i; } simpledfa->symbols_len=dfa->symbols_len; simpledfa->symbols=(char*)malloc(simpledfa->symbols_len*sizeof(char)); memcpy(simpledfa->symbols,dfa->symbols,simpledfa->symbols_len*sizeof(char)); memcpy(simpledfa->symbols_index,dfa->symbols_index,SIMBOLS_MAX*sizeof(int)); simpledfa->start=get_dividedID(dfa->start,divided); i=0; simpledfa->finals=(DFAstate*)malloc(dfa->finals_len*sizeof(DFAstate)); fid=get_dividedID(dfa->finals[i],divided); simpledfa->finals[finalids_index++]=fid; for(++i;i<dfa->finals_len;++i) { id=get_dividedID(dfa->finals[i],divided); if(id!=fid && (in_DFAstates(id,simpledfa->finals,finalids_index)==NOSTATE)) simpledfa->finals[finalids_index++]=id; } simpledfa->finals_len=finalids_index; simpledfa->matrix=(DFAStateId**)malloc(simpledfa->states_len*sizeof(DFAStateId*) +simpledfa->states_len*simpledfa->symbols_len*sizeof(DFAStateId)); for(i=0;i<simpledfa->states_len;++i) simpledfa->matrix[i]=(DFAStateId*)(simpledfa->matrix+simpledfa->states_len)+ i*simpledfa->symbols_len; memset(simpledfa->matrix+simpledfa->states_len,NOSTATE,simpledfa->states_len*simpledfa->symbols_len*sizeof(DFAStateId)); for(i=0;i<simpledfa->states_len;++i) for(j=0;j<simpledfa->symbols_len;++j) { indexID=divided->states[divided->ids[i]+1]; if(indexID==-1) continue; id=get_dividedID(dfa->matrix[indexID][j],divided); if(id==-1) continue; simpledfa->matrix[i][j]=id; } destroy_DividedState(divided); return simpledfa; } /*----------------------------------------------------------------------------*/ /* NFA与(合并)操作*/ /*----------------------------------------------------------------------------*/ NFA* NFA_and(NFA *nfa1,NFA *nfa2) { NFA *nfa; int i,j,k,revise,symbol_index; char symbol; NFAstate temp; int row,col; nfa=(NFA*) malloc(sizeof(NFA)); nfa->states_len=nfa1->states_len+nfa2->states_len-nfa1->finals_len; nfa->states=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->states[i]=i; nfa->symbols_len=nfa1->symbols_len+nfa2->symbols_len; nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); for(i=0,symbol_index=0;i<nfa1->symbols_len;++i) { symbol=nfa1->symbols[i]; nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } for(i=0;i<nfa2->symbols_len;++i) { symbol=nfa2->symbols[i]; if(!in_symbols(symbol,nfa->symbols,symbol_index)) { nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } } nfa->symbols_len=symbol_index; nfa->start=nfa1->start; revise=nfa1->states_len-nfa1->finals_len; nfa->finals_len=nfa2->finals_len; nfa->finals=(NFAstate*)malloc(nfa->finals_len*sizeof(NFAstate)); for(i=0;i<nfa->finals_len;++i) { nfa->finals[i]=revise+nfa2->finals[i]; } nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAstate*)+ nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); memset(nfa->matrix+nfa->states_len,NOSTATE, nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) { nfa->matrix[i]=(NFAMatrixItem*)(nfa->matrix+nfa->states_len)+i*nfa->symbols_len; } for(i=0;i<nfa1->states_len-1;++i) { for(j=0;j<nfa1->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { temp=nfa1->matrix[i][j][k]; if(temp==NOSTATE) break; else { col=nfa->symbols_index[nfa1->symbols[j]]; if(in_NFAstates(temp,nfa1->finals,nfa1->finals_len)!=NOSTATE) nfa->matrix[i][col][k]=revise+nfa2->start; else nfa->matrix[i][col][k]=temp; } } } } for(i=0;i<nfa2->states_len;++i) { for(j=0;j<nfa2->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { temp=nfa2->matrix[i][j][k]; if(temp==NOSTATE) break; else { col=nfa->symbols_index[nfa2->symbols[j]]; nfa->matrix[i+revise][col][k]=revise+temp; } } } } return nfa; } /*----------------------------------------------------------------------------*/ /* NFA或(并集)操作*/ /*----------------------------------------------------------------------------*/ NFA* NFA_or(NFA *nfa1,NFA *nfa2) { NFA *nfa; int i,j,k,revise,symbol_index=0; char symbol; NFAstate temp; int row,col; nfa=(NFA*)malloc(sizeof(NFA)); nfa->states_len=nfa1->states_len+nfa2->states_len+2; nfa->states=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->states[i]=i; nfa->symbols_len=nfa1->symbols_len+nfa2->symbols_len+1; nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); nfa->symbols[symbol_index]=Ee; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; for(i=0;i<nfa1->symbols_len;++i) { symbol=nfa1->symbols[i]; if(!in_symbols(symbol,nfa->symbols,symbol_index)) { nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } } for(i=0;i<nfa2->symbols_len;++i) { symbol=nfa2->symbols[i]; if(!in_symbols(symbol,nfa->symbols,symbol_index)) { nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } } nfa->symbols_len=symbol_index; nfa->start=0; nfa->finals_len=1; nfa->finals=(NFAstate*)malloc(sizeof(NFAstate)); nfa->finals[0]=nfa->states_len-1; nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAstate*)+ nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); memset(nfa->matrix+nfa->states_len,NOSTATE, nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) { nfa->matrix[i]=(NFAMatrixItem*)(nfa->matrix+nfa->states_len)+i*nfa->symbols_len; } revise=1; nfa->matrix[nfa->start][Ee][0]=nfa1->start+revise; nfa->matrix[nfa->start][Ee][1]=nfa2->start+revise+nfa1->states_len; for(i=0;i<nfa1->states_len;++i) { for(j=0;j<nfa1->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { if(nfa1->matrix[i][j][k]==NOSTATE) break; row=revise+i; col=nfa->symbols_index[nfa1->symbols[j]]; nfa->matrix[row][col][k]=revise+nfa1->matrix[i][j][k]; } } } nfa->matrix[revise+nfa1->finals[0]][Ee][0]=nfa->finals[0]; revise=1+nfa1->states_len; for(i=0;i<nfa2->states_len;++i) { for(j=0;j<nfa2->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { if(nfa2->matrix[i][j][k]==NOSTATE) break; row=revise+i; col=nfa->symbols_index[nfa2->symbols[j]]; nfa->matrix[row][col][k]=revise+nfa2->matrix[i][j][k]; } } } nfa->matrix[revise+nfa2->finals[0]][Ee][0]=nfa->finals[0]; return nfa; } /*----------------------------------------------------------------------------*/ /* NFA e闭包操作*/ /*----------------------------------------------------------------------------*/ NFA* NFA_Eclosure(NFA *nfa1) { NFA *nfa; int i,j,k,revise,symbol_index=0; char symbol; NFAstate temp; int row,col; nfa=(NFA*)malloc(sizeof(NFA)); nfa->states_len=nfa1->states_len+2; nfa->states=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->states[i]=i; nfa->symbols_len=nfa1->symbols_len+1; nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); nfa->symbols[symbol_index]=Ee; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; for(i=0;i<nfa1->symbols_len;++i) { symbol=nfa1->symbols[i]; if(!in_symbols(symbol,nfa->symbols,symbol_index)) { nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } } nfa->symbols_len=symbol_index; nfa->start=0; nfa->finals_len=1; nfa->finals=(NFAstate*)malloc(sizeof(NFAstate)); nfa->finals[0]=nfa->states_len-1; nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAstate*)+ nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); memset(nfa->matrix+nfa->states_len,NOSTATE, nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) { nfa->matrix[i]=(NFAMatrixItem*)(nfa->matrix+nfa->states_len)+i*nfa->symbols_len; } revise=1; nfa->matrix[nfa->start][Ee][0]=nfa1->start+revise; nfa->matrix[nfa->start][Ee][1]=nfa->finals[0]; for(i=0;i<nfa1->states_len;++i) { for(j=0;j<nfa1->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { if(nfa1->matrix[i][j][k]==NOSTATE) break; row=revise+i; col=nfa->symbols_index[nfa1->symbols[j]]; nfa->matrix[row][col][k]=revise+nfa1->matrix[i][j][k]; } } } nfa->matrix[nfa1->finals[0]+revise][Ee][0]=nfa1->start+revise; nfa->matrix[nfa1->finals[0]+revise][Ee][1]=nfa->finals[0]; return nfa; } /*----------------------------------------------------------------------------*/ /* NFA 正闭包操作*/ /*----------------------------------------------------------------------------*/ NFA* NFA_closure(NFA *nfa1) { NFA *nfa; int i,j,k,revise,symbol_index=0; char symbol; NFAstate temp; int row,col; nfa=(NFA*)malloc(sizeof(NFA)); nfa->states_len=nfa1->states_len+2; nfa->states=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->states[i]=i; nfa->symbols_len=nfa1->symbols_len+1; nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); nfa->symbols[symbol_index]=Ee; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; for(i=0;i<nfa1->symbols_len;++i) { symbol=nfa1->symbols[i]; if(!in_symbols(symbol,nfa->symbols,symbol_index)) { nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } } nfa->symbols_len=symbol_index; nfa->start=0; nfa->finals_len=1; nfa->finals=(NFAstate*)malloc(sizeof(NFAstate)); nfa->finals[0]=nfa->states_len-1; nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAstate*)+ nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); memset(nfa->matrix+nfa->states_len,NOSTATE, nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) { nfa->matrix[i]=(NFAMatrixItem*)(nfa->matrix+nfa->states_len)+i*nfa->symbols_len; } revise=1; nfa->matrix[nfa->start][Ee][0]=nfa1->start+revise; for(i=0;i<nfa1->states_len;++i) { for(j=0;j<nfa1->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { if(nfa1->matrix[i][j][k]==NOSTATE) break; row=revise+i; col=nfa->symbols_index[nfa1->symbols[j]]; nfa->matrix[row][col][k]=revise+nfa1->matrix[i][j][k]; } } } nfa->matrix[nfa1->finals[0]+revise][Ee][0]=nfa1->start+revise; nfa->matrix[nfa1->finals[0]+revise][Ee][1]=nfa->finals[0]; return nfa; } /*----------------------------------------------------------------------------*/ /* NFA ?闭包(0或1个实例)操作*/ /*----------------------------------------------------------------------------*/ NFA* NFA_ONEclosure(NFA *nfa1) { NFA *nfa; int i,j,k,revise,symbol_index=0; char symbol; NFAstate temp; int row,col; nfa=(NFA*)malloc(sizeof(NFA)); nfa->states_len=nfa1->states_len+2; nfa->states=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->states[i]=i; nfa->symbols_len=nfa1->symbols_len+1; nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); nfa->symbols[symbol_index]=Ee; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; for(i=0;i<nfa1->symbols_len;++i) { symbol=nfa1->symbols[i]; if(!in_symbols(symbol,nfa->symbols,symbol_index)) { nfa->symbols[symbol_index]=symbol; nfa->symbols_index[nfa->symbols[symbol_index]]=symbol_index; ++symbol_index; } } nfa->symbols_len=symbol_index; nfa->start=0; nfa->finals_len=1; nfa->finals=(NFAstate*)malloc(sizeof(NFAstate)); nfa->finals[0]=nfa->states_len-1; nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAstate*)+ nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); memset(nfa->matrix+nfa->states_len,NOSTATE, nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) { nfa->matrix[i]=(NFAMatrixItem*)(nfa->matrix+nfa->states_len)+i*nfa->symbols_len; } revise=1; nfa->matrix[nfa->start][Ee][0]=nfa1->start+revise; nfa->matrix[nfa->start][Ee][1]=nfa->finals[0]; for(i=0;i<nfa1->states_len;++i) { for(j=0;j<nfa1->symbols_len;++j) { for(k=0;k<NFA_TRANS;++k) { if(nfa1->matrix[i][j][k]==NOSTATE) break; row=revise+i; col=nfa->symbols_index[nfa1->symbols[j]]; nfa->matrix[row][col][k]=revise+nfa1->matrix[i][j][k]; } } } nfa->matrix[nfa1->finals[0]+revise][Ee][0]=nfa->finals[0]; return nfa; } /*----------------------------------------------------------------------------*/ /* 生成简单NFA*/ /*----------------------------------------------------------------------------*/ NFA* create_singleNFA(char ch) { NFA *nfa; int i; nfa=(NFA*)malloc(sizeof(NFA)); nfa->states_len=2; nfa->states= (NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->states[i]=i; nfa->symbols_len=1; nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); nfa->symbols[0]=ch; nfa->symbols_index[nfa->symbols[0]]=0; nfa->start=0; nfa->finals_len=1; nfa->finals=(NFAstate*)malloc(sizeof(NFAstate)); nfa->finals[0]=nfa->states_len-1; nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAstate*)+ nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); memset(nfa->matrix+nfa->states_len,NOSTATE, nfa->states_len*nfa->symbols_len*NFA_TRANS*sizeof(NFAstate)); for(i=0;i<nfa->states_len;++i) nfa->matrix[i]=(NFAMatrixItem*)(nfa->matrix+nfa->states_len)+i*nfa->symbols_len; nfa->matrix[nfa->start][nfa->symbols_index[ch]][0]=nfa->finals[0]; return nfa; } /*----------------------------------------------------------------------------*/ /* 判断ch是否为字符*/ /*----------------------------------------------------------------------------*/ BOOL is_letter(char ch) { if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return TRUE; else return FALSE; } /*----------------------------------------------------------------------------*/ /* 判断ch是否为数字*/ /*----------------------------------------------------------------------------*/ BOOL is_digit(char ch) { if(ch>='0'&&ch<='9') return TRUE; else return FALSE; } /*----------------------------------------------------------------------------*/ /* 判断ch是否为NFA操作符*/ /*----------------------------------------------------------------------------*/ BOOL is_NFAoperator(char ch) { if(ch==ECLOSURE || ch==AND || ch==OR || ch==CLOSURE || ch==ONECLOSURE) return TRUE; else return FALSE; } /*----------------------------------------------------------------------------*/ /* 判断ch是否为空白符*/ /*----------------------------------------------------------------------------*/ BOOL is_delim(char ch) { if(ch==' ' || ch=='/t' || ch=='/n') return TRUE; else return FALSE; } /*----------------------------------------------------------------------------*/ /* 将字符转换为大写*/ /*----------------------------------------------------------------------------*/ char to_upper(char ch) { if(ch>='a'&&ch<='z') return ch-32; return ch; } /*----------------------------------------------------------------------------*/ /* 解析正则表达式*/ /*----------------------------------------------------------------------------*/ void expr_traverse(char **lookahead) { GlobalExpr_Index=0; expr(lookahead); } /*----------------------------------------------------------------------------*/ /* 生成式 expr->term expr_rest*/ /*----------------------------------------------------------------------------*/ void expr(char **lookahead) { term(lookahead); expr_rest(lookahead); } /*----------------------------------------------------------------------------*/ /* 生成式 expr_rest-> |term expr_rest*/ /*----------------------------------------------------------------------------*/ void expr_rest(char **lookahead) { char ch=**lookahead; if(ch==OR) { ++(*lookahead); term(lookahead); GlobalPost_Expr[GlobalExpr_Index++]='|'; expr_rest(lookahead); } else if('('==ch) { atom(lookahead); } else if(')'==ch) { atom(lookahead); } } /*----------------------------------------------------------------------------*/ /* 生成式 factor->factor term_rest*/ /*----------------------------------------------------------------------------*/ void term(char **lookahead) { factor(lookahead); term_rest(lookahead); } /*----------------------------------------------------------------------------*/ /* 生成式 term_rest->.factor term_rest*/ /*----------------------------------------------------------------------------*/ void term_rest(char **lookahead) { char ch=**lookahead; if(AND==ch) { ++(*lookahead); factor(lookahead); GlobalPost_Expr[GlobalExpr_Index++]=AND; term_rest(lookahead); } } /*----------------------------------------------------------------------------*/ /* 生成式 factor->atom factor_rest*/ /*----------------------------------------------------------------------------*/ void factor(char **lookahead) { atom(lookahead); factor_rest(lookahead); } /*----------------------------------------------------------------------------*/ /* 生成式 factor_rest->* factor_rest*/ /*----------------------------------------------------------------------------*/ void factor_rest(char **lookahead) { char ch=**lookahead; if(ECLOSURE==ch) { ++(*lookahead); GlobalPost_Expr[GlobalExpr_Index++]=ECLOSURE; factor_rest(lookahead); } else if(CLOSURE==ch) { ++(*lookahead); GlobalPost_Expr[GlobalExpr_Index++]=CLOSURE; factor_rest(lookahead); } else if(ONECLOSURE==ch) { ++(*lookahead); GlobalPost_Expr[GlobalExpr_Index++]=ONECLOSURE; factor_rest(lookahead); } } /*----------------------------------------------------------------------------*/ /* 生成式 atom-> letter || (expr)*/ /*----------------------------------------------------------------------------*/ void atom(char **lookahead) { char ch=**lookahead; if('('==ch) { ++(*lookahead); expr(lookahead); } else if(**lookahead==')') { ++(*lookahead); } else if(!is_NFAoperator(ch)) { ++(*lookahead); GlobalPost_Expr[GlobalExpr_Index++]=ch; } } /*----------------------------------------------------------------------------*/ /* 插入元素*/ /*----------------------------------------------------------------------------*/ void expr_insert(char ch,char *s,int len,int pos) { int i; if(pos>=0 && pos<=len) { for(i=len+1;i>pos;--i) s[i]=s[i-1]; s[pos]=ch; } } /*----------------------------------------------------------------------------*/ /* 删除元素*/ /*----------------------------------------------------------------------------*/ char expr_delete(char *s,int len,int pos) { int i; char ch='/0'; if(pos>=0 && pos<len) { ch=s[pos]; for(i=pos;i<len;++i) s[i]=s[i+1]; } return ch; } /*----------------------------------------------------------------------------*/ /* 删除所有空白符*/ /*----------------------------------------------------------------------------*/ void trim_delim(char *s) { char *o=s; while(is_delim(*s)) ++s; while(*s!='/0') { if(is_delim(*s)) ++s; else *o++=*s++; } while(o!=s) *o++='/0'; } /*----------------------------------------------------------------------------*/ /* 转换正则式中的letter和digit*/ /*----------------------------------------------------------------------------*/ void expr_trans(char *expr) { char *letter_pos,*digit_pos; char *letter="(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)"; char *digit="(0|1|2|3|4|5|6|7|8|9)"; int letter_len=105,digit_len=21; char *dest,*scr; int i,len; while((letter_pos=strstr(expr,"letter"))!=NULL) { dest=letter_pos+letter_len; scr=letter_pos+6; len=strlen(scr); for(i=len;i>=0;--i) dest[i]=scr[i]; dest=letter_pos; scr=letter; while(*scr!='/0') *dest++=*scr++; } while((digit_pos=strstr(expr,"digit"))!=NULL) { dest=digit_pos+digit_len; scr=digit_pos+5; len=strlen(scr); for(i=len;i>=0;--i) dest[i]=scr[i]; dest=digit_pos; scr=digit; while(*scr!='/0') *dest++=*scr++; } } /*----------------------------------------------------------------------------*/ /* 检查表达式是否合法 */ /* 可以检查四种错误: */ /* 1.右括号先出现(RightBarce_First) */ /* 2.括号不配对、丢失(BraceCount) */ /* 3.字符和运算符号不匹配(SymbolOperator_Match),如"a+b.c","a|","cd."等 */ /*----------------------------------------------------------------------------*/ BOOL is_LegalExpression(char *expr) { char *s=expr; char symbol; int BraceCount=0,SymbolCount=0,OperatorCount=0; BOOL LeftBarce_First,RightBarce_First,IllegalSymbol,SymbolOperator_Match; int len,pos,post_len; char mark='#'; char *test_str; char *original; if(strlen(expr)==1 &&!is_NFAoperator(*expr)) return TRUE; LeftBarce_First=FALSE; RightBarce_First=FALSE; while((symbol=*s++)!='/0') { if(is_NFAoperator(symbol)) ++OperatorCount; else if('('==symbol) { if(FALSE==LeftBarce_First && LeftBarce_First!=TRUE) LeftBarce_First=TRUE; ++BraceCount; } else if(')'==symbol) { if(FALSE==LeftBarce_First && RightBarce_First!=TRUE) RightBarce_First=TRUE; ++BraceCount; } else ++SymbolCount; } if(RightBarce_First==TRUE) { //puts("Right Barce come first!"); puts("错误:右括号先出现!"); return FALSE; } if(BraceCount&1) { //puts("missing Brace!"); puts("错误:括号不匹配,丢失左括号或右括号!"); return FALSE; } len=strlen(expr); GlobalPost_Expr=(char*)calloc(len+1,sizeof(char)); original=expr; expr_traverse(&original); post_len=strlen(GlobalPost_Expr); if(post_len!=SymbolCount+OperatorCount) { //puts("Symbols and operators not match!"); puts("错误:字符和运算符不匹配,缺少运算符或字符!"); free(GlobalPost_Expr); return FALSE; } s=GlobalPost_Expr; pos=0; while((symbol=*s)!='/0') { if(is_NFAoperator(symbol)) { if(symbol==ECLOSURE || symbol==CLOSURE || symbol==ONECLOSURE) { --pos; if(pos<0) break; --s; expr_delete(GlobalPost_Expr,post_len,pos); --post_len; expr_delete(GlobalPost_Expr,post_len,pos); --post_len; expr_insert(mark, GlobalPost_Expr,post_len,pos); ++post_len; } else { pos-=2; if(pos<0) break; s-=2; expr_delete(GlobalPost_Expr,post_len,pos); --post_len; expr_delete(GlobalPost_Expr,post_len,pos); --post_len; expr_delete(GlobalPost_Expr,post_len,pos); --post_len; expr_insert(mark, GlobalPost_Expr,post_len,pos); ++post_len; } } else { ++s; ++pos; } } post_len=strlen(GlobalPost_Expr); if(post_len!=1 || pos<0 || *GlobalPost_Expr!=mark) { //puts("Symbols and operators not match!"); puts("错误:字符和运算符不匹配,缺少运算符或字符!"); free(GlobalPost_Expr); return FALSE; } else { free(GlobalPost_Expr); return TRUE; } return TRUE; } /*----------------------------------------------------------------------------*/ /* 判断NFA指针n是否在指针数组ns中*/ /*----------------------------------------------------------------------------*/ static BOOL in_NFAs(NFA* n,NFA** ns,int len) { int i; for(i=0;i<len;++i) { if(ns[i]==n) return TRUE; } return FALSE; } /*----------------------------------------------------------------------------*/ /* 表达式生成NFA*/ /*----------------------------------------------------------------------------*/ NFA* ExprtoNFA(char *expr) { char *s; char ch; NFA **Nfas,*Nfa_1,*Nfa_2; int i=0; NFA *NFA_stack[NFASTACK_SIZE]={0}; int stack_top=NFASTACK_SIZE-1; int len; int Gsymbols_alreadyOn[SIMBOLS_MAX]={0}; char Gsymbols[SIMBOLS_MAX]={0}; int Gsymbols_index=0; if(is_LegalExpression(expr)) { if(strlen(expr)==1 ) { return create_singleNFA(*expr); } len=strlen(expr)*2; GlobalPost_Expr=(char*)calloc(len,sizeof(char)); expr_traverse(&expr); s=GlobalPost_Expr; Nfas=(NFA**)malloc(strlen(s)*sizeof(NFA*)); while((ch=*s++)!='/0') { if(!is_NFAoperator(ch)) { if(!in_symbols(ch,Gsymbols,Gsymbols_index)) { Gsymbols_alreadyOn[ch]=Gsymbols_index; Gsymbols[Gsymbols_index]=ch; Nfas[Gsymbols_index]=create_singleNFA(ch); ++Gsymbols_index; } } } s=GlobalPost_Expr; while((ch=*s++)!='/0') { if(is_NFAoperator(ch)) { if(ch==ECLOSURE) { Nfa_1=NFA_stack[++stack_top]; NFA_stack[stack_top--]=NFA_Eclosure(Nfa_1); if(!in_NFAs(Nfa_1,Nfas,Gsymbols_index)) destroy_NFA(Nfa_1); } else if(ch==CLOSURE) { Nfa_1=NFA_stack[++stack_top]; NFA_stack[stack_top--]=NFA_closure(Nfa_1); if(!in_NFAs(Nfa_1,Nfas,Gsymbols_index)) destroy_NFA(Nfa_1); } else if(ch==ONECLOSURE) { Nfa_1=NFA_stack[++stack_top]; NFA_stack[stack_top--]=NFA_ONEclosure(Nfa_1); if(!in_NFAs(Nfa_1,Nfas,Gsymbols_index)) destroy_NFA(Nfa_1); } else if(ch==OR) { Nfa_1=NFA_stack[++stack_top]; Nfa_2=NFA_stack[++stack_top]; NFA_stack[stack_top--]=NFA_or(Nfa_1,Nfa_2); if(!in_NFAs(Nfa_1,Nfas,Gsymbols_index)) destroy_NFA(Nfa_1); if(!in_NFAs(Nfa_2,Nfas,Gsymbols_index)) destroy_NFA(Nfa_2); } else if(ch==AND) { Nfa_2=NFA_stack[++stack_top]; Nfa_1=NFA_stack[++stack_top]; NFA_stack[stack_top--]=NFA_and(Nfa_1,Nfa_2); if(!in_NFAs(Nfa_1,Nfas,Gsymbols_index)) destroy_NFA(Nfa_1); if(!in_NFAs(Nfa_2,Nfas,Gsymbols_index)) destroy_NFA(Nfa_2); } } else { NFA_stack[stack_top--]=Nfas[Gsymbols_alreadyOn[ch]]; } } for(i=0;i<Gsymbols_index;++i) { destroy_NFA(Nfas[i]); } free(Nfas); free(GlobalPost_Expr); return NFA_stack[++stack_top]; } else return NULL; } /*----------------------------------------------------------------------------*/ /* 打印带正则式的NFA /*----------------------------------------------------------------------------*/ void print_NFAwithExpr(NFAwithExpr *nfawe,FILE *fp) { int i,j,k,space=0; NFAstate *temp; NFA *nfa=nfawe->nfa; fprintf(fp,"Expression: %s/n",nfawe->expr); fprintf(fp,"NFAstates(%d): ",nfa->states_len); for(i=0;i<nfa->states_len;++i) fprintf(fp,"%d ",nfa->states[i]); fprintf(fp,"/n"); fprintf(fp,"start: %d/n",nfa->start); fprintf(fp,"finals(%d): ",nfa->finals_len); for(i=0;i<nfa->finals_len;++i) fprintf(fp,"%d ",nfa->finals[i]); fprintf(fp,"/n"); fprintf(fp,"symbols(%d): ",nfa->symbols_len); for(i=0;i<nfa->symbols_len;++i) { if(nfa->symbols[i]==Ee) fprintf(fp,"%s ","Ee"); else fprintf(fp,"%c ",nfa->symbols[i]); } fprintf(fp,"/n"); fprintf(fp,"NFAstate/t"); for(i=0;i<nfa->symbols_len;++i) { if(nfa->symbols[i]==Ee) fprintf(fp,"%-*s",NFA_TRANS*2,"Ee"); else fprintf(fp,"%-*c",NFA_TRANS*2,nfa->symbols[i]); } fprintf(fp,"/n"); for(i=0;i<nfa->states_len;++i) { fprintf(fp,"%d/t/t",nfa->states[i]); for(j=0;j<nfa->symbols_len;++j) { space=0; temp=(nfa->matrix)[i][j]; for(k=0;temp[k]!=NOSTATE&&k<NFA_TRANS;++k) { space+=fprintf(fp,"%d,",nfa->states[temp[k]]); } if(temp[k]==NOSTATE) space+=fprintf(fp,"-1 "); while(space++<NFA_TRANS*2) fprintf(fp," "); } fprintf(fp,"/n"); } } /*----------------------------------------------------------------------------*/ /* 销毁带正则式的NFA*/ /*----------------------------------------------------------------------------*/ void destroy_NFAwithExpr(NFAwithExpr *nfawe) { if(nfawe->nfa!=NULL) { destroy_NFA(nfawe->nfa); } if(nfawe!=NULL) { free(nfawe); nfawe=NULL; } } /*----------------------------------------------------------------------------*/ /* 从文件获取带正则式的NFA,并返回 //注意:文件的格式要和print_NFA格式完全一致 /*----------------------------------------------------------------------------*/ NFAwithExpr* get_NFAwithExpr(FILE *fp) { NFA* nfa; char *buf,subbuf[32]={0},subsubbuf[8]={0}; char *s,ch,*t,*tt,*symbols; int state_index,symbol_index,item_index,matrix_index; NFAstate *states; NFAstate item; NFAwithExpr *Nfawe; if((buf=(char*)calloc(BUF_SIZE,sizeof(char)))==NULL) { puts("错误:分配内存错误"); system("pause"); system("cls"); DFANFA_System(); return NULL; } if((Nfawe=(NFAwithExpr*)calloc(1,sizeof(NFAwithExpr)))==NULL) { puts("错误:分配内存错误"); free(buf); system("pause"); system("cls"); DFANFA_System(); return NULL; } if((Nfawe->nfa=(NFA*)malloc(sizeof(NFA)))==NULL) { puts("错误:分配内存错误"); destroy_NFAwithExpr(Nfawe); free(buf); system("pause"); system("cls"); DFANFA_System(); return NULL; } nfa=Nfawe->nfa; memset(nfa,0,sizeof(NFA)); if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取NFA正则式"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(strncmp(s,"Expression:",11)!=0) { puts("警告:不是正确的格式 Expression:"); } while(!is_delim(*s) && *s!=0) s++; while((*s==' '||*s=='/t') && *s!=0) ++s; if(strlen(s)==0) { puts("错误:未能读取NFA正则式!"); puts("请检查文件是否为正确形式:Expression: (后有空格)"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } memcpy(Nfawe->expr,s,strlen(s)-1); if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取NFA状态"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"NFAstates(%d)",&(nfa->states_len))==0) { puts("错误:读取NFA状态数错误!"); puts("请检查文件是否为正确形式:NFAstates(状态数): (后有空格)"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } nfa->states=(NFAstate*)malloc(nfa->states_len*sizeof(NFAstate)); t=subbuf; state_index=0; states=nfa->states; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(state_index < nfa->states_len) { states[state_index++]=atoi(subbuf); } else { puts("警告:NFA状态数过多!"); break; } } t=subbuf; } else { *t++=ch; } } if(state_index < nfa->states_len) { printf("错误:NFA状态数不足%d个!/n",nfa->states_len); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取nfa开始状态"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"start: %d",&(nfa->start))==0) { puts("错误:读取NFA开始状态错误!"); puts("请检查文件是否为正确形式:start: (后有空格)"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } if(in_NFAstates(nfa->start,nfa->states,nfa->states_len)==NOSTATE) { printf("错误:NFA开始状态->%d是非法状态!/n",nfa->start); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取NFA终结状态"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"finals(%d",&(nfa->finals_len))==0) { puts("错误:读取NFA终结状态数错误!"); puts("请检查文件是否为正确形式:finals(状态数): (后有空格)"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } nfa->finals=(NFAstate*)malloc(nfa->finals_len*sizeof(NFAstate)); t=subbuf; states=nfa->finals; state_index=0; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(state_index < nfa->finals_len) { item=atoi(subbuf); if(in_NFAstates(item,nfa->states,nfa->states_len)==NOSTATE) { printf("错误:NFA终结状态->%d是非法状态!/n",item); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } states[state_index++]=item; } else { puts("警告:NFA终结状态数过多!"); break; } } t=subbuf; } else { *t++=ch; } } if(state_index < nfa->finals_len) { printf("错误:NFA终结状态数不足%d个!/n",nfa->finals_len); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取NFA字符集"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"symbols(%d",&(nfa->symbols_len))==0) { puts("错误:读取NFA字符数错误!"); puts("请检查文件是否为正确形式:symbols(字符数): (后有空格)"); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } nfa->symbols=(char*)malloc(nfa->symbols_len*sizeof(char)); memset(nfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); t=subbuf; symbols=nfa->symbols; symbol_index=0; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(strcmp(subbuf,"Ee")==0) { if(symbol_index<nfa->symbols_len) { symbols[symbol_index]=Ee; nfa->symbols_index[Ee]=symbol_index; ++symbol_index; } else { puts("警告:字符过多!"); break; } } else { if(symbol_index<nfa->symbols_len) { symbols[symbol_index]=*subbuf; nfa->symbols_index[*subbuf]=symbol_index; ++symbol_index; } else { puts("警告:字符过多!"); break; } } } t=subbuf; } else { *t++=ch; } } if(symbol_index<nfa->symbols_len) { printf("错误: 字符数不足%d个!/n",nfa->symbols_len); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } nfa->matrix=(NFAMatrixItem**)malloc(nfa->states_len*sizeof(NFAMatrixItem*)+nfa->states_len*nfa->symbols_len*sizeof(NFAMatrixItem)); for(state_index=0;state_index<nfa->states_len;++state_index) { (nfa->matrix)[state_index]=(NFAMatrixItem*)((nfa->matrix)+nfa->states_len)+state_index*nfa->symbols_len; } memset(nfa->matrix+nfa->states_len,NOSTATE,nfa->states_len*nfa->symbols_len*sizeof(NFAMatrixItem)); fgets(buf,BUF_SIZE,fp); for(state_index=0;state_index<nfa->states_len;++state_index) { fgets(buf,BUF_SIZE,fp); s=buf; t=subbuf; symbol_index=0; while((*s==' '||*s=='/t') && *s!=0) ++s; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(*subbuf!='-') { if(symbol_index>=nfa->symbols_len) { puts("警告:NFA转换矩阵列数过多!"); break; } t=subbuf; tt=subsubbuf; item_index=0; while((ch=*t++)!=0) { if(ch==',') { *tt=0; if(*subsubbuf!='-') { item=atoi(subsubbuf); if((matrix_index=in_NFAstates(item,nfa->states,nfa->states_len))==NOSTATE) { printf("错误:NFA转换矩阵存在非法状态->%d!/n",item); free(buf); destroy_NFAwithExpr(Nfawe); return NULL; } if(item_index>NFA_TRANS) { printf("警告:NFA状态%d 对字符%c 的转换数超出了上限%d!/n", nfa->states[state_index],nfa->symbols[symbol_index],NFA_TRANS); break; } nfa->matrix[state_index][symbol_index][item_index++]=matrix_index; } tt=subsubbuf; } else { *tt++=ch; } } } ++symbol_index; } t=subbuf; } else { *t++=ch; } } } if(symbol_index < nfa->symbols_len) { puts("警告:NFA转换矩阵列数不足,默认为空状态!"); } if(fgets(buf,BUF_SIZE,fp)!=NULL) { puts("警告:有未读取的行!"); } free(buf); return Nfawe; } /*----------------------------------------------------------------------------*/ /* 打印带正则式的DFA /*----------------------------------------------------------------------------*/ void print_DFAwithExpr(DFAwithExpr *dfawe,FILE *fp) { int i,j,k; DFAstate temp; DFA *dfa=dfawe->dfa; fprintf(fp,"Expression: %s/n",dfawe->expr); fprintf(fp,"DFAstates(%d): ",dfa->states_len); for(i=0;i<dfa->states_len;++i) fprintf(fp,"%d ",dfa->states[i]); fprintf(fp,"/n"); fprintf(fp,"start: %d/n",dfa->start); fprintf(fp,"finals(%d): ",dfa->finals_len); for(i=0;i<dfa->finals_len;++i) fprintf(fp,"%d ",dfa->finals[i]); fprintf(fp,"/n"); fprintf(fp,"symbols(%d): ",dfa->symbols_len); for(i=0;i<dfa->symbols_len;++i) fprintf(fp,"%c ",dfa->symbols[i]); fprintf(fp,"/n"); fprintf(fp,"DFAstate/t"); for(i=0;i<dfa->symbols_len;++i) fprintf(fp,"%c/t",dfa->symbols[i]); fprintf(fp,"/n"); for(i=0;i<dfa->states_len;++i) { fprintf(fp,"%d/t/t",dfa->states[i]); for(j=0;j<dfa->symbols_len;++j) { if((dfa->matrix)[i][j]==NOSTATE) fprintf(fp,"%d/t",NOSTATE); else fprintf(fp,"%d/t",dfa->states[(dfa->matrix)[i][j]]); } fprintf(fp,"/n"); } } /*----------------------------------------------------------------------------*/ /* 从文件获取带正则式的DFA,并返回 /*----------------------------------------------------------------------------*/ DFAwithExpr* get_DFAwithExpr(FILE *fp) { DFA* dfa; char *buf,subbuf[32]={0}; char *s,ch,*t,*symbols; int state_index,symbol_index,item_index; DFAstate *states; DFAMatrixItem item; DFAwithExpr *Dfawe; if((buf=(char*)calloc(BUF_SIZE,sizeof(char)))==NULL) { puts("错误:分配内存错误"); system("pause"); system("cls"); DFANFA_System(); return NULL; } if((Dfawe=(DFAwithExpr*)calloc(1,sizeof(DFAwithExpr)))==NULL) { puts("错误:分配内存错误"); free(buf); system("pause"); system("cls"); DFANFA_System(); return NULL; } if((Dfawe->dfa=(DFA*)malloc(sizeof(DFA)))==NULL) { puts("错误:分配内存错误"); destroy_DFAwithExpr(Dfawe); free(buf); system("pause"); system("cls"); DFANFA_System(); return NULL; } memset(Dfawe->dfa,0,sizeof(DFA)); dfa=Dfawe->dfa; if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取DFA正则式"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(strncmp(s,"Expression:",11)!=0) { puts("警告:不是正确的格式 Expression: (后有空格)"); } while(!is_delim(*s) && *s!=0) s++; while((*s==' '||*s=='/t') && *s!=0) ++s; if(strlen(s)==0) { puts("错误:读取DFA正则式失败!"); puts("请检查文件是否为正确形式:Expression: (后有空格)"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } memcpy(Dfawe->expr,s,strlen(s)-1); if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取DFA状态"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"DFAstates(%d)",&(dfa->states_len))==0) { puts("错误:读取DFA状态数错误!"); puts("请检查文件是否为正确形式:DFAstates(状态数): (后有空格)"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } dfa->states=(DFAstate*)malloc(dfa->states_len*sizeof(DFAstate)); t=subbuf; state_index=0; states=dfa->states; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(state_index < dfa->states_len) { states[state_index++]=atoi(subbuf); } else { puts("警告:DFA状态数过多!"); break; } } t=subbuf; } else { *t++=ch; } } if(state_index < dfa->states_len) { printf("错误:DFA状态数不足%d个!/n",dfa->states_len); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取DFA开始状态"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"start: %d",&(dfa->start))==0) { puts("错误:读取DFA开始状态错误!"); puts("请检查文件是否为正确形式:start: (后有空格)"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } if(in_DFAstates(dfa->start,dfa->states,dfa->states_len)==NOSTATE) { printf("错误:DFA开始状态->%d是非法状态!/n",dfa->start); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取DFA终结状态"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"finals(%d",&(dfa->finals_len))==0) { puts("错误:读取DFA终结状态数错误!"); puts("请检查文件是否为正确形式:finals(状态数): (后有空格)"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } dfa->finals=(DFAstate*)malloc(dfa->finals_len*sizeof(DFAstate)); t=subbuf; states=dfa->finals; state_index=0; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(state_index<dfa->finals_len) { item=atoi(subbuf); if(in_DFAstates(item,dfa->states,dfa->states_len)==NOSTATE) { printf("错误:DFA终结状态->%d是非法状态!/n",item); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } states[state_index++]=item; } else { puts("警告:DFA终结状态数过多!"); break; } } t=subbuf; } else { *t++=ch; } } if(state_index < dfa->finals_len) { printf("错误:DFA终结状态数不足%d个!/n",dfa->finals_len); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } if(fgets(buf,BUF_SIZE,fp)==NULL) { puts("错误:未能读取DFA字符集"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(sscanf(s,"symbols(%d",&(dfa->symbols_len))==0) { puts("错误:读取DFA字符数错误!"); puts("请检查文件是否为正确形式:symbols(字符数): (后有空格)"); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } dfa->symbols=(char*)malloc(dfa->symbols_len*sizeof(char)); memset(dfa->symbols_index,-1,SIMBOLS_MAX*sizeof(int)); t=subbuf; symbols=dfa->symbols; symbol_index=0; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(strcmp(subbuf,"Ee")==0) { puts("警告:存在空字符!"); continue; } else { if(symbol_index<dfa->symbols_len) { symbols[symbol_index]=*subbuf; dfa->symbols_index[*subbuf]=symbol_index; ++symbol_index; } else { puts("警告:字符过多!"); break; } } } t=subbuf; } else { *t++=ch; } } if(symbol_index<dfa->symbols_len) { printf("错误: 字符数不足%d个!/n",dfa->symbols_len); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } dfa->matrix=(DFAMatrixItem**)malloc(dfa->states_len*sizeof(DFAMatrixItem*)+dfa->states_len*dfa->symbols_len*sizeof(DFAMatrixItem)); for(state_index=0;state_index<dfa->states_len;++state_index) { (dfa->matrix)[state_index]=(DFAMatrixItem*)((dfa->matrix)+dfa->states_len)+state_index*dfa->symbols_len; } memset(dfa->matrix+dfa->states_len,NOSTATE,dfa->states_len*dfa->symbols_len*sizeof(DFAMatrixItem)); fgets(buf,BUF_SIZE,fp); for(state_index=0;state_index<dfa->states_len;++state_index) { fgets(buf,BUF_SIZE,fp); s=buf; t=subbuf; symbol_index=0; while((*s==' '||*s=='/t') && *s!=0) ++s; while(!is_delim(*s) && *s!=0) s++; while((ch=*s++)!=0) { if(is_delim(ch)) { *t=0; if(strlen(subbuf)>0) { if(*subbuf!='-') { if(symbol_index>=dfa->symbols_len) { puts("警告:DFA转换矩阵列数过多!"); break; } item=atoi(subbuf); if((item_index=in_DFAstates(item,dfa->states,dfa->states_len))==NOSTATE) { printf("错误:DFA转换矩阵存在非法状态->%d!/n",item); free(buf); destroy_DFAwithExpr(Dfawe); return NULL; } dfa->matrix[state_index][symbol_index]=item_index; } ++symbol_index; } t=subbuf; } else { *t++=ch; } } } if(symbol_index < dfa->symbols_len) { puts("警告:DFA转换矩阵列数不足,默认为空状态!"); } if(fgets(buf,BUF_SIZE,fp)!=NULL) { puts("警告:有未读取的行!"); } free(buf); return Dfawe; } /*----------------------------------------------------------------------------*/ /* 销毁DFA*/ /*----------------------------------------------------------------------------*/ void destroy_DFAwithExpr(DFAwithExpr *dfawe) { if(dfawe->dfa!=NULL) { destroy_DFA(dfawe->dfa); dfawe->dfa=NULL; } if(dfawe!=NULL) { free(dfawe); dfawe=NULL; } } /*----------------------------------------------------------------------------*/ /* 打印系统菜单 */ /*----------------------------------------------------------------------------*/ void DFANFA_Menu(void) { system("color e3"); puts("***************************欢迎使用词法分析系统*******************************/n"); puts("/t本系统可以实现如下功能:"); puts("/t1. 将正则表达式转换为非确定的有限自动机(NFA)"); puts("/t2. 将非确定的有限自动机(NFA)转换为确定的有限自动机(DFA)"); puts("/t3. 将确定的有限自动机(DFA)化简"); puts("/t4. 非确定的有限自动机(NFA)模拟"); puts("/t5. 确定的有限自动机(DFA)模拟"); puts("/t6. 使用说明"); puts("/t7. 退出系统"); puts("******************************************************************************/n"); } /*----------------------------------------------------------------------------*/ /* 获取1-7间的选择*/ /*----------------------------------------------------------------------------*/ int get_Choice(void) { int choice; while((scanf("%d",&choice)!=1) || choice<1 || choice>7) { puts("输入错误,请输入1--7间的数字:"); fflush(stdin); } fflush(stdin); return choice; } /*----------------------------------------------------------------------------*/ /* 获取Y或N选择*/ /*----------------------------------------------------------------------------*/ char get_ChoiceYN(void) { char choice; choice=getchar(); if(choice=='/n' || choice=='/r') return 'Y'; choice=to_upper(choice); fflush(stdin); while(choice!='N' && choice!='Y') { puts("请输入Y或N(键入回车默认为Y):"); choice=getchar(); if(choice=='/n' || choice=='/r') return 'Y'; choice=to_upper(choice); fflush(stdin); } return choice; } /*----------------------------------------------------------------------------*/ /* 获取正则式*/ /*----------------------------------------------------------------------------*/ char* get_Expression(void) { char *expr; expr=(char*)calloc(EXPRESSION_SIZE,sizeof(char)); while((gets(expr)!=NULL) && !is_LegalExpression(expr)) { puts("正则式输入错误,请重新输入,形如 (a|b)*^a^b^b (注意:表示连接关系需用连接符^号):"); fflush(stdin); } fflush(stdin); trim_delim(expr); return expr; } /*----------------------------------------------------------------------------*/ /* 打印系统说明*/ /*----------------------------------------------------------------------------*/ void print_direction(FILE *fp) { system("color 7c"); fputs("*******************************使用说明*****************************************/n/n/n/n",fp); fputs("/t1>. 使用本系统需具备一定有限自动机知识,需要能把状态图转换为矩阵/n",fp); fputs("/t并且把矩阵转换为状态图,例如:/n",fp); fputs("/t/tDFAstate a b/n",fp); fputs("/t/t 0 1 -1/n",fp); fputs("/t表示状态0通过字符a到达状态1 (0--a-->1), 状态0通过字符b没有状态转化/n",fp); fputs("/n/t2>. 本系统正则式的运算符号为:",fp); fputs("/n/t或运算(|),与运算(^),正闭包(~),ε闭包(*),0或1个实例(?)/n",fp); fputs("/n/t其中,与运算^号,正闭包~号是与一般的正则式不同的/n",fp); fputs("/n/t例如(a|b)*abb要写为(a|b)*^a^b^b /n",fp); fputs("/n/t默认正则式letter为:(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)",fp); fputs("/n/t默认正则式digit为:(0|1|2|3|4|5|6|7|8|9)/n",fp); fputs("/n/t3>. 本系统空字符(即0)用Ee表示,无状态为用-1表示/n",fp); fputs("/n/t4>. 本系统有限自动机的状态用连续正整数表示/n",fp); fputs("/n/t5>. 本系统生成的非确定有限自动机(NFA)均只有一个终结状态/n",fp); fputs("/n/t6>. 有限自动机以矩阵形式存储,输入和输出以文件方式进行/n",fp); fputs("/n/t7>. 有限自动机的文件格式为:/n",fp); fputs("/t第一行为正则表达式->Expression: /n",fp); fputs("/t第二行为状态集,括号内为状态数。DFA为->DFAstates(),NFA为->NFAstates(): /n",fp); fputs("/t第三行为开始状态->start: /n",fp); fputs("/t第四行为终结状态集,括号内为状态数->finals(): /n",fp); fputs("/t第五行为字符集,括号内为字符数->finals(): /n",fp); fputs("/t第六行及以下为转换矩阵,其中第六行为字符标题,第一列为状态标题: /n",fp); fputs("/t能通过开始状态到达终结状态,则表示满足该自动机 /n",fp); fputs("/n/t8>. 自己输入自动机的话,格式需要与上述格式完全一致/n",fp); fputs("/t如果输入NFA,每个状态后需添加逗号(,),并以空状态(-1)结尾/n",fp); fputs("/t 注意每行标题后都必须有空白,否则会导致错误/n",fp); fputs("/t 系统默认NFA单个状态最多转换数为8./n",fp); fputs("/n/t9>. 使用本系统会生成如下三个文件:/n",fp); fputs("/tNFA.TXT为保存NFA的文件,DFA.TXT为保存DFA的文件,simpleDFA为保存最简化DFA的文件/n",fp); fputs("/t如需保存文件,将上面相应文件改名即可/n",fp); fputs("/n/t10>. 验证有限自动机的方法有二:/n",fp); fputs("/t一是输入字符串验证,二是自己画状态图(注意:状态图并不唯一)/n",fp); fputs("/n/t11>. 如果本系统使用出现问题,请联系QQ:75732861/n/n/n",fp); fputs("********************************************************************************/n",fp); } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:系统说明模块*/ /*----------------------------------------------------------------------------*/ void System_direction(void) { FILE *fp; if((fp=fopen("词法分析系统使用说明.txt","r"))==NULL) { fp=fopen("词法分析系统使用说明.txt","w"); print_direction(fp); fclose(fp); } fclose(fp); system("cls"); print_direction(stdout); system("pause"); system("cls"); DFANFA_System(); } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:正则式转化为NFA模块*/ /*----------------------------------------------------------------------------*/ void System_ExprToNfa(void) { char *oldexpr,*newexpr; int choice; NFA *nfa=NULL; FILE *fp; NFAwithExpr *Nfawe; char filename[64]={0}; char *buf=NULL,*s; puts("从文件输入正则式吗?键入Y从文件输入,键入N从键盘输入(键入回车默认为Y)"); choice=get_ChoiceYN(); if(choice=='Y') { if((oldexpr=(char*)calloc(EXPRESSION_SIZE,sizeof(char)))==NULL) { puts("生成NFA正则式失败! "); system("pause"); system("cls"); DFANFA_System(); return; } if((newexpr=(char*)calloc(EXPRESSION_SIZE,sizeof(char)))==NULL) { puts("生成NFA正则式失败! "); system("pause"); free(oldexpr); system("cls"); DFANFA_System(); return; } puts("请输入包含正则式的文件(可以使用NFA.TXT、DFA.TXT等文件):"); gets(filename); fflush(stdin); while((fp=fopen(filename,"r"))==NULL) { printf("无法打开文件%s ,请检查该文件是否存在并重新输入:",filename); gets(filename); fflush(stdin); } if((buf=(char*)calloc(BUF_SIZE,sizeof(char)))==NULL) { free(oldexpr); free(newexpr); puts("错误:分配内存错误"); system("pause"); system("cls"); DFANFA_System(); return; } if(fgets(buf,BUF_SIZE,fp)==NULL) { free(oldexpr); free(newexpr); puts("错误:未能读取正则式"); system("pause"); free(buf); system("cls"); DFANFA_System(); return; } fclose(fp); s=buf; while((*s==' '||*s=='/t') && *s!=0) ++s; if(strncmp(s,"Expression:",11)!=0) { puts("警告:不是正确的格式 Expression:"); } while(!is_delim(*s) && *s!=0 ) s++; while((*s==' '||*s=='/t') && *s!=0) ++s; if(strlen(s)==0) { free(oldexpr); free(newexpr); puts("错误:未能读取正则式"); system("pause"); free(buf); system("cls"); DFANFA_System(); return; } trim_delim(s); memcpy(oldexpr,s,strlen(s)); memcpy(newexpr,s,strlen(s)); expr_trans(newexpr); if(!is_LegalExpression(newexpr)) { puts("正则式格式错误,请修改,形如 (a|b)*^a^b^b (注意:表示连接关系需用连接符^号):"); system("pause"); free(oldexpr); free(newexpr); free(buf); system("cls"); DFANFA_System(); return; } if((Nfawe=(NFAwithExpr*)calloc(1,sizeof(NFAwithExpr)))==NULL) { puts("生成NFA失败! "); system("pause"); free(oldexpr); free(newexpr); free(buf); system("cls"); DFANFA_System(); return; } if((Nfawe->nfa=ExprtoNFA(newexpr))==NULL) { puts("生成NFA失败! "); system("pause"); destroy_NFAwithExpr(Nfawe); free(oldexpr); free(newexpr); free(buf); system("cls"); DFANFA_System(); return; } if((fp=fopen("NFA.txt","w"))==NULL) { puts("创建文件NFA.txt失败! "); system("pause"); destroy_NFAwithExpr(Nfawe); free(oldexpr); free(newexpr); free(buf); system("cls"); DFANFA_System(); return; } memcpy(Nfawe->expr,oldexpr,strlen(oldexpr)); print_NFAwithExpr(Nfawe,fp); fclose(fp); system("cls"); if(strcmp(oldexpr,newexpr)!=0) printf("由正则式%s --> {%s}创建NFA成功! NFA保存至NFA.txt。/n/n",oldexpr,newexpr); else printf("由正则式%s 创建NFA成功! NFA保存至NFA.txt。/n/n",oldexpr); free(oldexpr); free(newexpr); free(buf); destroy_NFAwithExpr(Nfawe); DFANFA_System(); } if(choice=='N') { if((oldexpr=(char*)calloc(EXPRESSION_SIZE,sizeof(char)))==NULL) { puts("生成NFA正则式失败! "); system("pause"); system("cls"); DFANFA_System(); return; } if((newexpr=(char*)calloc(EXPRESSION_SIZE,sizeof(char)))==NULL) { puts("生成NFA正则式失败! "); system("pause"); free(oldexpr); system("cls"); DFANFA_System(); return; } puts("请输入正则式:"); while((gets(oldexpr)==NULL) ) { puts("正则式输入错误,请重新输入,形如 (a|b)*^a^b^b (注意:表示连接关系需用连接符^号):"); fflush(stdin); } fflush(stdin); memcpy(newexpr,oldexpr,strlen(oldexpr)); trim_delim(newexpr); expr_trans(newexpr); while(!is_LegalExpression(newexpr)) { puts("正则式输入错误,请重新输入,形如 (a|b)*^a^b^b (注意:表示连接关系需用连接符^号):"); while((gets(oldexpr)==NULL) ) { puts("正则式输入错误,请重新输入,形如 (a|b)*^a^b^b (注意:表示连接关系需用连接符^号):"); fflush(stdin); } fflush(stdin); memcpy(newexpr,oldexpr,strlen(oldexpr)+1); trim_delim(newexpr); expr_trans(newexpr); } if((Nfawe=(NFAwithExpr*)calloc(1,sizeof(NFAwithExpr)))==NULL) { puts("生成NFA失败! "); system("pause"); free(oldexpr); free(newexpr); system("cls"); DFANFA_System(); return; } if((Nfawe->nfa=ExprtoNFA(newexpr))==NULL) { puts("生成NFA失败! "); system("pause"); destroy_NFAwithExpr(Nfawe); free(oldexpr); free(newexpr); system("cls"); DFANFA_System(); return; } if((fp=fopen("NFA.txt","w"))==NULL) { puts("创建文件NFA.txt失败! "); system("pause"); destroy_NFAwithExpr(Nfawe); free(oldexpr); free(newexpr); system("cls"); DFANFA_System(); return; } memcpy(Nfawe->expr,oldexpr,strlen(oldexpr)); print_NFAwithExpr(Nfawe,fp); fclose(fp); system("cls"); if(strcmp(oldexpr,newexpr)!=0) printf("由正则式%s --> {%s}创建NFA成功! NFA保存至NFA.txt。/n/n",oldexpr,newexpr); else printf("由正则式%s 创建NFA成功! NFA保存至NFA.txt。/n/n",oldexpr); free(oldexpr); free(newexpr); destroy_NFAwithExpr(Nfawe); DFANFA_System(); } } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:NFA转换为DFA模块*/ /*----------------------------------------------------------------------------*/ void System_NFAtoDFA(void) { char filename[64]={0}; FILE *fp; NFA *nfa; DFA *dfa; NFAwithExpr *Nfawe; DFAwithExpr *Dfawe; puts("请输入NFA文件(键入回车选择默认文件 NFA.txt):"); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"NFA.txt",7); while((fp=fopen(filename,"r"))==NULL) { printf("无法打开文件%s ,请检查该文件是否存在并重新输入(键入回车选择默认文件 NFA.txt):",filename); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"NFA.txt",7); } if((Nfawe=get_NFAwithExpr(fp))==NULL) { fclose(fp); printf("无法生成NFA!请检查文件%s格式是否正确。/n",filename); system("pause"); system("cls"); DFANFA_System(); return; } fclose(fp); if((Dfawe=(DFAwithExpr*)calloc(1,sizeof(DFAwithExpr)))==NULL) { destroy_NFAwithExpr(Nfawe); puts("生成DFA失败! "); system("pause"); system("cls"); DFANFA_System(); return; } if((Dfawe->dfa=NFAtoDFA(Nfawe->nfa))==NULL) { destroy_NFAwithExpr(Nfawe); destroy_DFAwithExpr(Dfawe); puts("生成DFA失败!"); system("pause"); system("cls"); DFANFA_System(); return; } memcpy(Dfawe->expr,Nfawe->expr,strlen(Nfawe->expr)); if((fp=fopen("DFA.txt","w"))==NULL) { destroy_NFAwithExpr(Nfawe); destroy_DFAwithExpr(Dfawe); puts("创建文件DFA.txt失败! "); system("pause"); system("cls"); DFANFA_System(); return; } print_DFAwithExpr(Dfawe,fp); fclose(fp); destroy_NFAwithExpr(Nfawe); destroy_DFAwithExpr(Dfawe); system("cls"); printf("NFA转换为DFA成功! DFA保存至DFA.txt。/n/n"); DFANFA_System(); } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:DFA化简模块*/ /*----------------------------------------------------------------------------*/ void System_DFAsimplify(void) { char filename[64]={0}; FILE *fp; DFA *dfa=NULL; DFA *simpledfa=NULL; DFAwithExpr *Dfawe; DFAwithExpr *simpleDfawe; puts("请输入DFA文件(键入回车选择默认文件 DFA.txt):"); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"DFA.txt",7); while((fp=fopen(filename,"r"))==NULL) { printf("无法打开文件%s ,请检查该文件是否存在并重新输入(键入回车选择默认文件 DFA.txt):",filename); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"DFA.txt",7); } if((Dfawe=get_DFAwithExpr(fp))==NULL) { fclose(fp); printf("生成DFA失败!请检查文件%s格式是否正确。/n",filename); system("pause"); system("cls"); DFANFA_System(); return; } fclose(fp); if((simpleDfawe=(DFAwithExpr*)calloc(1,sizeof(DFAwithExpr)))==NULL) { destroy_DFAwithExpr(Dfawe); puts("生成DFA失败! "); system("pause"); system("cls"); DFANFA_System(); return; } if((simpleDfawe->dfa=DFA_simplify(Dfawe->dfa))==NULL) { destroy_DFAwithExpr(Dfawe); destroy_DFAwithExpr(simpleDfawe); puts("DFA化简失败!"); system("pause"); system("cls"); DFANFA_System(); return; } memcpy(simpleDfawe->expr, Dfawe->expr,strlen(Dfawe->expr)); if((fp=fopen("simpleDFA.txt","w"))==NULL) { destroy_DFAwithExpr(Dfawe); destroy_DFAwithExpr(simpleDfawe); puts("创建文件simpleDFA.txt失败!"); system("pause"); system("cls"); DFANFA_System(); return; } print_DFAwithExpr(simpleDfawe,fp); fclose(fp); destroy_DFAwithExpr(Dfawe); destroy_DFAwithExpr(simpleDfawe); system("cls"); printf("DFA化简成功! 化简的DFA保存至simpleDFA.txt。/n/n"); DFANFA_System(); } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:模拟NFA模块*/ /*----------------------------------------------------------------------------*/ void System_NFAsimulate(void) { char str[128]={0}; char filename[64]={0}; FILE *fp; char choice; NFAwithExpr *Nfawe; puts("请输入NFA文件(键入回车选择默认文件 NFA.txt):"); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"NFA.txt",7); while((fp=fopen(filename,"r"))==NULL) { printf("无法打开文件%s ,请检查该文件是否存在并重新输入(键入回车选择默认文件 NFA.txt):",filename); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"NFA.txt",7); } if((Nfawe=get_NFAwithExpr(fp))==NULL) { fclose(fp); printf("生成NFA错误!请检查文件%s格式是否正确。/n",filename); system("pause"); system("cls"); DFANFA_System(); return; } fclose(fp); puts("成功读取并生成NFA。"); do { printf("输入一个字符串来验证该NFA(%s):",Nfawe->expr); gets(str); fflush(stdin); if(NFA_execute(Nfawe->nfa,str)) printf("%s 满足该NFA(%s)./n",str,Nfawe->expr); else printf("%s 不满足该NFA(%s)./n",str,Nfawe->expr); puts("继续输入字符串?键入Y继续输入,键入N返回系统菜单(键入回车默认为Y):"); choice=get_ChoiceYN(); }while(choice=='Y'); destroy_NFAwithExpr(Nfawe); system("cls"); DFANFA_System(); } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:模拟DFA模块*/ /*----------------------------------------------------------------------------*/ void System_DFAsimulate(void) { char str[128]={0}; char filename[64]={0}; FILE *fp; char choice; DFAwithExpr *Dfawe; puts("请输入DFA文件(键入回车选择默认文件 simpleDFA.txt):"); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"simpleDFA.txt",13); while((fp=fopen(filename,"r"))==NULL) { printf("无法打开文件%s ,请检查该文件是否存在并重新输入(键入回车选择默认文件 simpleDFA.txt):",filename); gets(filename); fflush(stdin); if(strlen(filename)==0) memcpy(filename,"simpleDFA.txt",13); } if((Dfawe=get_DFAwithExpr(fp))==NULL) { fclose(fp); printf("生成DFA错误!请检查文件%s格式是否正确。/n",filename); system("pause"); system("cls"); DFANFA_System(); return; } fclose(fp); puts("成功读取并生成DFA。"); do { printf("输入一个字符串来验证该DFA(%s):",Dfawe->expr); gets(str); fflush(stdin); if(DFA_execute(Dfawe->dfa,str)) printf("%s 满足该DFA(%s)./n",str,Dfawe->expr); else printf("%s 不满足该DFA(%s)./n",str,Dfawe->expr); puts("继续输入字符串?键入Y继续输入,键入N返回系统菜单(键入回车默认为Y):"); choice=get_ChoiceYN(); }while(choice=='Y'); destroy_DFAwithExpr(Dfawe); system("cls"); DFANFA_System(); } /*----------------------------------------------------------------------------*/ /* DFANFA 系统:退出模块*/ /*----------------------------------------------------------------------------*/ void System_Exit(void) { char choice; puts("确定退出系统?键入N继续,键入Y退出(键入回车默认为Y):"); choice=get_ChoiceYN(); if(choice=='Y') { puts("感谢您对本系统的使用,再见"); puts("如你在使用中有问题请联系QQ:75732861"); return; } else { system("cls"); DFANFA_System(); } } /*----------------------------------------------------------------------------*/ /* DFANFA 系统*/ /*----------------------------------------------------------------------------*/ void DFANFA_System(void) { int choice; DFANFA_Menu(); puts("请输入数字1-7选择相应功能:"); choice=get_Choice(); switch(choice) { case 1: System_ExprToNfa();break; case 2: System_NFAtoDFA();break; case 3: System_DFAsimplify();break; case 4: System_NFAsimulate();break; case 5: System_DFAsimulate();break; case 6: System_direction();break; case 7: System_Exit();break; default: break; } }