Fix horrible bugs

This commit is contained in:
Robin Jadoul 2016-05-25 21:26:04 +02:00
parent 87d1cf65ae
commit 842867bab4
1 changed files with 41 additions and 22 deletions

View File

@ -144,7 +144,7 @@ namespace lxs {
for (const auto& stateTransPair : d.delta) { for (const auto& stateTransPair : d.delta) {
for (const auto& child : stateTransPair.second) { for (const auto& child : stateTransPair.second) {
rev.delta[stateTransPair.first][child.first].insert(child.second); rev.delta[child.second][child.first].insert(stateTransPair.first);
} }
} }
@ -174,6 +174,8 @@ namespace lxs {
statesToRemove.push_back(i); statesToRemove.push_back(i);
} }
} }
if (reachable.count(deadState) == 0)
statesToRemove.push_back(deadState);
for (State s : statesToRemove) { for (State s : statesToRemove) {
reversed.accepting.erase(s); reversed.accepting.erase(s);
@ -195,6 +197,9 @@ namespace lxs {
q.push(std::make_pair(a, b)); q.push(std::make_pair(a, b));
} }
} }
if (rev.accepting.count(a) != rev.accepting.count(deadState)) {
q.push(std::make_pair(a, deadState));
}
} }
while (!q.empty()) { while (!q.empty()) {
@ -225,7 +230,10 @@ namespace lxs {
std::set<State> done; std::set<State> done;
State cur = 0; State cur = 0;
for (State a = 0; a < d.numStates; a++) { for (State a = 0; a <= d.numStates; a++) {
if (a == d.numStates)
a = deadState;
if (reachables.count(a) == 0 || done.count(a) > 0) continue; if (reachables.count(a) == 0 || done.count(a) > 0) continue;
Priority prior; Priority prior;
@ -236,19 +244,32 @@ namespace lxs {
} }
newStates[a] = cur; newStates[a] = cur;
done.insert(a); if (a == deadState)
for (State b = a + 1; b < d.numStates; b++) { newStates[a] = deadState;
if (reachables.count(b) > 0 && dist[a].count(b) == 0) {
done.insert(b);
newStates[b] = cur;
if (d.accepting.count(b) > 0) { done.insert(a);
Priority bprior = d.priority.find(b)->second; if (a != deadState) {
if (bprior < prior) { for (State b = a + 1; b <= d.numStates; b++) {
prior = bprior; if (b == d.numStates)
acTok = d.acceptingToken.find(b)->second; b = deadState;
if (reachables.count(b) > 0 && dist[a].count(b) == 0) {
done.insert(b);
newStates[b] = cur;
if (b == deadState)
newStates[b] = deadState;
if (d.accepting.count(b) > 0) {
Priority bprior = d.priority.find(b)->second;
if (bprior < prior) {
prior = bprior;
acTok = d.acceptingToken.find(b)->second;
}
} }
} }
if (b == deadState)
b = d.numStates;
} }
} }
@ -258,8 +279,13 @@ namespace lxs {
min.acceptingToken[a] = acTok; min.acceptingToken[a] = acTok;
} }
++min.numStates; if (a != deadState) {
++cur; ++min.numStates;
++cur;
}
if (a == deadState)
a = d.numStates;
} }
done.clear(); done.clear();
@ -317,13 +343,6 @@ namespace lxs {
} }
dfa[{}] = trans; 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 //Lazy evaluation, on a still implicit DFA
std::queue<std::set<State> > tocheck; std::queue<std::set<State> > tocheck;
tocheck.push(e.eClose(e.starting)); tocheck.push(e.eClose(e.starting));
@ -331,7 +350,7 @@ namespace lxs {
auto state = std::move(tocheck.front()); auto state = std::move(tocheck.front());
tocheck.pop(); tocheck.pop();
std::map<char, std::set<State> > trans; std::map<char, std::set<State> > trans;
for (char c : usedChars) { for (int c = 0; c < 256; c++) {
auto nextstate = getNextState(state,c,e); auto nextstate = getNextState(state,c,e);
if(dfa.find(nextstate) == dfa.end()) { if(dfa.find(nextstate) == dfa.end()) {
dfa[nextstate] = {}; dfa[nextstate] = {};