Speed up mssc
This commit is contained in:
parent
8ed2fd41e1
commit
8a59d19e5c
|
@ -34,6 +34,9 @@ namespace lxs {
|
|||
struct ENFA : public NFA {
|
||||
std::map<State, std::set<State> > epsilonTransitions;
|
||||
virtual std::set<State> eClose(State) const;
|
||||
|
||||
private:
|
||||
mutable std::map<State, std::set<State> > eCloseCache;
|
||||
};
|
||||
|
||||
std::string toDot(const DFA& d);
|
||||
|
|
|
@ -98,6 +98,10 @@ namespace lxs {
|
|||
}
|
||||
|
||||
std::set<State> ENFA::eClose(State s) const {
|
||||
auto cachedIt = eCloseCache.find(s);
|
||||
if (cachedIt != eCloseCache.end()) {
|
||||
return cachedIt->second;
|
||||
}
|
||||
std::set<State> states;
|
||||
std::queue<State> statequeue;
|
||||
statequeue.push(s);
|
||||
|
@ -114,7 +118,7 @@ namespace lxs {
|
|||
}
|
||||
}
|
||||
}
|
||||
return states;
|
||||
return eCloseCache[s] = states;
|
||||
}
|
||||
|
||||
std::set<State> NFA::eClose(State s) const {
|
||||
|
@ -282,9 +286,9 @@ namespace lxs {
|
|||
|
||||
namespace { // Utility function for mssc
|
||||
|
||||
std::set<State> getNextState(std::set<State> oldstate, char symbol, const NFA& e) {
|
||||
std::set<State> getNextState(const std::set<State>& oldstate, char symbol, const NFA& e) {
|
||||
std::set<State> states;
|
||||
for(auto &state: oldstate) {
|
||||
for(const auto &state: oldstate) {
|
||||
auto a = e.delta.find(state);
|
||||
if(a != e.delta.end()) {
|
||||
auto newStates = a->second.find(symbol);
|
||||
|
@ -313,19 +317,27 @@ namespace lxs {
|
|||
}
|
||||
dfa[{}] = trans;
|
||||
|
||||
std::set<char> usedChars;
|
||||
for (const auto& stateTrans : e.delta) {
|
||||
for (const auto& tr : stateTrans.second) {
|
||||
usedChars.insert(tr.first);
|
||||
}
|
||||
}
|
||||
|
||||
//Lazy evaluation, on a still implicit DFA
|
||||
std::queue<std::set<State> > tocheck;
|
||||
tocheck.push(e.eClose(e.starting));
|
||||
while(!tocheck.empty()) {
|
||||
auto state = tocheck.front();
|
||||
auto state = std::move(tocheck.front());
|
||||
tocheck.pop();
|
||||
std::map<char, std::set<State> > trans;
|
||||
for (int c = 0; c < 256; c++) {
|
||||
for (char c : usedChars) {
|
||||
auto nextstate = getNextState(state,c,e);
|
||||
trans[c] = nextstate;
|
||||
if(dfa.find(nextstate) == dfa.end()) {
|
||||
dfa[nextstate] = {};
|
||||
tocheck.push(nextstate);
|
||||
}
|
||||
trans[c] = std::move(nextstate);
|
||||
}
|
||||
dfa[state] = trans;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue