Skip to content
Snippets Groups Projects
Commit 45297d73 authored by Jan Trávníček's avatar Jan Trávníček
Browse files

allow epsilon as input or output in unknown trans

parent 400b18ce
No related branches found
No related tags found
No related merge requests found
......@@ -57,7 +57,7 @@ void AutomatonFromXMLParser::parseStates(std::list<sax::Token> &input, UnknownAu
void AutomatonFromXMLParser::parseInputAlphabet(std::list<sax::Token> &input, UnknownAutomaton& automaton) {
popToken(input, sax::Token::START_ELEMENT, "inputAlphabet");
while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
automaton.addInputSymbol(parseSymbol(input, "symbol"));
automaton.addInputSymbol(parseSymbol(input));
}
popToken(input, sax::Token::END_ELEMENT, "inputAlphabet");
}
......@@ -81,7 +81,7 @@ void AutomatonFromXMLParser::parseFinalStates(std::list<sax::Token> &input, Unkn
void AutomatonFromXMLParser::parseStackAlphabet(std::list<sax::Token> &input, UnknownAutomaton& automaton) {
popToken(input, sax::Token::START_ELEMENT, "stackAlphabet");
while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
automaton.addStackSymbol(parseSymbol(input, "symbol"));
automaton.addStackSymbol(parseSymbol(input));
}
popToken(input, sax::Token::END_ELEMENT, "stackAlphabet");
}
......@@ -89,7 +89,7 @@ void AutomatonFromXMLParser::parseStackAlphabet(std::list<sax::Token> &input, Un
void AutomatonFromXMLParser::parseStartSymbols(std::list<sax::Token> &input, UnknownAutomaton& automaton) {
popToken(input, sax::Token::START_ELEMENT, "startSymbols");
while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
automaton.addInitialSymbol(parseSymbol(input, "symbol"));
automaton.addInitialSymbol(parseSymbol(input));
}
popToken(input, sax::Token::END_ELEMENT, "startSymbols");
}
......@@ -97,14 +97,14 @@ void AutomatonFromXMLParser::parseStartSymbols(std::list<sax::Token> &input, Unk
void AutomatonFromXMLParser::parseTapeAlphabet(std::list<sax::Token>& input, UnknownAutomaton& automaton) {
popToken(input, sax::Token::START_ELEMENT, "tapeAlphabet");
while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
automaton.addTapeSymbol(parseSymbol(input, "symbol"));
automaton.addTapeSymbol(parseSymbol(input));
}
popToken(input, sax::Token::END_ELEMENT, "tapeAlphabet");
}
 
void AutomatonFromXMLParser::parseBlankSymbol(std::list<sax::Token>& input, UnknownAutomaton& automaton) {
popToken(input, sax::Token::START_ELEMENT, "blankSymbol");
automaton.setBlankSymbol(parseSymbol(input, "symbol"));
automaton.setBlankSymbol(parseSymbol(input));
popToken(input, sax::Token::END_ELEMENT, "blankSymbol");
}
 
