diff --git a/alib2/src/automaton/Automaton.cpp b/alib2/src/automaton/Automaton.cpp index d8dfa9540a9ac6dfbd5eec7eab9250ddf29bb380..cf7fe0bf13c83bad413daf92ef2cb0eaf9146cd0 100644 --- a/alib2/src/automaton/Automaton.cpp +++ b/alib2/src/automaton/Automaton.cpp @@ -13,5 +13,50 @@ Automaton::~Automaton() { } +bool Automaton::operator!=(const Automaton& other) const { + return !(*this == other); +} + +bool Automaton::operator==(const UnknownAutomaton& other) const { + return false; +} + +bool Automaton::operator==(const DFA& other) const { + return false; +} + +bool Automaton::operator==(const NFA& other) const { + return false; +} + +bool Automaton::operator==(const EpsilonNFA& other) const{ + return false; +} + +bool Automaton::operator==(const CompactNFA& other) const{ + return false; +} + +bool Automaton::operator==(const ExtendedNFA& other) const { + return false; +} + +bool Automaton::operator==(const PDA& other) const { + return false; +} + +bool Automaton::operator==(const OneTapeDTM& other) const { + return false; +} + +bool Automaton::operator==(const Automaton& other) const { + return false; +} + +std::ostream& operator<<(std::ostream& os, const Automaton& automaton) { + automaton >> os; + return os; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/Automaton.h b/alib2/src/automaton/Automaton.h index 5c6029a6e16db361487d2644bab45c605a1041bc..13a1acf614563a25c40681d7fb7bd1902a40f435 100644 --- a/alib2/src/automaton/Automaton.h +++ b/alib2/src/automaton/Automaton.h @@ -8,14 +8,49 @@ #ifndef AUTOMATON_H_ #define AUTOMATON_H_ +#include "../std/visitor.hpp" + namespace automaton { +class UnknownAutomaton; +class DFA; +class NFA; +class EpsilonNFA; +class CompactNFA; +class ExtendedNFA; +class PDA; +class OneTapeDTM; + /** * Abstract base class for all automata. */ -class Automaton { +class Automaton : virtual public std::elementBase<std::visitor<UnknownAutomaton, DFA, NFA, EpsilonNFA, CompactNFA, ExtendedNFA, PDA, OneTapeDTM> > { public: virtual ~Automaton() noexcept; + + virtual bool operator!=(const Automaton& other) const; + + virtual bool operator==(const UnknownAutomaton& other) const; + + virtual bool operator==(const DFA& other) const; + + virtual bool operator==(const NFA& other) const; + + virtual bool operator==(const EpsilonNFA& other) const; + + virtual bool operator==(const CompactNFA& other) const; + + virtual bool operator==(const ExtendedNFA& other) const; + + virtual bool operator==(const PDA& other) const; + + virtual bool operator==(const OneTapeDTM& other) const; + + virtual bool operator==(const Automaton& other) const = 0; + + friend std::ostream& operator<<(std::ostream& os, const Automaton& automaton); + + virtual void operator>>(std::ostream&) const = 0; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/AutomatonToXMLComposer.cpp b/alib2/src/automaton/AutomatonToXMLComposer.cpp index 34ed86507e664658bbe4ddd445d730a8bbbadd27..be77fd416e7354f2ce642862719518d7727f145d 100644 --- a/alib2/src/automaton/AutomatonToXMLComposer.cpp +++ b/alib2/src/automaton/AutomatonToXMLComposer.cpp @@ -6,6 +6,7 @@ */ #include "AutomatonToXMLComposer.h" +#include "../alphabet/Blank.h" namespace automaton { @@ -25,6 +26,53 @@ void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std: out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); } +void AutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& symbols, std::string tagName) { + out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); + for (auto& symbol : symbols) { + printSymbol(out, symbol, "symbol"); + } + out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); +} + +void AutomatonToXMLComposer::printShift(std::list<sax::Token>& out, const Shift shift, std::string tagName) { + out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); + out.push_back(sax::Token(SHIFT_NAMES [shift], sax::Token::CHARACTER)); + out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); +} + +void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const UnknownAutomaton& automaton) { + out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT)); + for (auto& transition : automaton.getTransitions()) { + out.push_back(sax::Token("transition", sax::Token::START_ELEMENT)); + + if (transition.hasFrom()) + printState(out, transition.getFrom(), "from"); + + if(transition.hasInput()) + printInput(out, transition.getInput(), "input"); + + if(transition.hasTo()) + printState(out, transition.getTo(), "to"); + + if (transition.getPop().size() > 0) + printSymbols(out, transition.getPop(), "pop"); + + if (transition.getPush().size() > 0) + printSymbols(out, transition.getPush(), "push"); + + if (transition.hasOutput()) + printInput(out, transition.getOutput(), "output"); + + if (transition.getShift() != Shift::NOT_SET) + printShift(out, transition.getShift(), "shift"); + + out.push_back(sax::Token("transition", sax::Token::END_ELEMENT)); + } + + out.push_back(sax::Token("transitions", sax::Token::END_ELEMENT)); +} + + void AutomatonToXMLComposer::printTransitions(std::list<sax::Token>& out, const DFA& automaton) { out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT)); for(auto& transition : automaton.getTransitions()) { @@ -91,6 +139,9 @@ void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::v 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 if(symbol.get<alphabet::Symbol>() == alphabet::Blank::BLANK) { + out.push_back(sax::Token("blank", sax::Token::START_ELEMENT)); + out.push_back(sax::Token("blank", sax::Token::END_ELEMENT)); } else { out.push_back(sax::Token(symbol.get<alphabet::Symbol>().getSymbol(), sax::Token::CHARACTER)); } @@ -99,17 +150,47 @@ void AutomatonToXMLComposer::printInput(std::list<sax::Token>& out, const std::v 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)); + if(symbol == alphabet::Blank::BLANK) { + out.push_back(sax::Token("blank", sax::Token::START_ELEMENT)); + out.push_back(sax::Token("blank", sax::Token::START_ELEMENT)); + } else { + out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER)); + } out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); } -std::list<sax::Token> AutomatonToXMLComposer::compose(const Automaton* automaton) { - std::list<sax::Token> out; - return out; -} - std::list<sax::Token> AutomatonToXMLComposer::compose(const UnknownAutomaton& automaton) { std::list<sax::Token> out; + out.push_back(sax::Token("automaton", sax::Token::START_ELEMENT)); + + if (automaton.getStates().size() > 0) + printStates(out, automaton.getStates(), "states"); + + if (automaton.getInputSymbols().size() > 0) + printSymbols(out, automaton.getInputSymbols(), "inputAlphabet"); + + if (automaton.getTapeSymbols().size() > 0) + printSymbols(out, automaton.getTapeSymbols(), "tapeAlphabet"); + + if (automaton.getStackSymbols().size() > 0) + printSymbols(out, automaton.getStackSymbols(), "stackAlphabet"); + + if (automaton.hasBlankSymbol()) + printSymbol(out, automaton.getBlankSymbol(), "blankSymbol"); + + if (automaton.getInitialSymbols().size() > 0) + printSymbols(out, automaton.getInitialSymbols(), "startSymbols"); + + if (automaton.getInitialStates().size() > 0) + printStates(out, automaton.getInitialStates(), "initialStates"); + + if (automaton.getFinalStates().size() > 0) + printStates(out, automaton.getFinalStates(), "finalStates"); + + if (automaton.getTransitions().size() > 0) + printTransitions(out, automaton); + + out.push_back(sax::Token("automaton", sax::Token::END_ELEMENT)); return out; } @@ -155,5 +236,64 @@ std::list<sax::Token> AutomatonToXMLComposer::compose(const EpsilonNFA& automato return out; } +std::list<sax::Token> AutomatonToXMLComposer::compose(const ExtendedNFA& automaton) { + std::list<sax::Token> out; + return out; +} + +std::list<sax::Token> AutomatonToXMLComposer::compose(const CompactNFA& automaton) { + std::list<sax::Token> out; + return out; +} + +std::list<sax::Token> AutomatonToXMLComposer::compose(const PDA& automaton) { + std::list<sax::Token> out; + return out; +} + +std::list<sax::Token> AutomatonToXMLComposer::compose(const OneTapeDTM& automaton) { + std::list<sax::Token> out; + return out; +} + + +std::list<sax::Token> AutomatonToXMLComposer::compose(const Automaton& automaton) { + std::list<sax::Token> out; + automaton.Accept((void*) &out, *this); + return out; +} + +void AutomatonToXMLComposer::Visit(void* data, const UnknownAutomaton& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton); +} + +void AutomatonToXMLComposer::Visit(void* data, const EpsilonNFA& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton); +} + +void AutomatonToXMLComposer::Visit(void* data, const NFA& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton); +} + +void AutomatonToXMLComposer::Visit(void* data, const DFA& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton); +} + +void AutomatonToXMLComposer::Visit(void* data, const ExtendedNFA& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton); +} + +void AutomatonToXMLComposer::Visit(void* data, const CompactNFA& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton);; +} + +void AutomatonToXMLComposer::Visit(void* data, const PDA& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton);; +} + +void AutomatonToXMLComposer::Visit(void* data, const OneTapeDTM& automaton) { + *((std::list<sax::Token>*) data) = this->compose(automaton);; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/AutomatonToXMLComposer.h b/alib2/src/automaton/AutomatonToXMLComposer.h index 1a39dc731c8467dbed71cc3c4902499bd162da3a..3daa380ce10428af8011442308e2534d6bd6a1f0 100644 --- a/alib2/src/automaton/AutomatonToXMLComposer.h +++ b/alib2/src/automaton/AutomatonToXMLComposer.h @@ -21,11 +21,23 @@ namespace automaton { /** * This class contains methods to print XML representation of automata to the output stream. */ -class AutomatonToXMLComposer { +class AutomatonToXMLComposer : public Automaton::visitor_type { + void Visit(void*, const UnknownAutomaton& automaton); + void Visit(void*, const EpsilonNFA& automaton); + void Visit(void*, const NFA& automaton); + void Visit(void*, const DFA& automaton); + void Visit(void*, const ExtendedNFA& automaton); + void Visit(void*, const CompactNFA& automaton); + void Visit(void*, const PDA& automaton); + void Visit(void*, const OneTapeDTM& automaton); + protected: static void printStates(std::list<sax::Token>&, const std::set<State>& states, std::string tagName); static void printSymbols(std::list<sax::Token>&, const std::set<alphabet::Symbol>& symbols, std::string tagName); - + static void printSymbols(std::list<sax::Token>&, const std::vector<alphabet::Symbol>& symbols, std::string tagName); + static void printShift(std::list<sax::Token>&, const Shift shift, std::string tagName); + + static void printTransitions(std::list<sax::Token>&, const UnknownAutomaton& automaton); static void printTransitions(std::list<sax::Token>&, const EpsilonNFA& automaton); static void printTransitions(std::list<sax::Token>&, const NFA& automaton); static void printTransitions(std::list<sax::Token>&, const DFA& automaton); @@ -41,12 +53,16 @@ public: * @param automaton automaton to print * @return list of xml tokens representing the automaton */ - std::list<sax::Token> compose(const Automaton* automaton); + std::list<sax::Token> compose(const Automaton& automaton); std::list<sax::Token> compose(const UnknownAutomaton& automaton); std::list<sax::Token> compose(const DFA& automaton); std::list<sax::Token> compose(const NFA& automaton); std::list<sax::Token> compose(const EpsilonNFA& automaton); + std::list<sax::Token> compose(const ExtendedNFA& automaton); + std::list<sax::Token> compose(const CompactNFA& automaton); + std::list<sax::Token> compose(const PDA& automaton); + std::list<sax::Token> compose(const OneTapeDTM& automaton); }; } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/CompactNFA.cpp b/alib2/src/automaton/FSM/CompactNFA.cpp index 0e2b2ed2d95dab60312ccf656daa62d371cfd138..e8f8585b906d9164283db392ea6ff3530abd621f 100644 --- a/alib2/src/automaton/FSM/CompactNFA.cpp +++ b/alib2/src/automaton/FSM/CompactNFA.cpp @@ -6,6 +6,7 @@ */ #include "CompactNFA.h" +#include "../../std/map.hpp" #include "../AutomatonException.h" #include <ostream> #include <algorithm> @@ -96,4 +97,22 @@ std::map<std::pair<State, string::String>, std::set<State>> CompactNFA::getTrans return transitionsToState; } +bool CompactNFA::operator==(const Automaton& other) const { + return other == *this; +} + +bool CompactNFA::operator==(const CompactNFA& other) const { + return states == other.states && inputAlphabet == other.inputAlphabet && initialStates == other.initialStates && finalStates == other.finalStates && transitions == other.transitions; +} + +void CompactNFA::operator>>(std::ostream& out) const { + out << "(CompactNFA" + << "states = " << states + << "inputAlphabet = " << inputAlphabet + << "initialStates = " << initialStates + << "finalStates = " << finalStates + << "transitions = " << transitions + << ")"; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/CompactNFA.h b/alib2/src/automaton/FSM/CompactNFA.h index 7e1b7e90534748ee3ed37369f71b81f3993b81b0..0779c6783ea104522039263f9d0f2bbd68a08e94 100644 --- a/alib2/src/automaton/FSM/CompactNFA.h +++ b/alib2/src/automaton/FSM/CompactNFA.h @@ -20,7 +20,7 @@ namespace automaton { * Represents Finite Automaton. * Can store nondeterministic finite automaton without epsilon transitions. */ -class CompactNFA : public Automaton, public MultiInitialStates, public InputAlphabet { +class CompactNFA : public Automaton, public std::element<CompactNFA, Automaton::visitor_type>, public MultiInitialStates, public InputAlphabet { protected: std::map<std::pair<State, string::String>, std::set<State> > transitions; public: @@ -66,7 +66,11 @@ public: */ std::map<std::pair<State, string::String>, std::set<State>> getTransitionsToState(const State& from) const; - friend std::ostream& operator<<(std::ostream& out, const CompactNFA& automaton); + virtual bool operator==(const Automaton& other) const; + + virtual bool operator==(const CompactNFA& other) const; + + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/DFA.cpp b/alib2/src/automaton/FSM/DFA.cpp index a96cbe28dfa8720f19dd2b2b267938eef3df897f..5b86e94dd594de4bdc4b5fc3395f77fc20e5a02a 100644 --- a/alib2/src/automaton/FSM/DFA.cpp +++ b/alib2/src/automaton/FSM/DFA.cpp @@ -6,6 +6,8 @@ */ #include "DFA.h" +#include "../../std/set.hpp" +#include "../../std/map.hpp" #include "../AutomatonException.h" #include <ostream> @@ -117,12 +119,26 @@ std::map<std::pair<State, alphabet::Symbol>, State> DFA::getTransitionsToState(c return transitionsToState; } +bool DFA::isTotal() const { + return transitions.size() == inputAlphabet.size() * states.size(); +} + +bool DFA::operator==(const Automaton& other) const { + return other == *this; +} + bool DFA::operator==(const DFA& other) const { return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->transitions == other.transitions; } -bool DFA::isTotal() const { - return transitions.size() == inputAlphabet.size() * states.size(); +void DFA::operator>>(std::ostream& out) const { + out << "(DFA" + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " initialState = " << initialState + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; } } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/DFA.h b/alib2/src/automaton/FSM/DFA.h index 6db2f5ede0abce173e8b749dd431f48c357a0ddd..db697e2827e48f9cfaaab00155037dfbd9665693 100644 --- a/alib2/src/automaton/FSM/DFA.h +++ b/alib2/src/automaton/FSM/DFA.h @@ -20,7 +20,7 @@ namespace automaton { * Represents Finite Automaton. * Can store nondeterministic finite automaton without epsilon transitions. */ -class DFA : public Automaton, public SingleInitialState, public InputAlphabet { +class DFA : public Automaton, public std::element<DFA, Automaton::visitor_type>, public SingleInitialState, public InputAlphabet { protected: std::map<std::pair<State, alphabet::Symbol>, State> transitions; public: @@ -75,10 +75,12 @@ public: * @return true when automaton is total deterministic, false otherwise */ bool isTotal() const; + + virtual bool operator==(const Automaton& other) const; - bool operator==(const DFA& other) const; + virtual bool operator==(const DFA& other) const; - friend std::ostream& operator<<(std::ostream& out, const DFA& automaton); + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/EpsilonNFA.cpp b/alib2/src/automaton/FSM/EpsilonNFA.cpp index fa208742d543d0f3a1b2d6455809a1af173a2f0f..45567fab5053a3f0f79a7c21cb3b9cfa3dfdf238 100644 --- a/alib2/src/automaton/FSM/EpsilonNFA.cpp +++ b/alib2/src/automaton/FSM/EpsilonNFA.cpp @@ -6,6 +6,7 @@ */ #include "EpsilonNFA.h" +#include "../../std/map.hpp" #include "../AutomatonException.h" #include <ostream> @@ -227,4 +228,22 @@ bool EpsilonNFA::isTotal() const { return isDeterministic() && transitions.size() == inputAlphabet.size() * states.size(); } +bool EpsilonNFA::operator==(const Automaton& other) const { + return other == *this; +} + +bool EpsilonNFA::operator==(const EpsilonNFA& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions; +} + +void EpsilonNFA::operator>>(std::ostream& out) const { + out << "(EpsilonNFA" + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " initialStates = " << initialStates + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/EpsilonNFA.h b/alib2/src/automaton/FSM/EpsilonNFA.h index 5e41b4243cd73c464fb89d5e04081d8232c8fafe..ef9d78e2a962163ce68f6e61069fbc8cce94f965 100644 --- a/alib2/src/automaton/FSM/EpsilonNFA.h +++ b/alib2/src/automaton/FSM/EpsilonNFA.h @@ -22,7 +22,7 @@ namespace automaton { * Represents Finite Automaton. * Can store nondeterministic finite automaton with epsilon transitions. */ -class EpsilonNFA : public Automaton, public MultiInitialStates, public InputAlphabet { +class EpsilonNFA : public Automaton, public std::element<EpsilonNFA, Automaton::visitor_type>, public MultiInitialStates, public InputAlphabet { protected: std::map<std::pair<State, std::variant<string::Epsilon, alphabet::Symbol> >, std::set<State> > transitions; public: @@ -146,8 +146,12 @@ public: * @return true when automaton is total deterministic, false otherwise */ bool isTotal() const; - - friend std::ostream& operator<<(std::ostream& out, const EpsilonNFA& automaton); + + virtual bool operator==(const Automaton& other) const; + + virtual bool operator==(const EpsilonNFA& other) const; + + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/ExtendedNFA.cpp b/alib2/src/automaton/FSM/ExtendedNFA.cpp index 796d32ab95c61b7d185cd222edbea7a6e0f6846a..66fecb5ad6f42a72896957007d5d222100776dcf 100644 --- a/alib2/src/automaton/FSM/ExtendedNFA.cpp +++ b/alib2/src/automaton/FSM/ExtendedNFA.cpp @@ -6,6 +6,7 @@ */ #include "ExtendedNFA.h" +#include "../../std/map.hpp" #include "../AutomatonException.h" #include <ostream> #include <algorithm> @@ -96,4 +97,22 @@ std::map<std::pair<State, regexp::RegExp>, std::set<State> > ExtendedNFA::getTra return transitionsToState; } +bool ExtendedNFA::operator==(const Automaton& other) const { + return other == *this; +} + +bool ExtendedNFA::operator==(const ExtendedNFA& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions; +} + +void ExtendedNFA::operator>>(std::ostream& out) const { + out << "(ExtendedNFA" + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " initialStates = " << initialStates + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/ExtendedNFA.h b/alib2/src/automaton/FSM/ExtendedNFA.h index b7cd2c7b859e581ec1766eb6bd7c04abb8496499..2e36838be7c11d2bf590d96b7915c0f05d5502e5 100644 --- a/alib2/src/automaton/FSM/ExtendedNFA.h +++ b/alib2/src/automaton/FSM/ExtendedNFA.h @@ -20,7 +20,7 @@ namespace automaton { * Represents Finite Automaton. * Can store nondeterministic finite automaton without epsilon transitions. */ -class ExtendedNFA : public Automaton, public MultiInitialStates, public InputAlphabet { +class ExtendedNFA : public Automaton, public std::element<ExtendedNFA, Automaton::visitor_type>, public MultiInitialStates, public InputAlphabet { protected: std::map<std::pair<State, regexp::RegExp>, std::set<State> > transitions; public: @@ -64,8 +64,12 @@ public: * @return automaton transitions to state */ std::map<std::pair<State, regexp::RegExp>, std::set<State> > getTransitionsToState(const State& from) const; - - friend std::ostream& operator<<(std::ostream& out, const ExtendedNFA& automaton); + + virtual bool operator==(const Automaton& other) const; + + virtual bool operator==(const ExtendedNFA& other) const; + + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/NFA.cpp b/alib2/src/automaton/FSM/NFA.cpp index faa1235750da3a6c267224859a66b5bf72ea2d50..e588e515cb846b675845157fd18ecde7c62bee16 100644 --- a/alib2/src/automaton/FSM/NFA.cpp +++ b/alib2/src/automaton/FSM/NFA.cpp @@ -112,4 +112,22 @@ bool NFA::isTotal() const { return isDeterministic() && transitions.size() == inputAlphabet.size() * states.size(); } +bool NFA::operator==(const Automaton& other) const { + return other == *this; +} + +bool NFA::operator==(const NFA& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->transitions == other.transitions; +} + +void NFA::operator>>(std::ostream& out) const { + out << "(NFA" + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " initialStates = " << initialStates + << " finalStates = " << finalStates + << " transitions = " << transitions + << ")"; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/FSM/NFA.h b/alib2/src/automaton/FSM/NFA.h index a71aad4991b51cc2a47f796474c035f3a7d54700..6fb134f24a8f07d924942afad5f1611844d36326 100644 --- a/alib2/src/automaton/FSM/NFA.h +++ b/alib2/src/automaton/FSM/NFA.h @@ -9,6 +9,7 @@ #define NFA_H_ #include <map> +#include "../../std/map.hpp" #include "../Automaton.h" #include "../common/MultiInitialStates.h" #include "../common/InputAlphabet.h" @@ -20,7 +21,7 @@ namespace automaton { * Represents Finite Automaton. * Can store nondeterministic finite automaton without epsilon transitions. */ -class NFA : public Automaton, public MultiInitialStates, public InputAlphabet { +class NFA : public Automaton, public std::element<NFA, Automaton::visitor_type>, public MultiInitialStates, public InputAlphabet { protected: std::map<std::pair<State, alphabet::Symbol>, std::set<State> > transitions; public: @@ -83,8 +84,12 @@ public: * @return true when automaton is total deterministic, false otherwise */ bool isTotal() const; - - friend std::ostream& operator<<(std::ostream& out, const NFA& automaton); + + virtual bool operator==(const Automaton& other) const; + + virtual bool operator==(const NFA& other) const; + + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/PDA/PDA.cpp b/alib2/src/automaton/PDA/PDA.cpp index aef4aa46eb67df7a1d288ea31e6e29a6f1b006f2..8c2278582f8be25b97b0ceac4f5aa557bd85f910 100644 --- a/alib2/src/automaton/PDA/PDA.cpp +++ b/alib2/src/automaton/PDA/PDA.cpp @@ -6,6 +6,7 @@ */ #include "PDA.h" +#include "../../std/map.hpp" #include "../AutomatonException.h" #include <algorithm> @@ -158,4 +159,24 @@ const std::set<alphabet::Symbol>& PDA::getInitialSymbols() const { return initialSymbols; } +bool PDA::operator==(const Automaton& other) const { + return other == *this; +} + +bool PDA::operator==(const PDA& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialStates == other.initialStates && this->finalStates == other.finalStates && this->stackAlphabet == other.stackAlphabet && this->initialSymbols == other.initialSymbols && this->transitions == other.transitions; +} + +void PDA::operator>>(std::ostream& out) const { + out << "(PDA" + << "states = " << states + << "inputAlphabet = " << inputAlphabet + << "initialStates = " << initialStates + << "finalStates = " << finalStates + << "stackAlphabet = " << stackAlphabet + << "initialSymbols = " << initialSymbols + << "transitions = " << transitions + << ")"; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/PDA/PDA.h b/alib2/src/automaton/PDA/PDA.h index a550b236f2e50ced78aa859fe5089a7e414a2876..bd4f2079d136461a6ebe107f63a5aa01be4520f6 100644 --- a/alib2/src/automaton/PDA/PDA.h +++ b/alib2/src/automaton/PDA/PDA.h @@ -23,7 +23,7 @@ namespace automaton { /** * Push Down Automaton */ -class PDA: public Automaton, public MultiInitialStates, public InputAlphabet { +class PDA: public Automaton, public std::element<PDA, Automaton::visitor_type>, public MultiInitialStates, public InputAlphabet { protected: std::set<alphabet::Symbol> stackAlphabet; std::map<std::tuple<State, std::variant<string::Epsilon, alphabet::Symbol>, std::vector<alphabet::Symbol> >, std::set<std::pair<State, std::vector<alphabet::Symbol> > > > transitions; @@ -117,6 +117,12 @@ public: */ const std::set<alphabet::Symbol>& getInitialSymbols() const; + virtual bool operator==(const Automaton& other) const; + + virtual bool operator==(const PDA& other) const; + + virtual void operator>>(std::ostream& os) const; + }; } /* namespace automaton */ diff --git a/alib2/src/automaton/TM/OneTapeDTM.cpp b/alib2/src/automaton/TM/OneTapeDTM.cpp index 6e695ef72a01e30459097b8391c412263841247d..1b496fe6531da051eff6dd8fd892e2d0f642c550 100644 --- a/alib2/src/automaton/TM/OneTapeDTM.cpp +++ b/alib2/src/automaton/TM/OneTapeDTM.cpp @@ -6,6 +6,7 @@ */ #include "OneTapeDTM.h" +#include "../../std/map.hpp" #include "../AutomatonException.h" #include "../../alphabet/Blank.h" @@ -105,4 +106,24 @@ const std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::S return transitions; } +bool OneTapeDTM::operator==(const Automaton& other) const { + return other == *this; +} + +bool OneTapeDTM::operator==(const OneTapeDTM& other) const { + return this->states == other.states && this->inputAlphabet == other.inputAlphabet && this->initialState == other.initialState && this->finalStates == other.finalStates && this->tapeAlphabet == other.tapeAlphabet && this->blankSymbol == other.blankSymbol && this->transitions == other.transitions; +} + +void OneTapeDTM::operator>>(std::ostream& out) const { + out << "(OneTapeDTM" + << "states = " << states + << "inputAlphabet = " << inputAlphabet + << "initialState = " << initialState + << "finalStates = " << finalStates + << "tapeAlphabet = " << tapeAlphabet + << "blankSymbol = " << blankSymbol + << "transitions = " << transitions + << ")"; +} + } /* namespace automaton */ diff --git a/alib2/src/automaton/TM/OneTapeDTM.h b/alib2/src/automaton/TM/OneTapeDTM.h index 7726bebc5a7e3ab2874e9e8e4afaa6e5b16fdd61..91b6b5399430d9594bf31ccf5084f52a74f119c6 100644 --- a/alib2/src/automaton/TM/OneTapeDTM.h +++ b/alib2/src/automaton/TM/OneTapeDTM.h @@ -22,7 +22,7 @@ namespace automaton { /** * One tape turing machine */ -class OneTapeDTM : public Automaton, public SingleInitialState, public BlankSymbolInputTapeAlphabet { +class OneTapeDTM : public Automaton, public std::element<OneTapeDTM, Automaton::visitor_type>, public SingleInitialState, public BlankSymbolInputTapeAlphabet { protected: std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::Symbol, Shift> > transitions; @@ -69,6 +69,11 @@ public: */ const std::map<std::pair<State, alphabet::Symbol>, std::tuple<State, alphabet::Symbol, Shift> >& getTransitions() const; + virtual bool operator==(const Automaton& other) const; + + virtual bool operator==(const OneTapeDTM& other) const; + + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/UnknownAutomaton.cpp b/alib2/src/automaton/UnknownAutomaton.cpp index c85d2ee291b983eab5c0fd49b23db805d3dcd6d7..12ac46e0e2f50dfb7913bbdff9e78868a6e0ec2d 100644 --- a/alib2/src/automaton/UnknownAutomaton.cpp +++ b/alib2/src/automaton/UnknownAutomaton.cpp @@ -171,7 +171,11 @@ const std::set<UnknownTransition>& UnknownAutomaton::getTransitions() const { } -bool UnknownAutomaton::operator==(const UnknownAutomaton& other) { +bool UnknownAutomaton::operator==(const Automaton& other) const { + return other == *this; +} + +bool UnknownAutomaton::operator==(const UnknownAutomaton& other) const { return states == other.states && inputAlphabet == other.inputAlphabet && initialStates == other.initialStates @@ -183,20 +187,19 @@ bool UnknownAutomaton::operator==(const UnknownAutomaton& other) { && transitions == other.transitions; } -std::ostream& operator<<(std::ostream& out, const UnknownAutomaton& automaton) { +void UnknownAutomaton::operator>>(std::ostream& out) const { out << "(UnknownAutomaton" - << " states = " << automaton.states - << " inputAlphabet = " << automaton.inputAlphabet - << " initialStates = " << automaton.initialStates - << " finalStates = " << automaton.finalStates - << " stackAlphabet = " << automaton.stackAlphabet - << " initialSymbols = " << automaton.initialSymbols - << " tapeAlphabet = " << automaton.tapeAlphabet + << " states = " << states + << " inputAlphabet = " << inputAlphabet + << " initialStates = " << initialStates + << " finalStates = " << finalStates + << " stackAlphabet = " << stackAlphabet + << " initialSymbols = " << initialSymbols + << " tapeAlphabet = " << tapeAlphabet << " blankSymbol = "; - if(automaton.blankSymbol == NULL) out << "NULL"; else out << *automaton.blankSymbol; - out << " transitions = " << automaton.transitions + if(blankSymbol == NULL) out << "NULL"; else out << *blankSymbol; + out << " transitions = " << transitions << ")"; - return out; } } /* namespace automaton */ diff --git a/alib2/src/automaton/UnknownAutomaton.h b/alib2/src/automaton/UnknownAutomaton.h index 550083484f768b0f7cc18156b37030aaca99d419..eb224489439e7520195bded2b8c6c26dfec2a1a3 100644 --- a/alib2/src/automaton/UnknownAutomaton.h +++ b/alib2/src/automaton/UnknownAutomaton.h @@ -21,7 +21,7 @@ namespace automaton { /** * Class representing unknown automaton parsed from XML. */ -class UnknownAutomaton : public Automaton { +class UnknownAutomaton : public Automaton, public std::element<UnknownAutomaton, Automaton::visitor_type> { protected: std::set<State> states; std::set<State> initialStates; @@ -271,9 +271,11 @@ public: * Compares two instances of UnknownAutomata * @return true if this and other instance are same */ - bool operator==(const UnknownAutomaton& other); + virtual bool operator==(const UnknownAutomaton& other) const; - friend std::ostream& operator<<(std::ostream&, const UnknownAutomaton&); + virtual bool operator==(const Automaton& other) const; + + virtual void operator>>(std::ostream& os) const; }; } /* namespace automaton */ diff --git a/alib2/src/automaton/UnknownAutomatonToXMLComposer.cpp b/alib2/src/automaton/UnknownAutomatonToXMLComposer.cpp deleted file mode 100644 index cc08fd1137c9d43ad6fc58f39f3f3f5b2025f253..0000000000000000000000000000000000000000 --- a/alib2/src/automaton/UnknownAutomatonToXMLComposer.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * UnknownAutomatonToXMLComposer.cpp - * - * Created on: Nov 11, 2013 - * Author: martin - */ - -#include "UnknownAutomatonToXMLComposer.h" - -namespace automaton { - -void UnknownAutomatonToXMLComposer::printStates(std::list<sax::Token>& out, const std::set<State>& states, std::string tagName) { - out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); - for (auto& state : states) { - printState(out, state, "state"); - } - out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); -} - -void UnknownAutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::set<alphabet::Symbol>& alphabet, std::string tagName) { - out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); - for (auto& symbol : alphabet) { - printSymbol(out, symbol, "symbol"); - } - out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); -} - -void UnknownAutomatonToXMLComposer::printSymbols(std::list<sax::Token>& out, const std::vector<alphabet::Symbol>& alphabet, std::string tagName) { - out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); - for (auto& symbol : alphabet) { - printSymbol(out, symbol, "symbol"); - } - out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); -} - -void UnknownAutomatonToXMLComposer::printUnknownTransitions(std::list<sax::Token>& out, const std::set<UnknownTransition>& transitions) { - out.push_back(sax::Token("transitions", sax::Token::START_ELEMENT)); - for (auto& transition : transitions) { - out.push_back(sax::Token("transition", sax::Token::START_ELEMENT)); - - if (transition.hasFrom()) { - printState(out, transition.getFrom(), "from"); - } - - if(transition.hasInput()) { - printInput(out, transition.getInput(), "input"); - } - - if(transition.hasTo()) { - printState(out, transition.getTo(), "to"); - } - - if (transition.getPop().size() > 0) { - printSymbols(out, transition.getPop(), "pop"); - } - if (transition.getPush().size() > 0) { - printSymbols(out, transition.getPush(), "push"); - } - - if (transition.hasOutput()) { - printInput(out, transition.getOutput(), "output"); - } - - if (transition.getShift() != Shift::NOT_SET) { - printShift(out, transition.getShift(), "shift"); - } - - out.push_back(sax::Token("transition", sax::Token::END_ELEMENT)); - } - - out.push_back(sax::Token("transitions", sax::Token::END_ELEMENT)); -} - -void UnknownAutomatonToXMLComposer::printState(std::list<sax::Token>& out, const State& state, std::string tagName) { - out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); - out.push_back(sax::Token(state.getName(), sax::Token::CHARACTER)); - out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); -} - -void UnknownAutomatonToXMLComposer::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 if(symbol.get<alphabet::Symbol>() == alphabet::Blank::BLANK) { - out.push_back(sax::Token("blank", sax::Token::START_ELEMENT)); - out.push_back(sax::Token("blank", 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 UnknownAutomatonToXMLComposer::printSymbol(std::list<sax::Token>& out, const alphabet::Symbol& symbol, std::string tagName) { - if(symbol == alphabet::Blank::BLANK) { - out.push_back(sax::Token("blank", sax::Token::START_ELEMENT)); - out.push_back(sax::Token("blank", sax::Token::START_ELEMENT)); - } else { - out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); - out.push_back(sax::Token(symbol.getSymbol(), sax::Token::CHARACTER)); - out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); - } -} - -void UnknownAutomatonToXMLComposer::printShift(std::list<sax::Token>& out, const Shift& shift, std::string tagName) { - out.push_back(sax::Token(tagName, sax::Token::START_ELEMENT)); - out.push_back(sax::Token(SHIFT_NAMES [shift], sax::Token::CHARACTER)); - out.push_back(sax::Token(tagName, sax::Token::END_ELEMENT)); -} - -std::list<sax::Token> UnknownAutomatonToXMLComposer::compose(const UnknownAutomaton& automaton) { - std::list<sax::Token> out; - out.push_back(sax::Token("automaton", sax::Token::START_ELEMENT)); - - if (automaton.getStates().size() > 0) { - printStates(out, automaton.getStates(), "states"); - } - - if (automaton.getInputSymbols().size() > 0) { - printSymbols(out, automaton.getInputSymbols(), "inputAlphabet"); - } - if (automaton.getTapeSymbols().size() > 0) { - printSymbols(out, automaton.getTapeSymbols(), "tapeAlphabet"); - } - if (automaton.getStackSymbols().size() > 0) { - printSymbols(out, automaton.getStackSymbols(), "stackAlphabet"); - } - - if (automaton.getTransitions().size() > 0) { - printUnknownTransitions(out, automaton.getTransitions()); - } - - if (automaton.hasBlankSymbol()) { - printSymbol(out, automaton.getBlankSymbol(), "blankSymbol"); - } - if (automaton.getInitialSymbols().size() > 0) { - printSymbols(out, automaton.getInitialSymbols(), "startSymbols"); - } - - if (automaton.getInitialStates().size() > 0) { - printStates(out, automaton.getInitialStates(), "initialStates"); - } - if (automaton.getFinalStates().size() > 0) { - printStates(out, automaton.getFinalStates(), "finalStates"); - } - - out.push_back(sax::Token("automaton", sax::Token::END_ELEMENT)); - return out; -} - -} /* namespace automaton */ - diff --git a/alib2/src/automaton/UnknownAutomatonToXMLComposer.h b/alib2/src/automaton/UnknownAutomatonToXMLComposer.h deleted file mode 100644 index 7325ebd1cfa45ad520e1bc6011ff019ae0384653..0000000000000000000000000000000000000000 --- a/alib2/src/automaton/UnknownAutomatonToXMLComposer.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * UnknownAutomatonToXMLComposer.h - * - * Created on: Nov 11, 2013 - * Author: Jan Travnicek - */ - -#ifndef UNKNOWN_AUTOMATON_TO_XML_COMPOSER_H_ -#define UNKNOWN_AUTOMATON_TO_XML_COMPOSER_H_ - -#include <string> -#include "UnknownAutomaton.h" -#include "../sax/Token.h" -#include "../alphabet/Blank.h" - -namespace automaton { - -/** - * This class contains methods to print XML representation of automata to the output stream. - */ -class UnknownAutomatonToXMLComposer { -protected: - static void printStates(std::list<sax::Token>&, const std::set<State>& states, std::string tagName); - static void printSymbols(std::list<sax::Token>&, const std::set<alphabet::Symbol>& alphabet, std::string tagName); - static void printSymbols(std::list<sax::Token>&, const std::vector<alphabet::Symbol>& alphabet, std::string tagName); - - static void printUnknownTransitions(std::list<sax::Token>&, const std::set<UnknownTransition>& transitions); - - 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: - /** - * Prints XML representation of UnknownAutomaton to the output stream. - * @param automaton automaton to print - * @return list of xml tokens representing the automaton - */ - std::list<sax::Token> compose(const UnknownAutomaton& automaton); -}; - -} /* namespace automaton */ - -#endif /* AUTOMATON_TO_XML_COMPOSER_H_ */ - diff --git a/alib2/src/factory/AutomatonFactory.cpp b/alib2/src/factory/AutomatonFactory.cpp index 847bbf3c86dd0cd28230783766b214698ce849d7..48a8a5a77021c2042ac1a556faa3eac49a5abd09 100644 --- a/alib2/src/factory/AutomatonFactory.cpp +++ b/alib2/src/factory/AutomatonFactory.cpp @@ -40,28 +40,28 @@ Automaton* AutomatonFactory::parse(std::list<sax::Token> tokens) { return parser.parse(tokens); } -void AutomatonFactory::toFile(const Automaton* automaton, const std::string& filename) { +void AutomatonFactory::toFile(const Automaton& automaton, const std::string& filename) { std::list<sax::Token> tokens = compose(automaton); sax::SaxComposeInterface::printFile(filename, tokens); } -std::string AutomatonFactory::toString(const Automaton* automaton) { +std::string AutomatonFactory::toString(const Automaton& automaton) { std::list<sax::Token> tokens = compose(automaton); std::string str; sax::SaxComposeInterface::printMemory(str, tokens); return str; } -void AutomatonFactory::toStdout(const Automaton* automaton) { +void AutomatonFactory::toStdout(const Automaton& automaton) { return AutomatonFactory::toStream(automaton, std::cout); } -void AutomatonFactory::toStream(const Automaton* automaton, std::ostream& out) { +void AutomatonFactory::toStream(const Automaton& automaton, std::ostream& out) { std::list<sax::Token> tokens = compose(automaton); sax::SaxComposeInterface::printStream(out, tokens); } -std::list<sax::Token> AutomatonFactory::compose(const Automaton* automaton) { +std::list<sax::Token> AutomatonFactory::compose(const Automaton& automaton) { AutomatonToXMLComposer composer; return composer.compose(automaton); } diff --git a/alib2/src/factory/AutomatonFactory.h b/alib2/src/factory/AutomatonFactory.h index 4f7152240fa806d9afa587c40a49e7faaef4cebb..91726ce29d4920259e21bf9105a1491ab05120ab 100644 --- a/alib2/src/factory/AutomatonFactory.h +++ b/alib2/src/factory/AutomatonFactory.h @@ -51,26 +51,26 @@ public: * @param filename path to the file * @return RegExp */ - static void toFile(const Automaton*, const std::string& filename); + static void toFile(const Automaton&, const std::string& filename); /** * Parses the XML and returns the RegExp. * @param str string containing the XML * @return RegExp */ - static std::string toString(const Automaton*); + static std::string toString(const Automaton&); /** * Parses the XML from stdin and returns the RegExp. * @return RegExp */ - static void toStdout(const Automaton*); + static void toStdout(const Automaton&); /** * Parses the XML from stream and returns the RegExp. * @return RegExp */ - static void toStream(const Automaton*, std::ostream& out); + static void toStream(const Automaton&, std::ostream& out); protected: @@ -86,7 +86,7 @@ protected: * @param tokens XML represented as list of tokens * @return parsed RegExp */ - static std::list<sax::Token> compose(const Automaton*); + static std::list<sax::Token> compose(const Automaton&); }; } /* namespace automaton */ diff --git a/alib2/src/std/list.hpp b/alib2/src/std/list.hpp index e208e17b3a3140a7888bf852f5e81356ac7d8f5f..7833c1b8be39ed2491b6a704030f4beca89f0942 100644 --- a/alib2/src/std/list.hpp +++ b/alib2/src/std/list.hpp @@ -2,6 +2,15 @@ #define __LIST_HPP_ #include <list> + +template< class T > +std::ostream& operator<<(std::ostream& out, const std::list<T>& list); + +#include "set.hpp" +#include "map.hpp" +#include "pair.hpp" +#include "tuple.hpp" +#include "vector.hpp" #include <iostream> namespace std { @@ -23,5 +32,5 @@ std::ostream& operator<<(std::ostream& out, const std::list<T>& list) { } /* namespace std */ -#endif /* LIST_HPP_ */ +#endif /* __LIST_HPP_ */ diff --git a/alib2/src/std/map.hpp b/alib2/src/std/map.hpp new file mode 100644 index 0000000000000000000000000000000000000000..4b2d78146a18fc4c26347782b5a3dd2cbfa99ab2 --- /dev/null +++ b/alib2/src/std/map.hpp @@ -0,0 +1,36 @@ +#ifndef __MAP_HPP_ +#define __MAP_HPP_ + +#include <map> + +template< class T, class R > +std::ostream& operator<<(std::ostream& out, const std::map<T, R>& map); + +#include "set.hpp" +#include "pair.hpp" +#include "list.hpp" +#include "tuple.hpp" +#include "vector.hpp" +#include <iostream> + +namespace std { + +template< class T, class R > +std::ostream& operator<<(std::ostream& out, const std::map<T, R>& map) { + out << "{"; + + bool first = true; + for(const std::pair<T, R>& item : map) { + if(!first) out << ", "; + first = false; + out << item; + } + + out << "}"; + return out; +} + +} /* namespace std */ + +#endif /* __MAP_HPP_ */ + diff --git a/alib2/src/std/pair.hpp b/alib2/src/std/pair.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c410e9f7d1399d0404114f6766fee0ee5bd13adf --- /dev/null +++ b/alib2/src/std/pair.hpp @@ -0,0 +1,27 @@ +#ifndef __PAIR_HPP_ +#define __PAIR_HPP_ + +#include <map> + +template< class T, class R > +std::ostream& operator<<(std::ostream& out, const std::pair<T, R>& pair); + +#include "set.hpp" +#include "map.hpp" +#include "list.hpp" +#include "tuple.hpp" +#include "vector.hpp" +#include <iostream> + +namespace std { + +template< class T, class R > +std::ostream& operator<<(std::ostream& out, const std::pair<T, R>& pair) { + out << "(" << pair.first << ", " << pair.second << ")"; + return out; +} + +} /* namespace std */ + +#endif /* __PAIR_HPP_ */ + diff --git a/alib2/src/std/set.hpp b/alib2/src/std/set.hpp index 706f5f6b2395652c882ec900e951a30f82f9c22c..ef4e849372713875c3bdf92af0b7638c0bd107e2 100644 --- a/alib2/src/std/set.hpp +++ b/alib2/src/std/set.hpp @@ -2,6 +2,15 @@ #define __SET_HPP_ #include <set> + +template< class T > +std::ostream& operator<<(std::ostream& out, const std::set<T>& list); + +#include "map.hpp" +#include "pair.hpp" +#include "list.hpp" +#include "tuple.hpp" +#include "vector.hpp" #include <iostream> namespace std { @@ -23,5 +32,5 @@ std::ostream& operator<<(std::ostream& out, const std::set<T>& list) { } /* namespace std */ -#endif /* SET_HPP_ */ +#endif /* __SET_HPP_ */ diff --git a/alib2/src/std/tuple.hpp b/alib2/src/std/tuple.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f91f3402bf7823750cbe4edc88b5b9790f02f3f7 --- /dev/null +++ b/alib2/src/std/tuple.hpp @@ -0,0 +1,52 @@ +#ifndef __TUPLE_HPP_ +#define __TUPLE_HPP_ + +#include <tuple> + +template< class... Ts> +std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...>& tuple); + +#include "set.hpp" +#include "map.hpp" +#include "list.hpp" +#include "pair.hpp" +#include "vector.hpp" +#include <iostream> + +namespace std { + +template<int I, class Tuple> +struct operator_shift_left_impl; + +template<int I, class Tuple> +struct operator_shift_left_impl { + static void operator_shift_left(ostream& out, const Tuple& t) { + operator_shift_left_impl<I - 1, Tuple>::operator_shift_left(out, t); + out << ", " << get<I>(t); + } +}; + +template<class Tuple> +struct operator_shift_left_impl<0, Tuple> { + static void operator_shift_left(ostream& out, const Tuple& t) { + out << get<0>(t); + } +}; + +template<class Tuple> +void operator_shift_left(ostream& out, const Tuple& t) { + operator_shift_left_impl<tuple_size<Tuple>::value - 1, Tuple>::operator_shift_left(out, t); +} + +template< class... Ts> +std::ostream& operator<<(std::ostream& out, const std::tuple<Ts...>& tuple) { + out << "("; + operator_shift_left(out, tuple); + out << ")"; + return out; +} + +} /* namespace std */ + +#endif /* __TUPLE_HPP_ */ + diff --git a/alib2/src/std/vector.hpp b/alib2/src/std/vector.hpp index 9593e944dac478e062d9d858c22a8ccc388c2c6e..a9c4017052692ad2ac053d59d0ac4d53cb87e115 100644 --- a/alib2/src/std/vector.hpp +++ b/alib2/src/std/vector.hpp @@ -2,6 +2,15 @@ #define __VECTOR_HPP_ #include <vector> + +template< class T > +std::ostream& operator<<(std::ostream& out, const std::vector<T>& vector); + +#include "set.hpp" +#include "map.hpp" +#include "pair.hpp" +#include "tuple.hpp" +#include "list.hpp" #include <iostream> namespace std { @@ -23,4 +32,5 @@ std::ostream& operator<<(std::ostream& out, const std::vector<T>& vector) { } /* namespace std */ -#endif /* VECTOR_HPP_ */ \ No newline at end of file +#endif /* __VECTOR_HPP_ */ + diff --git a/alib2/test-src/automaton/AutomatonTest.cpp b/alib2/test-src/automaton/AutomatonTest.cpp index 41784292119fb98ca27ecef7a4b637a5502e9919..919d79efebbc8dbac20ac04ce62fd7250ed6563e 100644 --- a/alib2/test-src/automaton/AutomatonTest.cpp +++ b/alib2/test-src/automaton/AutomatonTest.cpp @@ -5,7 +5,6 @@ #include "sax/SaxComposeInterface.h" #include "automaton/UnknownAutomaton.h" -#include "automaton/UnknownAutomatonToXMLComposer.h" #include "automaton/FSM/DFA.h" #include "automaton/AutomatonFromXMLParser.h" @@ -31,7 +30,7 @@ void AutomatonTest::testXMLParser() { CPPUNIT_ASSERT( automaton == automaton ); { - automaton::UnknownAutomatonToXMLComposer composer; + automaton::AutomatonToXMLComposer composer; std::list<sax::Token> tokens = composer.compose(automaton); std::string tmp; sax::SaxComposeInterface::printMemory(tmp, tokens); @@ -44,11 +43,10 @@ void AutomatonTest::testXMLParser() { CPPUNIT_ASSERT( automaton == automaton2 ); } { -// std::string tmp = automaton::AutomatonFactory::toString(automaton); -// automaton::UnknownAutomaton automaton2 = automaton::AutomatonFactory::fromString(tmp); - -// CPPUNIT_ASSERT( automaton == automaton2 ); + std::string tmp = automaton::AutomatonFactory::toString(automaton); + automaton::Automaton* automaton2 = automaton::AutomatonFactory::fromString(tmp); + CPPUNIT_ASSERT( automaton == *automaton2 ); } }