From 2538ab7a7028dfd7a91e2b86f7fbffd29ecd902a Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sun, 18 May 2014 20:47:56 +0200 Subject: [PATCH] visitor in xml composer, polymorfic printing, operator== --- alib2/src/automaton/Automaton.cpp | 45 ++++++ alib2/src/automaton/Automaton.h | 37 ++++- .../src/automaton/AutomatonToXMLComposer.cpp | 152 +++++++++++++++++- alib2/src/automaton/AutomatonToXMLComposer.h | 22 ++- alib2/src/automaton/FSM/CompactNFA.cpp | 19 +++ alib2/src/automaton/FSM/CompactNFA.h | 8 +- alib2/src/automaton/FSM/DFA.cpp | 20 ++- alib2/src/automaton/FSM/DFA.h | 8 +- alib2/src/automaton/FSM/EpsilonNFA.cpp | 19 +++ alib2/src/automaton/FSM/EpsilonNFA.h | 10 +- alib2/src/automaton/FSM/ExtendedNFA.cpp | 19 +++ alib2/src/automaton/FSM/ExtendedNFA.h | 10 +- alib2/src/automaton/FSM/NFA.cpp | 18 +++ alib2/src/automaton/FSM/NFA.h | 11 +- alib2/src/automaton/PDA/PDA.cpp | 21 +++ alib2/src/automaton/PDA/PDA.h | 8 +- alib2/src/automaton/TM/OneTapeDTM.cpp | 21 +++ alib2/src/automaton/TM/OneTapeDTM.h | 7 +- alib2/src/automaton/UnknownAutomaton.cpp | 27 ++-- alib2/src/automaton/UnknownAutomaton.h | 8 +- .../UnknownAutomatonToXMLComposer.cpp | 152 ------------------ .../automaton/UnknownAutomatonToXMLComposer.h | 46 ------ alib2/src/factory/AutomatonFactory.cpp | 10 +- alib2/src/factory/AutomatonFactory.h | 10 +- alib2/src/std/list.hpp | 11 +- alib2/src/std/map.hpp | 36 +++++ alib2/src/std/pair.hpp | 27 ++++ alib2/src/std/set.hpp | 11 +- alib2/src/std/tuple.hpp | 52 ++++++ alib2/src/std/vector.hpp | 12 +- alib2/test-src/automaton/AutomatonTest.cpp | 10 +- 31 files changed, 607 insertions(+), 260 deletions(-) delete mode 100644 alib2/src/automaton/UnknownAutomatonToXMLComposer.cpp delete mode 100644 alib2/src/automaton/UnknownAutomatonToXMLComposer.h create mode 100644 alib2/src/std/map.hpp create mode 100644 alib2/src/std/pair.hpp create mode 100644 alib2/src/std/tuple.hpp diff --git a/alib2/src/automaton/Automaton.cpp b/alib2/src/automaton/Automaton.cpp index d8dfa9540a..cf7fe0bf13 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 5c6029a6e1..13a1acf614 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 34ed86507e..be77fd416e 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 1a39dc731c..3daa380ce1 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 0e2b2ed2d9..e8f8585b90 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 7e1b7e9053..0779c6783e 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 a96cbe28df..5b86e94dd5 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 6db2f5ede0..db697e2827 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 fa208742d5..45567fab50 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 5e41b4243c..ef9d78e2a9 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 796d32ab95..66fecb5ad6 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 b7cd2c7b85..2e36838be7 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 faa1235750..e588e515cb 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 a71aad4991..6fb134f24a 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 aef4aa46eb..8c2278582f 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 a550b236f2..bd4f2079d1 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 6e695ef72a..1b496fe653 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 7726bebc5a..91b6b53994 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 c85d2ee291..12ac46e0e2 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 550083484f..eb22448943 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 cc08fd1137..0000000000 --- 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 7325ebd1cf..0000000000 --- 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 847bbf3c86..48a8a5a770 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 4f7152240f..91726ce29d 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 e208e17b3a..7833c1b8be 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 0000000000..4b2d78146a --- /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 0000000000..c410e9f7d1 --- /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 706f5f6b23..ef4e849372 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 0000000000..f91f3402bf --- /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 9593e944da..a9c4017052 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 4178429211..919d79efeb 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 ); } } -- GitLab