void CAG_RegEx::ConvertNFAtoDFA() { // Clean up the DFA Table first for(int i=0; i<m_DFATable.size(); ++i) delete m_DFATable[i]; m_DFATable.clear(); // Check is NFA table empty if(m_NFATable.size() == 0) return; // Reset the state id for new naming m_nNextStateID = 0; // Array of unprocessed DFA states vector<CAG_State*> unmarkedStates; // Starting state of DFA is epsilon closure of // starting state of NFA state (set of states) set<CAG_State*> DFAStartStateSet; set<CAG_State*> NFAStartStateSet; NFAStartStateSet.insert(m_NFATable[0]); EpsilonClosure(NFAStartStateSet, DFAStartStateSet); // Create new DFA State (start state) from the NFA states CAG_State *DFAStartState = new CAG_State(DFAStartStateSet, ++m_nNextStateID); // Add the start state to the DFA m_DFATable.push_back(DFAStartState); // Add the starting state to set of unprocessed DFA states unmarkedStates.push_back(DFAStartState); while(!unmarkedStates.empty()) { // process an unprocessed state CAG_State* processingDFAState = unmarkedStates[unmarkedStates.size()-1]; unmarkedStates.pop_back(); // for each input signal a set<char>::iterator iter; for(iter=m_InputSet.begin(); iter!=m_InputSet.end(); ++iter) { set<CAG_State*> MoveRes, EpsilonClosureRes; Move(*iter, processingDFAState->GetNFAState(), MoveRes); EpsilonClosure(MoveRes, EpsilonClosureRes); // Check is the resulting set (EpsilonClosureSet) in the // set of DFA states (is any DFA state already constructed // from this set of NFA states) or in pseudocode: // is U in D-States already (U = EpsilonClosureSet) BOOL bFound = FALSE; CAG_State *s = NULL; for(i=0; i<m_DFATable.size(); ++i) { s = m_DFATable[i]; if(s->GetNFAState() == EpsilonClosureRes) { bFound = TRUE; break; } } if(!bFound) { CAG_State* U = new CAG_State(EpsilonClosureRes, ++m_nNextStateID); unmarkedStates.push_back(U); m_DFATable.push_back(U); // Add transition from processingDFAState to new state on the current character processingDFAState->AddTransition(*iter, U); } else { // This state already exists so add transition from // processingState to already processed state processingDFAState->AddTransition(*iter, s); } } } }
void CompileNfaToDfa( Context* con ) { InitStateEdge( con ); //Node* n = DfaAddNode( con ); Node* n = new Node(); n->statelist = NULL; n->edgelist = NULL; n->next = NULL; Node* t = con->nfa_stacktop->nfa->starts; AddState( n, MakeDfaState( con, t->statelist->dummy ) ); EpsilonClosure( con, n, n->statelist ); PushDfaNode( con, n ); con->dfa = new Dfa(); con->dfa->next = NULL; con->dfa->starts = n; con->dfa->accepts = NULL; DfaNodeElement* dne; while ( ( dne = FirstUncoloredNode( con ) ) != NULL ) { n = dne->node; // test code DfaNodeElement* _dne = con->dne_queue; printf( "printf dne queue\n" ); while ( _dne != NULL ) { Node *_n = _dne->node; State* _ss = _n->statelist; while ( _ss != NULL ) { printf( "%d\t", _ss->dummy ); _ss = _ss->next; } printf( " colored:%d\n", _dne->colored ); _dne = _dne->next; } // test code end dne->colored = true; State* s = n->statelist; Symbol* sym = con->symbollist; Weight w; while ( sym != NULL ) { w = sym->symbol; if ( w == EPSILON ) continue; StateEdge* se = sequeue; Node *nn = new Node(); nn->statelist = NULL; nn->edgelist = NULL; nn->next = NULL; while ( se != NULL ) { //printf( "%c", se->w ); if ( se->w == w ) { // if find se->from in n->statelist; bool found = false; State* _s = n->statelist; while ( _s != NULL ) { if ( _s->dummy == se->from->dummy ) { found = true; break; } _s = _s->next; } if ( found ) { AddState( nn, MakeDfaState( con, se->to->dummy ) ); } } se = se->next; } EpsilonClosure( con, nn, nn->statelist ); if ( nn->statelist == NULL ) { delete nn; } else { if ( FindDfaNode( con, nn ) == NULL ) { PushDfaNode( con, nn ); } else { Node* temp = nn; nn = FindDfaNode( con, nn ); State* prev, *next; prev = next = temp->statelist; while ( next != NULL ) { prev = next; next = next->next; delete prev; } delete temp; } Edge* ee = new Edge(); ee->dest = nn; ee->weight = w; ee->next = n->edgelist; n->edgelist = ee; } sym = sym->next; } } dne = con->dne_queue; while ( dne != NULL ) { Node *_n = dne->node; State* _ss = _n->statelist; while ( _ss != NULL ) { if ( _ss->dummy == con->nfa_stacktop->nfa->accepts->statelist->dummy ) { _n->next = con->dfa->accepts; con->dfa->accepts = _n; break; } _ss = _ss->next; } dne = dne->next; } // test code DfaNodeElement* _dne = con->dne_queue; /* printf( "printf dne queue\n" ); while ( _dne != NULL ) { Node *_n = _dne->node; State* _ss = _n->statelist; while ( _ss != NULL ) { printf( "%d\t", _ss->dummy ); _ss = _ss->next; } printf( " colored:%d\n", _dne->colored ); _dne = _dne->next; } */ // test code end DestoryStateEdge(); //DestoryContext( con ); }