First work
This commit is contained in:
parent
c86e40bfd2
commit
3f21513ac5
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
#ifndef AUTOMATA_H
|
||||
#define AUTOMATA_H
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace lxs {
|
||||
typedef unsigned long long State;
|
||||
typedef unsigned long long Priority;
|
||||
|
||||
struct Automaton {
|
||||
State numStates;
|
||||
std::set<State> accepting;
|
||||
std::map<State, Priority> priority;
|
||||
std::map<State, std::string> acceptingToken;
|
||||
State starting;
|
||||
};
|
||||
|
||||
struct DFA : public Automaton {
|
||||
std::map<State, std::map<char, State> > delta;
|
||||
};
|
||||
|
||||
struct NFA : public Automaton {
|
||||
std::map<State, std::map<char, std::set<State> > > delta;
|
||||
virtual std::set<State> eClose(State);
|
||||
};
|
||||
|
||||
struct ENFA : public NFA {
|
||||
std::map<State, std::set<State> > epsilonTransitions;
|
||||
virtual std::set<State> eClose(State);
|
||||
};
|
||||
|
||||
std::string toDot(const DFA& d);
|
||||
std::string toDot(const NFA& n);
|
||||
std::string toDot(const ENFA& e);
|
||||
|
||||
ENFA merge(const std::vector<ENFA>& enfas);
|
||||
DFA mssc(const NFA& e);
|
||||
DFA minimize(const DFA& d);
|
||||
} //namespace lxs
|
||||
|
||||
#endif //AUTOMATA_H
|
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
#ifndef RE_H
|
||||
#define RE_H
|
||||
|
||||
#include "Lexesis/automata.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace lxs {
|
||||
class RE
|
||||
{
|
||||
public:
|
||||
virtual ~RE() {}
|
||||
virtual int toENFA(ENFA& enfa, int attach) = 0;
|
||||
virtual std::string toRe() = 0;
|
||||
};
|
||||
|
||||
class EmptyRE : public RE
|
||||
{
|
||||
public:
|
||||
EmptyRE() {}
|
||||
~EmptyRE() {}
|
||||
virtual int toENFA(ENFA& enfa, int attach);
|
||||
virtual std::string toRe();
|
||||
};
|
||||
|
||||
class EpsilonRE : public RE
|
||||
{
|
||||
public:
|
||||
EpsilonRE() {}
|
||||
~EpsilonRE() {}
|
||||
virtual int toENFA(ENFA& enfa, int attach);
|
||||
virtual std::string toRe();
|
||||
};
|
||||
|
||||
class SingleRE : public RE
|
||||
{
|
||||
public:
|
||||
SingleRE(char c) : c(c) {}
|
||||
~SingleRE() {}
|
||||
virtual int toENFA(ENFA& enfa, int attach);
|
||||
virtual std::string toRe();
|
||||
|
||||
char c;
|
||||
};
|
||||
|
||||
class ConcatRE : public RE
|
||||
{
|
||||
public:
|
||||
ConcatRE(RE* e, RE* f) : e(e), f(f) {}
|
||||
~ConcatRE() {delete e; delete f;}
|
||||
virtual int toENFA(ENFA& enfa, int attach);
|
||||
virtual std::string toRe();
|
||||
|
||||
RE* e, *f;
|
||||
};
|
||||
|
||||
class StarRE : public RE
|
||||
{
|
||||
public:
|
||||
StarRE(RE* e) : e(e) {}
|
||||
~StarRE() {delete e;}
|
||||
virtual int toENFA(ENFA& enfa, int attach);
|
||||
virtual std::string toRe();
|
||||
|
||||
RE* e;
|
||||
};
|
||||
|
||||
class PlusRE : public RE
|
||||
{
|
||||
public:
|
||||
PlusRE(RE* e, RE* f) : e(e), f(f) {}
|
||||
~PlusRE() {delete e; delete f;}
|
||||
virtual int toENFA(ENFA& enfa, int attach);
|
||||
virtual std::string toRe();
|
||||
|
||||
RE* e, *f;
|
||||
};
|
||||
|
||||
RE* parseRE(std::string& input);
|
||||
|
||||
class SyntaxError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
SyntaxError(const char* w) : std::runtime_error(w) {}
|
||||
};
|
||||
|
||||
} //namespace lxs
|
||||
|
||||
#endif //RE_H
|
|
@ -0,0 +1,97 @@
|
|||
#include "automata.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace lxs {
|
||||
std::string toDot(const DFA& d)
|
||||
{
|
||||
std::string s = "digraph {\nrankdir=LR\nin [shape=point style=invis]";
|
||||
|
||||
for (State state = 0; state < d.numStates; state++)
|
||||
{
|
||||
s += std::to_string(state) + " [label=\"" + std::to_string(state) + "\"";
|
||||
if (state == d.starting)
|
||||
s += " color=yellow";
|
||||
if (d.accepting.count(state) > 0)
|
||||
s += " color=green shape=doublecircle";
|
||||
s += "]\n";
|
||||
}
|
||||
|
||||
for (const auto& tmp : d.delta)
|
||||
{
|
||||
const auto& from = tmp.first;
|
||||
for (const auto& trans : tmp.second)
|
||||
{
|
||||
s += std::to_string(from) + " -> " + std::to_string(trans.second) + " [label=\"" + trans.first + "\"]\n";
|
||||
}
|
||||
}
|
||||
|
||||
s += "in -> " + std::to_string(d.starting) + "\n}\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string toDot(const NFA& n)
|
||||
{
|
||||
std::string s = "digraph {\nrankdir=LR\nin [shape=point style=invis]\n";
|
||||
|
||||
for (State state = 0; state < n.numStates; state++)
|
||||
{
|
||||
s += std::to_string(state) + " [label=\"" + std::to_string(state) + "\"";
|
||||
if (state == n.starting)
|
||||
s += " color=yellow";
|
||||
if (n.accepting.count(state) > 0)
|
||||
s += " color=green shape=doublecircle";
|
||||
s += "]\n";
|
||||
}
|
||||
|
||||
for (const auto& tmp : n.delta)
|
||||
{
|
||||
const auto& from = tmp.first;
|
||||
for (const auto& trans : tmp.second)
|
||||
{
|
||||
for (const auto& to : trans.second)
|
||||
s += std::to_string(from) + " -> " + std::to_string(to) + " [label=\"" + trans.first + "\"]\n";
|
||||
}
|
||||
}
|
||||
|
||||
s += "in -> " + std::to_string(n.starting) + "\n}\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string toDot(const ENFA& e)
|
||||
{
|
||||
std::string s = "digraph {\nrankdir=LR\nin [shape=point style=invis]\n";
|
||||
|
||||
for (State state = 0; state < e.numStates; state++)
|
||||
{
|
||||
s += std::to_string(state) + " [label=\"" + std::to_string(state) + "\"";
|
||||
if (state == e.starting)
|
||||
s += " color=yellow";
|
||||
if (e.accepting.count(state) > 0)
|
||||
s += " color=green shape=doublecircle";
|
||||
s += "]\n";
|
||||
}
|
||||
|
||||
for (const auto& tmp : e.delta)
|
||||
{
|
||||
const auto& from = tmp.first;
|
||||
for (const auto& trans : tmp.second)
|
||||
{
|
||||
for (const auto& to : trans.second)
|
||||
s += std::to_string(from) + " -> " + std::to_string(to) + " [label=\"" + trans.first + "\"]\n";
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& etrans : e.epsilonTransitions)
|
||||
{
|
||||
for (const auto& dest : etrans.second)
|
||||
s += std::to_string(etrans.first) + " -> " + std::to_string(dest) + " [label=\"ε\"]\n";
|
||||
}
|
||||
|
||||
s += "in -> " + std::to_string(e.starting) + "\n}\n";
|
||||
return s;
|
||||
}
|
||||
} //namespace lxs
|
Loading…
Reference in New Issue