First work

This commit is contained in:
Robin Jadoul 2016-04-24 15:42:29 +02:00
parent c86e40bfd2
commit 3f21513ac5
3 changed files with 233 additions and 0 deletions

View File

@ -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

90
include/Lexesis/re.h Normal file
View File

@ -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

97
src/automata.cpp Normal file
View File

@ -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