Exemplo n.º 1
0
    DfaGraphComplement(V3Graph* dfagraphp, V3EdgeFuncP edgeFuncp)
	: GraphAlg(dfagraphp, edgeFuncp) {
	if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_in");

	// Vertex::m_user begin: 1 indicates new edge, no more processing
	m_graphp->userClearEdges();

	m_tempNewerReject = new DfaVertex(graphp());
	add_complement_edges();
	if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap");

	m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject=NULL;
	if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out");
    }
Exemplo n.º 2
0
    void optimize_orphans() {
	// Remove states that don't come from start
	// Presumably the previous optimization orphaned them.

	// Vertex::m_user begin: 1 indicates on the work list, 2 processed
	// (Otherwise we might have nodes on the list twice, and reference after deleting them.)
	m_graphp->userClearVertices();

	DfaVertex* startp = graphp()->findStart();
	stack<V3GraphVertex*> workps;  workps.push(startp);

	// Mark all nodes connected to start
	while (!workps.empty()) {
	    V3GraphVertex* vertexp = workps.top(); workps.pop();
	    vertexp->user(2);  // Processed
	    // Add nodes from here to the work list
	    for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
		V3GraphVertex* tovertexp = edgep->top();
		if (!tovertexp->user()) {
		    workps.push(tovertexp);
		    tovertexp->user(1);
		}
	    }
	}

	// Delete all nodes not connected
	for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) {
	    nextp = vertexp->verticesNextp();
	    if (!vertexp->user()) {
		vertexp->unlinkDelete(m_graphp); vertexp=NULL;
	    }
	}
    }
Exemplo n.º 3
0
    DfaVertex* newDfaVertex(DfaVertex* nfaTemplatep=NULL) {
	DfaVertex* vertexp = new DfaVertex (graphp());
	vertexp->color(1);  // Mark as dfa
	if (nfaTemplatep && nfaTemplatep->start()) vertexp->start(true);
	if (nfaTemplatep && nfaTemplatep->accepting()) vertexp->accepting(true);
	UINFO(9, "        New "<<vertexp<<endl);
	return vertexp;
    }
Exemplo n.º 4
0
    void add_complement_edges() {
	// Find accepting vertex
	DfaVertex* acceptp = NULL;
	for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
	    if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
		if (vvertexp->accepting()) {
		    acceptp = vvertexp;
		    break;
		}
	    }
	}
	if (!acceptp) v3fatalSrc("No accepting vertex in DFA\n");

	// Remap edges
	for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
	    if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
		//UINFO(9, "   on vertex "<<vvertexp->name()<<endl);
		if (!vvertexp->accepting() && vvertexp != m_tempNewerReject) {
		    for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
			nextp = edgep->outNextp();
			if (!edgep->user()) { // Not processed
			    // Old edges to accept now go to new reject
			    DfaEdge* vedgep = static_cast<DfaEdge*>(edgep);
			    DfaVertex* tovertexp = static_cast<DfaVertex*>(edgep->top());
			    if (tovertexp->accepting()) {
				new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep);
				edgep->unlinkDelete(); edgep=NULL;
			    }

			    // NOT of all values goes to accept
			    // We make a edge for each value to OR, IE
			    // edge(complemented,a) edge(complemented,b) means !(a | b)
			    if (!tovertexp->accepting()) {  // Note we must include edges moved above to reject
				DfaEdge* newp = new DfaEdge (graphp(), vvertexp, acceptp, vedgep);
				newp->complement(!newp->complement());
				newp->user(1);
			    }
			}
		    }
		}
	    }
	}
    }
