// This is called when a tree has built. void update() { assert(root != NULL); setAccepts(); //root->print(); //std::cout << std::endl; //-- NFAState *next = nfa->getStartState(); for(std::list<CNode *>::iterator i = root->children.begin(); i != root->children.end(); ++i ) { CNode *node = *i; if(node->children.empty()) { NFAState *tmp = nfa->newState(); next->addEdge(tmp, node->value); if(node->accept) tmp->makeFinal(acceptStr, acceptFlags); next = tmp; } else { NFAState *tmp = next; std::list<CNode *>::iterator j = node->children.begin(); for(unsigned i = 1; i < node->children.size(); ++i, ++j) { NFAState *tmp2 = nfa->newState(); tmp->addEdge(tmp2, (*j)->value); tmp = tmp2; } tmp->addEdge(next, node->children.back()->value); } } //-- }
void useNfa() { NewQDFA dfa; buildTransitionMap(dfa); NFA *tmpNFA = nfa; NFA &nfa = *tmpNFA; //--- NewQDFA &output = nfa.newQDFA; QDFASet startState; startState.state.insert(nfa.getStartState()); // std::cout << "---begin NFA---" << std::endl; std::set<QDFASet> wanted; wanted.insert(startState); output.start = startState; while(!wanted.empty()) { std::set<QDFASet>::iterator j = wanted.begin(); QDFASet js = *j; wanted.erase(j); // 'js' has a set of QNFAState pointers. if(output.transitionMap.find(js) != output.transitionMap.end()) { std::cout << "NFA to DFA - internal error" << std::endl; throw -1; } output.transitionMap[js] = NewQDFAItems(); NewQDFAItems &io = output.transitionMap[js]; bool accept = false; std::string finalStr = ""; unsigned finalFlags = 0; //[+] // 'js' is a set of QNFAState pointers that we want. // Look at each row in 'js'. for(std::set<QNFAState *>::iterator k = js.state.begin(); k != js.state.end(); ++k ) { if((*k)->isFinal) { if(accept) { if(finalStr != (*k)->finalStr || finalFlags != (*k)->finalFlags) { std::cout << "Ambiguous accept string or flags!" << std::endl; throw -1; } } accept = true; finalStr = (*k)->finalStr; finalFlags = (*k)->finalFlags; //std::cout << "accept:"; } //std::cout << std::hex << *k << std::dec << " "; // Now for each row in 'js', go thru each column. for(std::map<int, QNFATarget >::iterator h = (*k)->transitionMap.begin(); h != (*k)->transitionMap.end(); ++h ) { for(std::set<QNFAState *>::iterator hh = h->second.targets.begin(); hh != h->second.targets.end(); ++hh ) { io.targets[h->first].state.insert(*hh); } } } // Now look at io.targets[x] for all x. for(std::map<int, QDFASet>::iterator xi = io.targets.begin(); xi != io.targets.end(); ++xi ) { QDFASet &xt = xi->second; if(output.transitionMap.find(xt) == output.transitionMap.end()) { wanted.insert(xt); } } if(accept) { io.accept = true; io.finalStr = finalStr; io.finalFlags = finalFlags; } } //std::cout << std::endl; //std::cout << "--- end NFA ---" << std::endl; //generateOutput(); //--- useDfa(output); }