From c17b24257e11d34f89a7b8c8fd3cedcdbbddb372 Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sun, 24 Aug 2014 15:20:56 +0200 Subject: [PATCH] Implement set container represenation --- alib2data/src/Api.cpp | 13 +++++ alib2data/src/Api.hpp | 10 +++- alib2data/src/container/Container.h | 25 +++++++++ alib2data/src/container/ContainerBase.h | 28 ++++++++++ alib2data/src/container/ContainerFeatures.h | 19 +++++++ .../src/container/ContainerFromXMLParser.cpp | 27 +++++++++ .../src/container/ContainerFromXMLParser.hpp | 13 ++++- .../src/container/ContainerToXMLComposer.cpp | 25 +++++++++ .../src/container/ContainerToXMLComposer.hpp | 23 +++++++- alib2data/src/container/ObjectsSet.cpp | 55 +++++++++++++++++++ alib2data/src/container/ObjectsSet.h | 47 ++++++++++++++++ alib2data/src/object/Object.h | 3 +- alib2data/src/object/ObjectBase.h | 12 +++- alib2data/src/object/ObjectFromXMLParser.cpp | 3 + .../test-src/container/ContainerTest.cpp | 48 ++++++++++++++++ alib2data/test-src/container/ContainerTest.h | 19 +++++++ 16 files changed, 362 insertions(+), 8 deletions(-) create mode 100644 alib2data/src/container/Container.h create mode 100644 alib2data/src/container/ContainerBase.h create mode 100644 alib2data/src/container/ContainerFeatures.h create mode 100644 alib2data/src/container/ContainerToXMLComposer.cpp create mode 100644 alib2data/src/container/ObjectsSet.cpp create mode 100644 alib2data/src/container/ObjectsSet.h create mode 100644 alib2data/test-src/container/ContainerTest.cpp create mode 100644 alib2data/test-src/container/ContainerTest.h diff --git a/alib2data/src/Api.cpp b/alib2data/src/Api.cpp index 32660945af..e07c77f7bb 100644 --- a/alib2data/src/Api.cpp +++ b/alib2data/src/Api.cpp @@ -27,9 +27,18 @@ const automaton::AutomatonToXMLComposer ToXMLComposers::automatonComposer; const grammar::GrammarToXMLComposer ToXMLComposers::grammarComposer; const alib::ObjectToXMLComposer ToXMLComposers::objectComposer; const exception::ExceptionToXMLComposer ToXMLComposers::exceptionComposer; +const container::ContainerToXMLComposer ToXMLComposers::containerComposer; const ToXMLComposers ToXMLComposers::toXMLComposers; +container::ObjectsSet api<container::ObjectsSet>::parse(std::list<sax::Token>& input) { + return FromXMLParsers::containerParser.parseObjectsSet(input); +} + +std::list<sax::Token> api<container::ObjectsSet>::compose(const container::ObjectsSet& data) { + return ToXMLComposers::containerComposer.compose(data); +} + alib::Object api<alib::Object>::parse(std::list<sax::Token>& input) { return FromXMLParsers::objectParser.parseObject(input); } @@ -379,6 +388,10 @@ std::list<sax::Token> api<string::Epsilon>::compose(const string::Epsilon& data) return ToXMLComposers::stringComposer.compose(data); } +void ToXMLComposers::Visit(void* data, const container::ObjectsSet& container) const { + *((std::list<sax::Token>*) data) = std::move(ToXMLComposers::containerComposer.compose(container)); +} + void ToXMLComposers::Visit(void* data, const exception::AlibException& symbol) const { *((std::list<sax::Token>*) data) = std::move(ToXMLComposers::exceptionComposer.compose(symbol)); } diff --git a/alib2data/src/Api.hpp b/alib2data/src/Api.hpp index 62d7caf187..093ef63e93 100644 --- a/alib2data/src/Api.hpp +++ b/alib2data/src/Api.hpp @@ -42,6 +42,12 @@ struct api<std::set<T>> { static std::list<sax::Token> compose(const std::set<T>& data); }; +template<> +struct api<container::ObjectsSet> { + static container::ObjectsSet parse(std::list<sax::Token>& input); + static std::list<sax::Token> compose(const container::ObjectsSet& data); +}; + template<> struct api<alib::Object> { @@ -378,6 +384,8 @@ class ToXMLComposers : public ObjectBase::const_visitor_type { void Visit(void*, const string::CyclicString& string) const; void Visit(void*, const string::Epsilon& string) const; + void Visit(void*, const container::ObjectsSet& set) const; + public: static const label::LabelToXMLComposer labelComposer; static const alphabet::SymbolToXMLComposer symbolComposer; @@ -399,7 +407,7 @@ std::set<T> api<std::set<T>>::parse(std::list<sax::Token>& input) { template<typename T> std::list<sax::Token> api<std::set<T>>::compose(const std::set<T>& input) { - return ToXMLComposers::containerComposer.composeSet<T>(input); + return ToXMLComposers::containerComposer.compose<T>(input); } } /* namespace alib */ diff --git a/alib2data/src/container/Container.h b/alib2data/src/container/Container.h new file mode 100644 index 0000000000..3577d661e0 --- /dev/null +++ b/alib2data/src/container/Container.h @@ -0,0 +1,25 @@ +/* + * Container.h + * + * Created on: Apr 10, 2013 + * Author: Martin Zak + */ + +#ifndef CONTAINER_H_ +#define CONTAINER_H_ + +#include "../std/visitor.hpp" +#include "ContainerBase.h" +#include "../common/wrapper.hpp" + +namespace container { + +/** + * Wrapper around automata. + */ +typedef alib::wrapper<ContainerBase> Container; + +} /* namespace container */ + +#endif /* CONTAINER_H_ */ + diff --git a/alib2data/src/container/ContainerBase.h b/alib2data/src/container/ContainerBase.h new file mode 100644 index 0000000000..8d0057fccd --- /dev/null +++ b/alib2data/src/container/ContainerBase.h @@ -0,0 +1,28 @@ +/* + * ContainerBase.h + * + * Created on: Mar 26, 2013 + * Author: Jan Travnicek + */ + +#ifndef CONTAINER_BASE_H_ +#define CONTAINER_BASE_H_ + +#include "../common/base.hpp" +#include "../object/ObjectBase.h" + +namespace container { + +/** + * Represents symbol in an container. + */ +class ContainerBase : public alib::ObjectBase { +public: + virtual ContainerBase* clone() const = 0; + virtual ContainerBase* plunder() && = 0; + +}; + +} /* namespace container */ + +#endif /* CONTAINER_BASE_H_ */ diff --git a/alib2data/src/container/ContainerFeatures.h b/alib2data/src/container/ContainerFeatures.h new file mode 100644 index 0000000000..05e5cf6dc0 --- /dev/null +++ b/alib2data/src/container/ContainerFeatures.h @@ -0,0 +1,19 @@ +/* + * ContainerFeatures.h + * + * Created on: Jun 19, 2014 + * Author: Jan Travnicek + */ + +#ifndef CONTAINER_FEATURES_H_ +#define CONTAINER_FEATURES_H_ + +namespace container { + +enum class FEATURES { + SET +}; + +} /* namespace container */ + +#endif /* CONTAINER_FEATURES_H_ */ diff --git a/alib2data/src/container/ContainerFromXMLParser.cpp b/alib2data/src/container/ContainerFromXMLParser.cpp index 231a96c0fb..2164e1363d 100644 --- a/alib2data/src/container/ContainerFromXMLParser.cpp +++ b/alib2data/src/container/ContainerFromXMLParser.cpp @@ -6,6 +6,7 @@ */ #include "ContainerFromXMLParser.hpp" +#include "../sax/ParserException.h" namespace container { @@ -17,5 +18,31 @@ bool ContainerFromXMLParser::first(std::list<sax::Token>& input) const { } } +Container ContainerFromXMLParser::parseContainer(std::list<sax::Token>& input) const { + return parseContainer(input, std::set<FEATURES>({FEATURES::SET})); +} + +Container ContainerFromXMLParser::parseContainer(std::list<sax::Token>& input, const std::set<FEATURES>& features) const { + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "set")) { + if(!features.count(FEATURES::SET)) throw exception::AlibException(); + return Container(parseObjectsSet(input)); + } else { + throw sax::ParserException(sax::Token("set", sax::Token::TokenType::START_ELEMENT), input.front()); + } +} + +ObjectsSet ContainerFromXMLParser::parseObjectsSet(std::list<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "set"); + + ObjectsSet set; + + while(isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + set.insert(alib::api<alib::Object>::parse(input)); + } + + popToken(input, sax::Token::TokenType::END_ELEMENT, "set"); + return set; +} + } /* namespace automaton */ diff --git a/alib2data/src/container/ContainerFromXMLParser.hpp b/alib2data/src/container/ContainerFromXMLParser.hpp index 44f56c797b..5bd06047e1 100644 --- a/alib2data/src/container/ContainerFromXMLParser.hpp +++ b/alib2data/src/container/ContainerFromXMLParser.hpp @@ -9,8 +9,12 @@ #define CONTAINER_FROM_XML_PARSER_H_ #include "../sax/FromXMLParserHelper.h" +#include "ContainerFeatures.h" #include <set> +#include "ObjectsSet.h" + +#include "Container.h" namespace alib { @@ -31,15 +35,20 @@ namespace container { * Parser used to get general FSM or EpsilonNFA, NFA, DFA from XML parsed into list of Tokens. */ class ContainerFromXMLParser : public sax::FromXMLParserHelper { -public: - bool first(std::list<sax::Token>& input) const; + Container parseContainer(std::list<sax::Token>& input) const; + Container parseContainer(std::list<sax::Token>& input, const std::set<FEATURES>& features) const; template<typename T> std::set<T> parseSet(std::list<sax::Token>& input) const; + ObjectsSet parseObjectsSet(std::list<sax::Token>& input) const; + friend class alib::ObjectFromXMLParser; template<typename T> friend class alib::api; + +public: + bool first(std::list<sax::Token>& input) const; }; } /* namespace container */ diff --git a/alib2data/src/container/ContainerToXMLComposer.cpp b/alib2data/src/container/ContainerToXMLComposer.cpp new file mode 100644 index 0000000000..1aea2bd67b --- /dev/null +++ b/alib2data/src/container/ContainerToXMLComposer.cpp @@ -0,0 +1,25 @@ +/* + * ContainerToXMLComposer.cpp + * + * Created on: Oct 12, 2013 + * Author: Jan Travnicek + */ + +#include "ContainerToXMLComposer.hpp" + +namespace container { + +std::list<sax::Token> ContainerToXMLComposer::compose(const ObjectsSet& container) const { + std::list<sax::Token> out; + out.push_back(sax::Token("set", sax::Token::TokenType::START_ELEMENT)); + + for(const alib::Object& item : container) { + out.splice(out.end(), alib::api<alib::Object>::compose(item)); + } + + out.push_back(sax::Token("set", sax::Token::TokenType::END_ELEMENT)); + return out; +} + +} /* namespace container */ + diff --git a/alib2data/src/container/ContainerToXMLComposer.hpp b/alib2data/src/container/ContainerToXMLComposer.hpp index 0403151185..2deca9412d 100644 --- a/alib2data/src/container/ContainerToXMLComposer.hpp +++ b/alib2data/src/container/ContainerToXMLComposer.hpp @@ -12,6 +12,9 @@ #include <set> #include "../sax/Token.h" +#include "Container.h" +#include "ObjectsSet.h" + namespace alib { template<typename T> @@ -26,8 +29,24 @@ namespace container { */ class ContainerToXMLComposer { 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 ContainerBase& symbol) const; + + /** + * Prints XML representation of String to the output stream. + * @param string String to print + * @param out output stream to which print the String + */ + std::list<sax::Token> compose(const Container& symbol) const; + template<typename T> - std::list<sax::Token> composeSet(const std::set<T>& container) const; + std::list<sax::Token> compose(const std::set<T>& container) const; + + std::list<sax::Token> compose(const ObjectsSet& container) const; template<typename T> friend class alib::api; }; @@ -39,7 +58,7 @@ public: namespace container { template<typename T> -std::list<sax::Token> ContainerToXMLComposer::composeSet(const std::set<T>& container) const { +std::list<sax::Token> ContainerToXMLComposer::compose(const std::set<T>& container) const { std::list<sax::Token> out; out.push_back(sax::Token("set", sax::Token::TokenType::START_ELEMENT)); diff --git a/alib2data/src/container/ObjectsSet.cpp b/alib2data/src/container/ObjectsSet.cpp new file mode 100644 index 0000000000..c127b8a5ad --- /dev/null +++ b/alib2data/src/container/ObjectsSet.cpp @@ -0,0 +1,55 @@ +/* + * Set.cpp + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#include "ObjectsSet.h" +#include "../std/set.hpp" + +#include <cstdlib> +#include <iostream> +#include <sstream> + +namespace container { + +ContainerBase* ObjectsSet::clone() const { + return new ObjectsSet(*this); +} + +ContainerBase* ObjectsSet::plunder() && { + return new ObjectsSet(std::move(*this)); +} + +bool ObjectsSet::operator==(const ObjectBase& other) const { + return other == *this; +} + +bool ObjectsSet::operator<(const ObjectBase& other) const { + return other > *this; +} + +bool ObjectsSet::operator>(const ObjectBase& other) const { + return other < *this; +} + +bool ObjectsSet::operator==(const ObjectsSet& other) const { + return static_cast<const std::set<alib::Object>>(*this) == static_cast<const std::set<alib::Object>>(other); +} + +bool ObjectsSet::operator<(const ObjectsSet& other) const { + return static_cast<const std::set<alib::Object>>(*this) < static_cast<const std::set<alib::Object>>(other); +} + +void ObjectsSet::operator>>(std::ostream& os) const { + os << *this; +} + +ObjectsSet::operator std::string() const { + std::stringstream ss; + ss << *this; + return std::move(ss).str(); +} + +} /* namespace container */ diff --git a/alib2data/src/container/ObjectsSet.h b/alib2data/src/container/ObjectsSet.h new file mode 100644 index 0000000000..a5a98d46f9 --- /dev/null +++ b/alib2data/src/container/ObjectsSet.h @@ -0,0 +1,47 @@ +/* + * Set.h + * + * Created on: Apr 1, 2013 + * Author: Jan Travnicek + */ + +#ifndef SET_H_ +#define SET_H_ + +#include <set> +#include <string> + +#include "../object/Object.h" +#include "ContainerBase.h" + +namespace container { + +/** + * Basic container from which are derived all other containers. + * Contains reason why the container occured. + */ +class ObjectsSet : public std::set<alib::Object>, public std::element<ObjectsSet, ContainerBase> { +public: + virtual ContainerBase* clone() const; + + virtual ContainerBase* plunder() &&; + + virtual bool operator>(const ObjectBase& other) const; + virtual bool operator==(const ObjectBase& other) const; + virtual bool operator<(const ObjectBase& other) const; + + virtual bool operator==(const ObjectsSet& other) const; + virtual bool operator<(const ObjectsSet& other) const; + + virtual void operator>>(std::ostream& os) const; + + virtual operator std::string() const; + + virtual int selfTypeId() const { + return typeId(*this); + } +}; + +} /* namespace container */ + +#endif /* SET_H_ */ diff --git a/alib2data/src/object/Object.h b/alib2data/src/object/Object.h index a41fa5c3f9..842528ea99 100644 --- a/alib2data/src/object/Object.h +++ b/alib2data/src/object/Object.h @@ -8,11 +8,12 @@ #ifndef OBJECT_H_ #define OBJECT_H_ -#include "ObjectBase.h" #include "../common/wrapper.hpp" namespace alib { +class ObjectBase; + /** * Wrapper around object. */ diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index 62015e9d53..c888b34f8c 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -82,6 +82,12 @@ class EndSymbol; } +namespace container { + +class ObjectsSet; + +} + namespace alib { class ObjectBase : @@ -93,7 +99,8 @@ class ObjectBase : label::StringLabel, label::IntegerLabel, label::CharacterLabel, regexp::UnboundedRegExp, regexp::FormalRegExp, string::Epsilon, string::LinearString, string::CyclicString, - alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::EndSymbol + alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::EndSymbol, + container::ObjectsSet >, public std::elementBase< exception::AlibException, @@ -102,7 +109,8 @@ class ObjectBase : label::StringLabel, label::IntegerLabel, label::CharacterLabel, regexp::UnboundedRegExp, regexp::FormalRegExp, string::Epsilon, string::LinearString, string::CyclicString, - alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::EndSymbol + alphabet::LabeledSymbol, alphabet::BlankSymbol, alphabet::BottomOfTheStackSymbol, alphabet::EndSymbol, + container::ObjectsSet > { }; diff --git a/alib2data/src/object/ObjectFromXMLParser.cpp b/alib2data/src/object/ObjectFromXMLParser.cpp index 662f31b3ff..33f387034e 100644 --- a/alib2data/src/object/ObjectFromXMLParser.cpp +++ b/alib2data/src/object/ObjectFromXMLParser.cpp @@ -38,6 +38,9 @@ Object ObjectFromXMLParser::parseObject(std::list<sax::Token>& input) const { } else if(alib::FromXMLParsers::grammarParser.first(input)) { grammar::Grammar grammar = alib::FromXMLParsers::grammarParser.parseGrammar(input); tmp = std::move(grammar.getData()).plunder(); + } else if(alib::FromXMLParsers::containerParser.first(input)) { + container::Container container = alib::FromXMLParsers::containerParser.parseContainer(input); + tmp = std::move(container.getData()).plunder(); } else { throw exception::AlibException("Unknown element in xml"); } diff --git a/alib2data/test-src/container/ContainerTest.cpp b/alib2data/test-src/container/ContainerTest.cpp new file mode 100644 index 0000000000..5d257af03d --- /dev/null +++ b/alib2data/test-src/container/ContainerTest.cpp @@ -0,0 +1,48 @@ +#include <list> +#include "ContainerTest.h" + +#include "sax/SaxParseInterface.h" +#include "sax/SaxComposeInterface.h" + +#include "object/Object.h" +#include "container/ObjectsSet.h" +#include "alphabet/LabeledSymbol.h" + +#include "factory/DataFactory.hpp" + +#include "label/StringLabel.h" +#include "label/Label.h" + +#define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) +#define CPPUNIT_EXCLUSIVE_OR(x, y) CPPUNIT_ASSERT((!(x) && (y)) || ((x) && !(y))) + +CPPUNIT_TEST_SUITE_REGISTRATION( ContainerTest ); + +void ContainerTest::setUp() { +} + +void ContainerTest::tearDown() { +} + +void ContainerTest::testXMLParser() { + + alib::Object tmp(alphabet::LabeledSymbol(label::Label(label::StringLabel("1")))); + + container::ObjectsSet set; + set.insert(tmp); + + alib::Object object(set); + + { + std::string tmp = alib::DataFactory::toString(object); + alib::Object object2 = alib::DataFactory::fromString<alib::Object>(tmp); + + CPPUNIT_ASSERT( object == object2 ); + + std::set<alphabet::LabeledSymbol> concrete = alib::DataFactory::fromString<std::set<alphabet::LabeledSymbol>>(tmp); + std::string tmp2 = alib::DataFactory::toString(concrete); + + CPPUNIT_ASSERT( tmp == tmp2 ); + } +} + diff --git a/alib2data/test-src/container/ContainerTest.h b/alib2data/test-src/container/ContainerTest.h new file mode 100644 index 0000000000..b13ecd5be4 --- /dev/null +++ b/alib2data/test-src/container/ContainerTest.h @@ -0,0 +1,19 @@ +#ifndef CONTAINER_TEST_H_ +#define CONTAINER_TEST_H_ + +#include <cppunit/extensions/HelperMacros.h> + +class ContainerTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( ContainerTest ); + CPPUNIT_TEST( testXMLParser ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void testXMLParser(); +}; + +#endif // CONTAINER_TEST_H_ -- GitLab