Exemplo n.º 5
0
sexpr read_directory_sx (sexpr rx)
{
    sexpr r = sx_end_of_list;

    if (graphp (rx)) {
        r = read_directory_rx (".", rx);
    } else if (stringp (rx)) {
        r = read_directory (sx_string (rx));
    } else if (symbolp (rx)) {
        r = read_directory (sx_symbol (rx));
    }

    return r;
}
Exemplo n.º 6
0
    void main() {
	UINFO(5,"Dfa to Nfa conversion...\n");
	// Vertex::color() begin: 1 indicates vertex on DFA graph, 0=NFA graph
	m_graphp->clearColors();
	// Vertex::m_user begin: # indicates processed this m_step number
	m_graphp->userClearVertices();

	if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_nfa");

	// Find NFA start
	DfaVertex* nfaStartp = graphp()->findStart();

	// Create new DFA State (start state) from the NFA states
	DfaVertex* dfaStartp = newDfaVertex(nfaStartp);

	DfaStates dfaUnprocps;		// Unprocessed DFA nodes
	dfaUnprocps.push_back(dfaStartp);

	UINFO(5,"Starting state conversion...\n");
	// Form DFA starting state from epsilon closure of NFA start
	nextStep();
	DfaStates workps; workps.push_back(nfaStartp);

	while (!workps.empty()) {  // While work
	    DfaVertex* nfaStatep = workps.back(); workps.pop_back();
	    //UINFO(9," Processing "<<nfaStatep<<endl);
	    nfaStatep->user(m_step);	// Mark as processed
	    // Add a edge so we can find NFAs from a given DFA.
	    // The NFA will never see this edge, because we only look at TO edges.
	    new DfaEdge(graphp(), dfaStartp, nfaStatep, DfaEdge::NA());
	    // Find epsilon closure of this nfa node, and destinations to work list
	    for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
		DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
		DfaVertex* nfaStatep = static_cast<DfaVertex*>(nfaEdgep->top());
		//UINFO(9,"   Consider "<<nfaEdgep->top()<<" EP "<<cNfaEdgep->epsilon()<<endl);
		if (cNfaEdgep->epsilon()
		    && unseenNfaThisStep(nfaStatep)) {  // Not processed?
		    workps.push_back(nfaStatep);
		}
	    }
	}
	if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_start");
	insertDfaOrigins(dfaStartp);

	int i=0;
	UINFO(5,"Main state conversion...\n");
	while (!dfaUnprocps.empty()) {
	    DfaVertex* dfaStatep = dfaUnprocps.back(); dfaUnprocps.pop_back();
	    UINFO(9,"  On dfaState "<<dfaStatep<<endl);

	    // From this dfaState, what corresponding nfaStates have what inputs?
	    set<DfaInput> inputs;
	    // Foreach NFA state (this DFA state was formed from)
	    for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) {
		if (nfaState(dfaEdgep->top())) {
		    DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
		    // Foreach input on this nfaStatep
		    for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
			DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
			if (!cNfaEdgep->epsilon()) {
			    if (inputs.find(cNfaEdgep->input()) == inputs.end()) {
				inputs.insert(cNfaEdgep->input());
				UINFO(9,"    Input to "<<dfaStatep<<" is "<<(void*)(cNfaEdgep->input())<<" via "<<nfaStatep<<endl);
			    }
			}
		    }
		}
	    }

	    // Foreach input state (NFA inputs of this DFA state)
	    for (set<DfaInput>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) {
		DfaInput input = *inIt;
		UINFO(9,"    ==="<<++i<<"=======================\n");
		UINFO(9,"    On input "<<(void*)(input)<<endl);

		// Find all states reachable for given input
		DfaStates nfasWithInput;
		findNfasWithInput(dfaStatep, input, nfasWithInput/*ref*/);

		// nfasWithInput now maps to the DFA we want a transition to.
		// Does a DFA already exist with this, and only this subset of NFA's?
		DfaVertex* toDfaStatep = findDfaOrigins(nfasWithInput);
		if (!toDfaStatep) {
		    // Doesn't exist, make new dfa state corresponding to this one,
		    toDfaStatep = newDfaVertex();
		    dfaUnprocps.push_back(toDfaStatep);  // Add to process list
		    // Track what nfa's point to it.
		    for (DfaStates::const_iterator nfaIt=nfasWithInput.begin(); nfaIt!=nfasWithInput.end(); ++nfaIt) {
			UINFO(9,"          NewContainsNfa "<<*nfaIt<<endl);
			new DfaEdge (graphp(), toDfaStatep, *nfaIt, DfaEdge::NA());
			if ((*nfaIt)->accepting()) toDfaStatep->accepting(true);
		    }
		    insertDfaOrigins(toDfaStatep);
		}
		// Add input transition
		new DfaEdge (graphp(), dfaStatep, toDfaStatep, input);

		if (debug()>=6) m_graphp->dumpDotFilePrefixed("step");
	    }
	}

	// Remove old NFA states
	UINFO(5,"Removing NFA states...\n");
	if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_withnfa");
	for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) {
	    nextp = vertexp->verticesNextp();
	    if (nfaState(vertexp)) {
		vertexp->unlinkDelete(m_graphp); vertexp=NULL;
	    }
	}

	UINFO(5,"Done.\n");
	if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_done");
    }