dfa * createDFA(char *regex){ nfa* automata=createNFA(regex); int i=0; //printf("Creating DFA with %d states\n\t",automata->nStates); dfa *deter_auto=(dfa*)malloc(sizeof(dfa));//deterministic automata deter_auto->nStates= automata->nStates; deter_auto->states = (int **)calloc(automata->nStates,sizeof(int*)); deter_auto->quants = (int * )calloc(automata->nStates,sizeof(int )); if(automata==NULL){ //printf("No automata found\n"); return; } int index; for(;i<automata->nStates;i++){ //printf("state #%d : ",i); index=1; deter_auto->states[i]=(int*)calloc(automata->states[i]->size+1,sizeof(int)); deter_auto->states[i][0]=automata->states[i]->size; deter_auto->quants[i]=automata->quants[i]; while(automata->states[i]->size!=0){ //printf("%c ",getFront(automata->states[i])); deter_auto->states[i][index++]=getFront(automata->states[i]); dequeue(automata->states[i]); } //printf(" | "); //printf(" - quant : %d\n\t",automata->quants[i]); } return deter_auto; }
pair<int,int> NFA::createNFA(TreeNode* root) { switch(root->getKind()) { case CONNECT : { auto left_nfa = createNFA(root->left); auto right_nfa = createNFA(root->right); addEdge(EPSILON,' ',left_nfa.second,right_nfa.first); return {left_nfa.first,right_nfa.second}; } case OR : { auto left_nfa = createNFA(root->left); auto right_nfa = createNFA(root->right); int new_left = getNewNodeNum(); int new_right = getNewNodeNum(); addEdge(EPSILON,' ',new_left,left_nfa.first); addEdge(EPSILON,' ',new_left,right_nfa.first); addEdge(EPSILON,' ',left_nfa.second,new_right); addEdge(EPSILON,' ',right_nfa.second,new_right); return {new_left,new_right}; } case REPEAT : { auto nfa = createNFA(root->left); int new_left = getNewNodeNum(); int new_right = getNewNodeNum(); addEdge(EPSILON,' ',new_left,nfa.first); addEdge(EPSILON,' ',new_left,new_right); addEdge(EPSILON,' ',nfa.second,nfa.first); addEdge(EPSILON,' ',nfa.second,new_right); return {new_left,new_right}; } case LEAF : { int new_left = getNewNodeNum(); int new_right = getNewNodeNum(); addEdge(CHAR,root->getVal(),new_left,new_right); return {new_left,new_right}; } } }
static void createNFA(NFA::Builder* nfaBuilder,Node* node,NFA::StateIndex initialState,NFA::StateIndex finalState) { switch(node->type) { case NodeType::lit: { auto lit = (Lit*)node; NFA::addEdge(nfaBuilder,initialState,lit->charSet,finalState); break; } case NodeType::zeroOrMore: { auto zeroOrMore = (ZeroOrMore*)node; createNFA(nfaBuilder,zeroOrMore->child,initialState,initialState); NFA::addEpsilonEdge(nfaBuilder,initialState,finalState); break; }; case NodeType::oneOrMore: { auto oneOrMore = (OneOrMore*)node; auto intermediateState = NFA::addState(nfaBuilder); createNFA(nfaBuilder,oneOrMore->child,initialState,intermediateState); createNFA(nfaBuilder,oneOrMore->child,intermediateState,intermediateState); NFA::addEpsilonEdge(nfaBuilder,intermediateState,finalState); break; } case NodeType::optional: { auto optional = (Optional*)node; createNFA(nfaBuilder,optional->child,initialState,finalState); NFA::addEpsilonEdge(nfaBuilder,initialState,finalState); break; } case NodeType::alt: { auto alt = (Alt*)node; createNFA(nfaBuilder,alt->firstChild,initialState,finalState); createNFA(nfaBuilder,alt->secondChild,initialState,finalState); break; } case NodeType::seq: { auto seq = (Seq*)node; auto intermediateState = NFA::addState(nfaBuilder); createNFA(nfaBuilder,seq->firstChild,initialState,intermediateState); createNFA(nfaBuilder,seq->secondChild,intermediateState,finalState); break; } default: Errors::unreachable(); }; }
void addToNFA(const char* regexpString,NFA::Builder* nfaBuilder,NFA::StateIndex initialState,NFA::StateIndex finalState) { Node* rootNode = parse(regexpString); createNFA(nfaBuilder,rootNode,initialState,finalState); delete rootNode; }