First try for mssc, probably still has a few bugs
This commit is contained in:
parent
e323bb5084
commit
0f6742f005
103
src/automata.cpp
103
src/automata.cpp
|
@ -1,5 +1,6 @@
|
|||
#include "Lexesis/automata.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
|
@ -94,11 +95,25 @@ namespace lxs {
|
|||
return s;
|
||||
}
|
||||
|
||||
std::set<State> ENFA::eClose(State) {
|
||||
|
||||
std::set<State> ENFA::eClose(State s) const {
|
||||
std::set<State> states;
|
||||
std::queue<State> statequeue;
|
||||
statequeue.push(s);
|
||||
while(!statequeue.empty()) {
|
||||
auto state = statequeue.front();
|
||||
statequeue.pop();
|
||||
auto newStates = epsilonTransitions.find(state)->second;
|
||||
for(auto newstate: newStates) {
|
||||
if(states.find(newstate) == states.end()) {
|
||||
states.insert(newstate);
|
||||
statequeue.push(newstate);
|
||||
}
|
||||
}
|
||||
}
|
||||
return states;
|
||||
}
|
||||
|
||||
std::set<State> NFA::eClose(State s) {
|
||||
std::set<State> NFA::eClose(State s) const {
|
||||
return {s};
|
||||
}
|
||||
|
||||
|
@ -260,5 +275,87 @@ namespace lxs {
|
|||
computeDistinguishable(reversed, dist);
|
||||
return compress(d, reachable, dist);
|
||||
}
|
||||
|
||||
namespace { // Utility functions for mssc
|
||||
|
||||
std::set<State> getNextState(std::set<State> oldstate, char symbol, const NFA& e) {
|
||||
std::set<State> states;
|
||||
for(auto &state: oldstate) {
|
||||
auto a = e.delta.find(state)->second;
|
||||
auto newStates = a.find(symbol);
|
||||
if(newStates != a.end()) {
|
||||
for(auto &newstate:newStates->second) {
|
||||
auto eclosestates = e.eClose(newstate);
|
||||
for(auto &eclosestate:eclosestates) {
|
||||
states.insert(eclosestate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(states.empty()) states.insert(-1);
|
||||
return states;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
DFA mssc(const NFA& e) {
|
||||
std::map<std::set<State>,std::map<char,std::set<State> > > dfa;
|
||||
|
||||
std::map<char, std::set<State> > trans;
|
||||
for (int c = 0; c < 256; c++) {
|
||||
trans.insert(std::pair<char,std::set<State> >(c,{(unsigned long long) -1}));
|
||||
}
|
||||
dfa.insert(std::pair<std::set<State>,std::map<char,std::set<State> > > ({(unsigned long long) -1},trans));
|
||||
|
||||
std::queue<std::set<State> > tocheck;
|
||||
tocheck.push(e.eClose(e.starting));
|
||||
while(!tocheck.empty()) {
|
||||
auto state = tocheck.front();
|
||||
tocheck.pop();
|
||||
std::map<char, std::set<State> > trans;
|
||||
for (int c = 0; c < 256; c++) {
|
||||
auto nextstate = getNextState(state,c,e);
|
||||
trans.insert(std::pair<char,std::set<State> > (c,nextstate));
|
||||
if(dfa.find(nextstate) == dfa.end()) {
|
||||
tocheck.push(nextstate);
|
||||
}
|
||||
}
|
||||
dfa.insert(std::pair<std::set<State>, std::map<char,std::set<State> > > (state,trans));
|
||||
}
|
||||
std::map<std::set<State>,State> lookup;
|
||||
State numStates = 0;
|
||||
for(auto &state:dfa) {
|
||||
lookup.insert(std::pair<std::set<State>, State> (state.first, numStates++));
|
||||
}
|
||||
DFA result;
|
||||
result.numStates = numStates;
|
||||
result.starting = lookup.find(e.eClose(e.starting))->second;
|
||||
std::map<Priority, State> reversepriority;
|
||||
for(auto &state:dfa) {
|
||||
std::set<Priority> priorityset;
|
||||
State newstate = lookup.find(state.first)->second;
|
||||
std::map<char,State> newtransitions;
|
||||
for(auto &item:state.first) {
|
||||
auto accepting = e.priority.find(item);
|
||||
if(accepting != e.priority.end()) {
|
||||
priorityset.insert(accepting->second);
|
||||
}
|
||||
}
|
||||
if(!priorityset.empty()) {
|
||||
result.accepting.insert(newstate);
|
||||
result.priority.insert(std::pair<State,Priority> (newstate,*priorityset.begin()));
|
||||
reversepriority.insert(std::pair<Priority,State> (*priorityset.begin(),newstate));
|
||||
}
|
||||
for(auto &tranition:state.second) {
|
||||
newtransitions.insert(std::pair<char,State> (tranition.first, lookup.find(tranition.second)->second));
|
||||
}
|
||||
result.delta.insert(std::pair<State,std::map<char,State> > (newstate,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;
|
||||
}
|
||||
|
||||
} //namespace lxs
|
||||
|
|
Loading…
Reference in New Issue