diff --git a/include/Lexesis/automata.h b/include/Lexesis/automata.h index a6335b1..67d4680 100644 --- a/include/Lexesis/automata.h +++ b/include/Lexesis/automata.h @@ -2,6 +2,7 @@ #ifndef AUTOMATA_H #define AUTOMATA_H +#include #include #include #include @@ -11,6 +12,7 @@ namespace lxs { typedef unsigned long long State; typedef unsigned long long Priority; + const State deadState = ULLONG_MAX; struct Automaton { State numStates = 0; diff --git a/src/automata.cpp b/src/automata.cpp index b0fbf9e..7896118 100644 --- a/src/automata.cpp +++ b/src/automata.cpp @@ -103,7 +103,7 @@ namespace lxs { while(!statequeue.empty()) { auto state = statequeue.front(); statequeue.pop(); - auto newStates = epsilonTransitions.find(state)->second; + const auto& newStates = epsilonTransitions.find(state)->second; for(auto newstate: newStates) { if(states.find(newstate) == states.end()) { states.insert(newstate); @@ -296,20 +296,21 @@ namespace lxs { } } } - if(states.empty()) states.insert(-1); return states; } } //namespace DFA mssc(const NFA& e) { + //Temporary, improper dfa structure std::map,std::map > > dfa; std::map > trans; for (int c = 0; c < 256; c++) { - trans.insert(std::pair >(c,{(unsigned long long) -1})); + trans[c] = {}; } - dfa.insert(std::pair,std::map > > ({(unsigned long long) -1},trans)); + dfa[{}] = trans; + //Lazy evaluation, on a still implicit DFA std::queue > tocheck; tocheck.push(e.eClose(e.starting)); while(!tocheck.empty()) { @@ -318,46 +319,63 @@ namespace lxs { std::map > trans; for (int c = 0; c < 256; c++) { auto nextstate = getNextState(state,c,e); - trans.insert(std::pair > (c,nextstate)); + trans[c] = nextstate; if(dfa.find(nextstate) == dfa.end()) { tocheck.push(nextstate); } } - dfa.insert(std::pair, std::map > > (state,trans)); + dfa[state] = trans; } + + //Assign sequential indices for the actual DFA std::map,State> lookup; State numStates = 0; - for(auto &state:dfa) { - lookup.insert(std::pair, State> (state.first, numStates++)); + for(auto &state : dfa) { + if (state.first.size()) + lookup[state.first] = numStates++; + else + lookup[state.first] = deadState; } + + //Setup the actual DFA DFA result; result.numStates = numStates; result.starting = lookup.find(e.eClose(e.starting))->second; - std::map reversepriority; + + //Setup the transitions + //Merge priorities and acceptingTokens for(auto &state:dfa) { - std::set priorityset; + Priority priority = std::numeric_limits::max(); + std::string acTok = ""; + State newstate = lookup.find(state.first)->second; std::map newtransitions; - for(auto &item:state.first) { - auto accepting = e.priority.find(item); - if(accepting != e.priority.end()) { - priorityset.insert(accepting->second); + for(auto &item : state.first) { + if(e.accepting.count(item) > 0) { + const auto& newPrior = e.priority.find(item)->second; + if (newPrior < priority) + { + priority = newPrior; + acTok = e.acceptingToken.find(item)->second; + } } } - if(!priorityset.empty()) { + + //Insert the found priority + if(priority != std::numeric_limits::max()) { result.accepting.insert(newstate); - result.priority.insert(std::pair (newstate,*priorityset.begin())); - reversepriority.insert(std::pair (*priorityset.begin(),newstate)); + result.priority[newstate] = priority; + result.acceptingToken[newstate] = acTok; } - for(auto &tranition:state.second) { - newtransitions.insert(std::pair (tranition.first, lookup.find(tranition.second)->second)); + + //Do transition + for(auto &transition : state.second) { + newtransitions[transition.first] = lookup[transition.second]; } - result.delta.insert(std::pair > (newstate,newtransitions)); - } - for(auto &priority: e.priority) { - auto newstate = reversepriority.find(priority.second)->second; - result.acceptingToken.insert(std::pair (newstate,e.acceptingToken.find(priority.first)->second)); + + result.delta[newstate] = std::move(newtransitions); } + return result; }