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);
			}
		}
	}
}
Пример #2
0
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 );
}