......@@ -119,7 +119,7 @@ void AutomatonFromXMLParser::parseTransitions(std::list<sax::Token> &input, Unkn
void AutomatonFromXMLParser::parsePop(std::list<sax::Token>& input, UnknownTransition& transition) {
popToken(input, sax::Token::START_ELEMENT, "pop");
while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
transition.addPop(parseSymbol(input, "symbol"));
transition.addPop(parseSymbol(input));
}
popToken(input, sax::Token::END_ELEMENT, "pop");
}
......@@ -127,7 +127,7 @@ void AutomatonFromXMLParser::parsePop(std::list<sax::Token>& input, UnknownTrans
void AutomatonFromXMLParser::parsePush(std::list<sax::Token>& input, UnknownTransition& transition) {
popToken(input, sax::Token::START_ELEMENT, "push");
while (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
transition.addPush(parseSymbol(input, "symbol"));
transition.addPush(parseSymbol(input));
}
popToken(input, sax::Token::END_ELEMENT, "push");
}
......@@ -140,23 +140,42 @@ State AutomatonFromXMLParser::parseState(std::list<sax::Token> &input, std::stri
return state;
}
 
alphabet::Symbol AutomatonFromXMLParser::parseSymbol(std::list<sax::Token>& input, std::string tagName) {
popToken(input, sax::Token::START_ELEMENT, tagName);
alphabet::Symbol AutomatonFromXMLParser::parseSymbol(std::list<sax::Token>& input) {
alphabet::Symbol result("");
if (isTokenType(input, sax::Token::CHARACTER)) {
if (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
popToken(input, sax::Token::START_ELEMENT, "symbol");
result = alphabet::Symbol(popTokenData(input, sax::Token::CHARACTER));
popToken(input, sax::Token::END_ELEMENT, "symbol");
} else if (isToken(input, sax::Token::START_ELEMENT, "blank")) {
result = alphabet::Blank();
input.pop_front();
popToken(input, sax::Token::END_ELEMENT,"blank");
} else {
throw sax::ParserException(sax::Token("", sax::Token::CHARACTER), input.front());
}
return result;
}
std::variant<string::Epsilon, alphabet::Symbol> AutomatonFromXMLParser::parseInput(std::list<sax::Token>& input, std::string tagName) {
popToken(input, sax::Token::START_ELEMENT, tagName);
std::variant<string::Epsilon, alphabet::Symbol> result;
if (isToken(input, sax::Token::START_ELEMENT, "symbol")) {
popToken(input, sax::Token::START_ELEMENT, "symbol");
result.set<alphabet::Symbol>(alphabet::Symbol(popTokenData(input, sax::Token::CHARACTER)));
popToken(input, sax::Token::END_ELEMENT, "symbol");
} else if(isToken(input, sax::Token::START_ELEMENT, "epsilon")) {
result = alphabet::Symbol(""); //TODO predelat na opravdovy epsilon
result.set<string::Epsilon>(string::Epsilon());
input.pop_front();
popToken(input, sax::Token::END_ELEMENT,"epsilon");
popToken(input, sax::Token::END_ELEMENT, "epsilon");
} else if (isToken(input, sax::Token::START_ELEMENT, "blank")) {
result = alphabet::Blank();
result.set<alphabet::Symbol>(alphabet::Blank());
input.pop_front();
popToken(input, sax::Token::END_ELEMENT,"blank");
} else {
throw sax::ParserException(sax::Token("", sax::Token::CHARACTER), input.front());
}
popToken(input, sax::Token::END_ELEMENT, tagName);
return result;
}
......@@ -190,7 +209,7 @@ UnknownTransition AutomatonFromXMLParser::parseTransition(std::list<sax::Token>&
if (isToken(input, sax::Token::START_ELEMENT, "from")) {
transition.setFrom(parseState(input, "from"));
} else if (isToken(input, sax::Token::START_ELEMENT, "input")) {
transition.setInput(parseSymbol(input, "input"));
transition.setInput(parseInput(input, "input"));
} else if (isToken(input, sax::Token::START_ELEMENT, "to")) {
transition.setTo(parseState(input, "to"));
} else if (isToken(input, sax::Token::START_ELEMENT, "pop")) {
......@@ -198,7 +217,7 @@ UnknownTransition AutomatonFromXMLParser::parseTransition(std::list<sax::Token>&
} else if (isToken(input, sax::Token::START_ELEMENT, "push")) {
parsePush(input, transition);
} else if (isToken(input, sax::Token::START_ELEMENT, "output")) {
transition.setOutput(parseSymbol(input, "output"));
transition.setOutput(parseInput(input, "output"));
} else if (isToken(input, sax::Token::START_ELEMENT, "shift")) {
transition.setShift(parseShift(input));
} else {
......
......@@ -13,7 +13,9 @@
 
#include <list>
#include <set>
#include "../std/variant.hpp"
#include "../sax/Token.h"
#include "../string/Epsilon.h"
 
namespace automaton {
 
......@@ -37,7 +39,8 @@ protected:
 
UnknownTransition parseTransition(std::list<sax::Token>& input);
State parseState(std::list<sax::Token> &input, std::string tagName);
alphabet::Symbol parseSymbol(std::list<sax::Token> &input, std::string tagName);
std::variant<string::Epsilon, alphabet::Symbol> parseInput(std::list<sax::Token> &input, std::string tagName);
alphabet::Symbol parseSymbol(std::list<sax::Token> &input);
Shift parseShift(std::list<sax::Token> &input);
 
public:
......
......@@ -43,7 +43,7 @@ void AutomatonToXMLComposer::printUnknownTransitions(std::list<sax::Token>& out,
}
 
if(transition.hasInput()) {
printSymbol(out, transition.getInput(), "input");
printInput(out, transition.getInput(), "input");
}
if(transition.hasTo()) {
......@@ -58,7 +58,7 @@ void AutomatonToXMLComposer::printUnknownTransitions(std::list<sax::Token>& out,
}
 
if (transition.hasOutput()) {
printSymbol(out, transition.getOutput(), "output");
printInput(out, transition.getOutput(), "output");
}
 
if (transition.getShift() != Shift::NOT_SET) {
......@@ -77,6 +77,17 @@ void AutomatonToXMLComposer::printState(std::list<sax::Token>& out, const State&
out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
}
 
void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::variant<string::Epsilon, alphabet::Symbol>& symbol, std::string tagName) {
out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
if(symbol.is<string::Epsilon>()) {
out.push_back(sax::Token("epsilon", sax::Token::START_ELEMENT));
out.push_back(sax::Token("epsilon", sax::Token::END_ELEMENT));
} else {
out.push_back(sax::Token(symbol.get<alphabet::Symbol>().getSymbol(), sax::Token::CHARACTER));
}
out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT));
}
void AutomatonToXMLComposer::printSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) {
out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT));
out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER));
......
......@@ -27,6 +27,7 @@ protected:
 
static void printState(std::list<sax::Token>&, const State& state, std::string tagName);
static void printSymbol(std::list<sax::Token>&, const alphabet::Symbol& symbol, std::string tagName);
static void printInput(std::list<sax::Token>&, const std::variant<string::Epsilon, alphabet::Symbol>&, std::string);
static void printShift(std::list<sax::Token>&, const Shift& shift, std::string tagName);
 
public:
......
......@@ -14,8 +14,8 @@ UnknownTransition::UnknownTransition() : from(NULL), to(NULL), input(NULL), outp
 
}
 
UnknownTransition::UnknownTransition(const State& from, const State& to, const std::vector<alphabet::Symbol>& pop, const std::vector<alphabet::Symbol>& push, const alphabet::Symbol& input, const alphabet::Symbol& output, Shift shift) :
from(new State(from)), to(new State(to)), pop(pop), push(push), input(new alphabet::Symbol(input)), output(new alphabet::Symbol(output)), shift(shift) {
UnknownTransition::UnknownTransition(const State& from, const State& to, const std::vector<alphabet::Symbol>& pop, const std::vector<alphabet::Symbol>& push, const std::variant<string::Epsilon, alphabet::Symbol>& input, const std::variant<string::Epsilon, alphabet::Symbol>& output, Shift shift) :
from(new State(from)), to(new State(to)), pop(pop), push(push), input(new std::variant<string::Epsilon, alphabet::Symbol>(input)), output(new std::variant<string::Epsilon, alphabet::Symbol>(output)), shift(shift) {
 
}
 
......@@ -83,9 +83,9 @@ void UnknownTransition::addPush(const alphabet::Symbol& symbol) {
push.push_back(symbol);
}
 
void UnknownTransition::setOutput(const alphabet::Symbol& symbol) {
void UnknownTransition::setOutput(const std::variant<string::Epsilon, alphabet::Symbol>& symbol) {
delete output;
output = new alphabet::Symbol(symbol);
output = new std::variant<string::Epsilon, alphabet::Symbol>(symbol);
}
 
bool UnknownTransition::hasOutput() const {
......@@ -97,13 +97,13 @@ void UnknownTransition::clearOutput() {
output = NULL;
}
 
const alphabet::Symbol& UnknownTransition::getOutput() const {
const std::variant<string::Epsilon, alphabet::Symbol>& UnknownTransition::getOutput() const {
return *output;
}
 
void UnknownTransition::setInput(const alphabet::Symbol& symbol) {
void UnknownTransition::setInput(const std::variant<string::Epsilon, alphabet::Symbol>& symbol) {
delete input;
input = new alphabet::Symbol(symbol);
input = new std::variant<string::Epsilon, alphabet::Symbol>(symbol);
}
 
bool UnknownTransition::hasInput() const {
......@@ -115,7 +115,7 @@ void UnknownTransition::clearInput() {
input = NULL;
}
 
const alphabet::Symbol& UnknownTransition::getInput() const {
const std::variant<string::Epsilon, alphabet::Symbol>& UnknownTransition::getInput() const {
return *input;
}
 
......@@ -168,12 +168,15 @@ bool UnknownTransition::operator !=(const UnknownTransition& other) const {
}
 
std::ostream& operator<<(std::ostream& out, const UnknownTransition& transition) {
out << "(UnknownTransition"
<< " from = " << ((transition.from == NULL) ? (std::string) "NULL" : *transition.from)
<< " input = " << ((transition.input == NULL) ? (std::string) "NULL" : *transition.input)
<< " to = " << ((transition.to == NULL) ? (std::string) "NULL" : *transition.to)
<< " output = " << ((transition.output == NULL) ? (std::string) "NULL" : *transition.output)
<< " pop = " << transition.pop
out << "(UnknownTransition" << " from = ";
if(transition.from == NULL) out << "NULL"; else out << *transition.from;
out << " input = ";
if(transition.input == NULL) out << "NULL"; else out << *transition.input;
out << " to = ";
if(transition.to == NULL) out << "NULL"; else out << *transition.to;
out << " output = ";
if(transition.output == NULL) out << "NULL"; else out << *transition.output;
out << " pop = " << transition.pop
<< " push = " << transition.push
<< " shift = " << SHIFT_NAMES[transition.shift]
<< ")";
......
......@@ -13,6 +13,8 @@
#include "State.h"
#include "../alphabet/Symbol.h"
#include "Shift.h"
#include "../std/variant.hpp"
#include "../string/Epsilon.h"
 
namespace automaton {
 
......@@ -27,15 +29,15 @@ protected:
std::vector<alphabet::Symbol> pop;
std::vector<alphabet::Symbol> push;
 
alphabet::Symbol* input;
alphabet::Symbol* output;
std::variant<string::Epsilon, alphabet::Symbol>* input;
std::variant<string::Epsilon, alphabet::Symbol>* output;
 
Shift shift;
 
public:
UnknownTransition();
UnknownTransition(const State& from, const State& to, const std::vector<alphabet::Symbol>& pop, const std::vector<alphabet::Symbol>& push, const alphabet::Symbol& input, const alphabet::Symbol& output, Shift shift);
UnknownTransition(const State& from, const State& to, const std::vector<alphabet::Symbol>& pop, const std::vector<alphabet::Symbol>& push, const std::variant<string::Epsilon, alphabet::Symbol>& input, const std::variant<string::Epsilon, alphabet::Symbol>& output, Shift shift);
~UnknownTransition();
 
/**
......@@ -113,13 +115,13 @@ public:
/**
* @return the output symbol of the transition
*/
const alphabet::Symbol& getInput() const;
const std::variant<string::Epsilon, alphabet::Symbol>& getInput() const;
 
/**
* Sets the output Symbol of the transition.
* @param symbol Symbol to set
*/
void setInput(const alphabet::Symbol& symbol);
void setInput(const std::variant<string::Epsilon, alphabet::Symbol>& symbol);
 
/**
* @return true if the input symbol is set
......@@ -134,13 +136,13 @@ public:
/**
* @return the output symbol of the transition
*/
const alphabet::Symbol& getOutput() const;
const std::variant<string::Epsilon, alphabet::Symbol>& getOutput() const;
 
/**
* Sets the output Symbol of the transition.
* @param symbol Symbol to set
*/
void setOutput(const alphabet::Symbol& symbol);
void setOutput(const std::variant<string::Epsilon, alphabet::Symbol>& symbol);
 
/**
* @return true if the output symbol is set
......
......@@ -70,6 +70,14 @@ struct variant_helper<F, Ts...> {
return variant_helper<Ts...>::compareEq(this_t, this_v, other_t, other_v);
}
 
inline static void print(ostream& out, const size_t id, const void* data) {
if (id == typeid(F).hash_code())
out << *reinterpret_cast<const F*>(data);
else
variant_helper<Ts...>::print(out, id, data);
}
inline static bool compareLess(size_t this_t, const void * this_v, size_t other_t, const void * other_v)
{
if (this_t == typeid(F).hash_code() && other_t != typeid(F).hash_code()) return true;
......@@ -88,6 +96,7 @@ inline static void destroy(size_t id, void * data) { }
inline static bool move(size_t old_t, void * old_v, void * new_v) { return false; }
inline static void copy(size_t old_t, const void * old_v, void * new_v) { }
inline static bool compareEq(size_t this_t, const void * this_v, size_t other_t, const void * other_v) { return true; }
inline static void print(ostream& out, const size_t id, const void* data) {}
inline static bool compareLess(size_t this_t, const void * this_v, size_t other_t, const void * other_v) { return false; }
};
 
......@@ -137,11 +146,31 @@ public:
return helper_t::compareEq(type_id, &data, other.type_id, &other.data);
}
 
bool operator!= (const variant<F, Ts...>& other) const
{
return !(*this == other);
}
bool operator< (const variant<F, Ts...>& other) const
{
return helper_t::compareLess(type_id, &data, other.type_id, &other.data);
}
 
bool operator> (const variant<F, Ts...>& other) const
{
return other < *this;
}
bool operator<= (const variant<F, Ts...>& other) const
{
return !(*this > other);
}
bool operator>= (const variant<F, Ts...>& other) const
{
return !(*this < other);
}
template<typename T>
bool is() const {
return (type_id == typeid(T).hash_code());
......@@ -192,6 +221,11 @@ public:
~variant() {
helper_t::destroy(type_id, &data);
}
friend std::ostream& operator <<(std::ostream& out, const variant<F, Ts...>& obj) {
helper_t::print(out, obj.type_id, &obj.data);
return out;
}
};
 
} /* namespace std */
......
......@@ -25,6 +25,11 @@ bool Epsilon::operator!=(const Epsilon& other) const {
return false;
}
 
std::ostream& operator<<(std::ostream& out, const Epsilon& eps) {
out << (const String&) eps;
return out;
}
Epsilon Epsilon::EPSILON = Epsilon();
 
} /* namespace string */
......@@ -32,6 +32,8 @@ public:
bool operator==(const Epsilon& other) const;
bool operator!=(const Epsilon& other) const;
friend std::ostream& operator<<(std::ostream& out, const Epsilon& eps);
static Epsilon EPSILON;
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment