Clean up mssc
This commit is contained in:
parent
95f8b4dac1
commit
32f4d6be81
|
@ -2,6 +2,7 @@
|
||||||
#ifndef AUTOMATA_H
|
#ifndef AUTOMATA_H
|
||||||
#define AUTOMATA_H
|
#define AUTOMATA_H
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -11,6 +12,7 @@
|
||||||
namespace lxs {
|
namespace lxs {
|
||||||
typedef unsigned long long State;
|
typedef unsigned long long State;
|
||||||
typedef unsigned long long Priority;
|
typedef unsigned long long Priority;
|
||||||
|
const State deadState = ULLONG_MAX;
|
||||||
|
|
||||||
struct Automaton {
|
struct Automaton {
|
||||||
State numStates = 0;
|
State numStates = 0;
|
||||||
|
|
|
@ -103,7 +103,7 @@ namespace lxs {
|
||||||
while(!statequeue.empty()) {
|
while(!statequeue.empty()) {
|
||||||
auto state = statequeue.front();
|
auto state = statequeue.front();
|
||||||
statequeue.pop();
|
statequeue.pop();
|
||||||
auto newStates = epsilonTransitions.find(state)->second;
|
const auto& newStates = epsilonTransitions.find(state)->second;
|
||||||
for(auto newstate: newStates) {
|
for(auto newstate: newStates) {
|
||||||
if(states.find(newstate) == states.end()) {
|
if(states.find(newstate) == states.end()) {
|
||||||
states.insert(newstate);
|
states.insert(newstate);
|
||||||
|
@ -296,20 +296,21 @@ namespace lxs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(states.empty()) states.insert(-1);
|
|
||||||
return states;
|
return states;
|
||||||
}
|
}
|
||||||
|
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
||||||
DFA mssc(const NFA& e) {
|
DFA mssc(const NFA& e) {
|
||||||
|
//Temporary, improper dfa structure
|
||||||
std::map<std::set<State>,std::map<char,std::set<State> > > dfa;
|
std::map<std::set<State>,std::map<char,std::set<State> > > dfa;
|
||||||
std::map<char, std::set<State> > trans;
|
std::map<char, std::set<State> > trans;
|
||||||
for (int c = 0; c < 256; c++) {
|
for (int c = 0; c < 256; c++) {
|
||||||
trans.insert(std::pair<char,std::set<State> >(c,{(unsigned long long) -1}));
|
trans[c] = {};
|
||||||
}
|
}
|
||||||
dfa.insert(std::pair<std::set<State>,std::map<char,std::set<State> > > ({(unsigned long long) -1},trans));
|
dfa[{}] = trans;
|
||||||
|
|
||||||
|
//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));
|
||||||
while(!tocheck.empty()) {
|
while(!tocheck.empty()) {
|
||||||
|
@ -318,46 +319,63 @@ namespace lxs {
|
||||||
std::map<char, std::set<State> > trans;
|
std::map<char, std::set<State> > trans;
|
||||||
for (int c = 0; c < 256; c++) {
|
for (int c = 0; c < 256; c++) {
|
||||||
auto nextstate = getNextState(state,c,e);
|
auto nextstate = getNextState(state,c,e);
|
||||||
trans.insert(std::pair<char,std::set<State> > (c,nextstate));
|
trans[c] = nextstate;
|
||||||
if(dfa.find(nextstate) == dfa.end()) {
|
if(dfa.find(nextstate) == dfa.end()) {
|
||||||
tocheck.push(nextstate);
|
tocheck.push(nextstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dfa.insert(std::pair<std::set<State>, std::map<char,std::set<State> > > (state,trans));
|
dfa[state] = trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Assign sequential indices for the actual DFA
|
||||||
std::map<std::set<State>,State> lookup;
|
std::map<std::set<State>,State> lookup;
|
||||||
State numStates = 0;
|
State numStates = 0;
|
||||||
for(auto &state:dfa) {
|
for(auto &state : dfa) {
|
||||||
lookup.insert(std::pair<std::set<State>, State> (state.first, numStates++));
|
if (state.first.size())
|
||||||
|
lookup[state.first] = numStates++;
|
||||||
|
else
|
||||||
|
lookup[state.first] = deadState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Setup the actual DFA
|
||||||
DFA result;
|
DFA result;
|
||||||
result.numStates = numStates;
|
result.numStates = numStates;
|
||||||
result.starting = lookup.find(e.eClose(e.starting))->second;
|
result.starting = lookup.find(e.eClose(e.starting))->second;
|
||||||
std::map<Priority, State> reversepriority;
|
|
||||||
|
//Setup the transitions
|
||||||
|
//Merge priorities and acceptingTokens
|
||||||
for(auto &state:dfa) {
|
for(auto &state:dfa) {
|
||||||
std::set<Priority> priorityset;
|
Priority priority = std::numeric_limits<Priority>::max();
|
||||||
|
std::string acTok = "";
|
||||||
|
|
||||||
State newstate = lookup.find(state.first)->second;
|
State newstate = lookup.find(state.first)->second;
|
||||||
std::map<char,State> newtransitions;
|
std::map<char,State> newtransitions;
|
||||||
for(auto &item:state.first) {
|
for(auto &item : state.first) {
|
||||||
auto accepting = e.priority.find(item);
|
if(e.accepting.count(item) > 0) {
|
||||||
if(accepting != e.priority.end()) {
|
const auto& newPrior = e.priority.find(item)->second;
|
||||||
priorityset.insert(accepting->second);
|
if (newPrior < priority)
|
||||||
|
{
|
||||||
|
priority = newPrior;
|
||||||
|
acTok = e.acceptingToken.find(item)->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!priorityset.empty()) {
|
|
||||||
|
//Insert the found priority
|
||||||
|
if(priority != std::numeric_limits<Priority>::max()) {
|
||||||
result.accepting.insert(newstate);
|
result.accepting.insert(newstate);
|
||||||
result.priority.insert(std::pair<State,Priority> (newstate,*priorityset.begin()));
|
result.priority[newstate] = priority;
|
||||||
reversepriority.insert(std::pair<Priority,State> (*priorityset.begin(),newstate));
|
result.acceptingToken[newstate] = acTok;
|
||||||
}
|
}
|
||||||
for(auto &tranition:state.second) {
|
|
||||||
newtransitions.insert(std::pair<char,State> (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<State,std::map<char,State> > (newstate,newtransitions));
|
|
||||||
}
|
result.delta[newstate] = std::move(newtransitions);
|
||||||
for(auto &priority: e.priority) {
|
|
||||||
auto newstate = reversepriority.find(priority.second)->second;
|
|
||||||
result.acceptingToken.insert(std::pair<State,std::string> (newstate,e.acceptingToken.find(priority.first)->second));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue