DFA DFA::FROM_NFA(NFA nfa){ DFA dfa; NFATable nfa_table = nfa.getTable(); fa_table nfa_table_map = nfa_table.getMapping(); unordered_set<string> visited; int_set first_set = nfa_table_map[0][Symbol::EPSILON]; queue<int_set> set_queue= queue<int_set>{{first_set}}; // set_queue.push(first_set); int dfa_state_count = 0; string set_name = Utils::TO_STRING(first_set); unordered_map<string, int> dfa_state_mapping = unordered_map<string, int> {{ set_name, 0 }}; dfa.addState("q" + to_string(0)); int nfa_state_count = nfa_table_map.size(); while (!set_queue.empty()){ int_set curr_state_set = set_queue.front(); set_queue.pop(); // set_name = Utils::TO_STRING(curr_state_set); string state_name = Utils::TO_STRING(curr_state_set); if (visited.find(state_name) != visited.end()) continue; visited.insert(state_name); bool is_final_state = false; { bool states_visited[nfa_state_count] = { 0 }; for (auto st : curr_state_set) states_visited[st] = true; for (auto curr_state : curr_state_set){ int_set e_closure = nfa_table_map[curr_state][Symbol::EPSILON]; for (auto e_closure_state : e_closure){ if (!states_visited[e_closure_state]){ curr_state_set.insert(e_closure_state); states_visited[e_closure_state] = true; } } } // delete states_visited; } for (auto symbol : nfa_table.getAlphabet()){ if (symbol == Symbol::EPSILON) continue; int_set next_set; bool states_visited[nfa_state_count] = { 0 }; for (auto curr_state : curr_state_set){ if (!is_final_state && curr_state == nfa_table.getFinalState()) is_final_state = true; if (nfa_table_map[curr_state].find(symbol) != nfa_table_map[curr_state].end()){ int_set next_states = nfa_table_map[curr_state][symbol]; for (auto ns : next_states){ int_set e_closure = nfa_table_map[ns][Symbol::EPSILON]; for (auto e_closure_state : e_closure){ if (!states_visited[e_closure_state]){ next_set.insert(e_closure_state); states_visited[e_closure_state] = true; } } } } } string next_state_name = Utils::TO_STRING(next_set); if (next_set.size() > 0){ if (dfa_state_mapping.find(next_state_name) == dfa_state_mapping.end()){ // dfa.addState(next_state_name); dfa_state_count++; dfa.addState("q" + to_string(dfa_state_count)); dfa_state_mapping.insert({next_state_name, dfa_state_count}); } dfa.addTransition(dfa_state_mapping[state_name], dfa_state_mapping[next_state_name], symbol); } // else{ // dfa.addTransition(dfa_state_mapping[state_name], 0, symbol); // } if (is_final_state) dfa.addFinalState(dfa_state_mapping[state_name]); if (next_set.size() > 0 && visited.find(next_state_name) == visited.end()){ set_queue.push(next_set); } // delete states_visited; } } return dfa; }