From b29da92674d7b58edec23844ac01f326bf5bffbe Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Sun, 24 May 2015 23:36:55 +0200 Subject: [PATCH] +UnrankedPattern --- .../src/arbology/exact/ExactSubtreeMatch.cpp | 4 + .../src/arbology/exact/ExactSubtreeMatch.h | 1 + .../exact/ExactSubtreeMatchingAutomaton.cpp | 4 + .../exact/ExactSubtreeMatchingAutomaton.h | 1 + alib2data/src/XmlApi.cpp | 17 +++ alib2data/src/XmlApi.hpp | 9 ++ alib2data/src/alphabet/RankedSymbol.cpp | 4 + alib2data/src/alphabet/RankedSymbol.h | 1 + alib2data/src/object/ObjectBase.h | 3 +- alib2data/src/tree/TreeFeatures.h | 2 +- alib2data/src/tree/TreeFromXMLParser.cpp | 33 +++-- alib2data/src/tree/TreeFromXMLParser.h | 1 + alib2data/src/tree/TreeToRawComposer.cpp | 4 + alib2data/src/tree/TreeToRawComposer.h | 1 + alib2data/src/tree/TreeToXMLComposer.cpp | 18 ++- alib2data/src/tree/TreeToXMLComposer.h | 4 +- .../src/tree/common/RankedPatternAlphabet.cpp | 14 +- .../src/tree/common/RankedPatternAlphabet.h | 8 +- .../tree/common/UnrankedPatternAlphabet.cpp | 32 +++++ .../src/tree/common/UnrankedPatternAlphabet.h | 41 ++++++ alib2data/src/tree/ranked/RankedPattern.cpp | 14 +- alib2data/src/tree/ranked/RankedPattern.h | 6 +- alib2data/src/tree/unranked/UnrankedNode.h | 1 + .../src/tree/unranked/UnrankedPattern.cpp | 131 ++++++++++++++++++ alib2data/src/tree/unranked/UnrankedPattern.h | 113 +++++++++++++++ alib2data/test-src/tree/TreeTest.cpp | 35 ++++- alib2data/test-src/tree/TreeTest.h | 2 + 27 files changed, 466 insertions(+), 38 deletions(-) create mode 100644 alib2data/src/tree/common/UnrankedPatternAlphabet.cpp create mode 100644 alib2data/src/tree/common/UnrankedPatternAlphabet.h create mode 100644 alib2data/src/tree/unranked/UnrankedPattern.cpp create mode 100644 alib2data/src/tree/unranked/UnrankedPattern.h diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp index 7322aae1c3..51eb253753 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp @@ -105,6 +105,10 @@ void ExactSubtreeMatch::Visit(void* data, const tree::PrefixRankedNotation& subj res = this->match(subject, pattern); } +void ExactSubtreeMatch::Visit(void*, const tree::UnrankedPattern&, const tree::UnrankedPattern&) const { + throw exception::AlibException("Unsupported tree type UnrankedPattern"); +} + const ExactSubtreeMatch ExactSubtreeMatch::EXACT_SUBTREE_MATCH; } /* namespace exact */ diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h index b350a48635..ba76c43842 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h @@ -42,6 +42,7 @@ private: void Visit(void*, const tree::RankedTree& subject, const tree::RankedTree& pattern) const; void Visit(void*, const tree::RankedPattern& subject, const tree::RankedPattern& pattern) const; void Visit(void*, const tree::PrefixRankedNotation& subject, const tree::PrefixRankedNotation& pattern) const; + void Visit(void*, const tree::UnrankedPattern& subject, const tree::UnrankedPattern& pattern) const; static const ExactSubtreeMatch EXACT_SUBTREE_MATCH; }; diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp index 3b6c9502e9..b47a60a222 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp @@ -61,6 +61,10 @@ void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::UnrankedTree&) cons throw exception::AlibException("Unsupported tree type UnrankedTree"); } +void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::UnrankedPattern&) const { + throw exception::AlibException("Unsupported tree type UnrankedPattern"); +} + const ExactSubtreeMatchingAutomaton ExactSubtreeMatchingAutomaton::EXACT_SUBTREE_MATCHING_AUTOMATON; } /* namespace exact */ diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h index 7810129072..bcc68f34b3 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h @@ -32,6 +32,7 @@ private: void Visit(void*, const tree::RankedPattern& subject) const; void Visit(void*, const tree::PrefixRankedNotation& pattern) const; void Visit(void*, const tree::UnrankedTree& pattern) const; + void Visit(void*, const tree::UnrankedPattern& subject) const; static const ExactSubtreeMatchingAutomaton EXACT_SUBTREE_MATCHING_AUTOMATON; }; diff --git a/alib2data/src/XmlApi.cpp b/alib2data/src/XmlApi.cpp index f769107bcd..5a4a733da8 100644 --- a/alib2data/src/XmlApi.cpp +++ b/alib2data/src/XmlApi.cpp @@ -109,6 +109,7 @@ const std::string Names::TREE_RANKED_TREE = "RankedTree"; const std::string Names::TREE_RANKED_PATTERN = "RankedPattern"; const std::string Names::TREE_PREFIX_RANKED_NOTATION = "PrefixRankedNotation"; const std::string Names::TREE_UNRANKED_TREE = "UnrankedTree"; +const std::string Names::TREE_UNRANKED_PATTERN = "UnrankedPattern"; Void xmlApi<Void>::parse(std::deque<sax::Token>& input) { return FromXMLParsers::objectParser.parseVoid(input); @@ -1173,6 +1174,18 @@ void xmlApi<tree::UnrankedTree>::compose(std::deque<sax::Token>& output, const t ToXMLComposers::treeComposer.compose(output, data); } +tree::UnrankedPattern xmlApi<tree::UnrankedPattern>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::treeParser.parseUnrankedPattern(input); +} + +bool xmlApi<tree::UnrankedPattern>::first(const std::deque<sax::Token>& input) { + return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, Names::TREE_UNRANKED_TREE); +} + +void xmlApi<tree::UnrankedPattern>::compose(std::deque<sax::Token>& output, const tree::UnrankedPattern& data) { + ToXMLComposers::treeComposer.compose(output, data); +} + void ToXMLComposers::Visit(void* data, const Void& voidObject) const { xmlApi<Void>::compose(*((std::deque<sax::Token>*) data), voidObject); } @@ -1457,4 +1470,8 @@ void ToXMLComposers::Visit(void* data, const tree::UnrankedTree& tree) const { xmlApi<tree::UnrankedTree>::compose(*((std::deque<sax::Token>*) data), tree); } +void ToXMLComposers::Visit(void* data, const tree::UnrankedPattern& tree) const { + xmlApi<tree::UnrankedPattern>::compose(*((std::deque<sax::Token>*) data), tree); +} + } /* namespace alib */ diff --git a/alib2data/src/XmlApi.hpp b/alib2data/src/XmlApi.hpp index 8fed15d19e..42df224eac 100644 --- a/alib2data/src/XmlApi.hpp +++ b/alib2data/src/XmlApi.hpp @@ -110,6 +110,7 @@ public: const static std::string TREE_RANKED_PATTERN; const static std::string TREE_PREFIX_RANKED_NOTATION; const static std::string TREE_UNRANKED_TREE; + const static std::string TREE_UNRANKED_PATTERN; }; @@ -778,6 +779,13 @@ struct xmlApi<tree::UnrankedTree> { static void compose(std::deque<sax::Token>& output, const tree::UnrankedTree& data); }; +template<> +struct xmlApi<tree::UnrankedPattern> { + static tree::UnrankedPattern parse(std::deque<sax::Token>& input); + static bool first(const std::deque<sax::Token>& input); + static void compose(std::deque<sax::Token>& output, const tree::UnrankedPattern& data); +}; + } /* namespace alib */ #include "container/ContainerFromXMLParser.hpp" @@ -901,6 +909,7 @@ private: void Visit(void*, const tree::RankedPattern& tree) const; void Visit(void*, const tree::PrefixRankedNotation& tree) const; void Visit(void*, const tree::UnrankedTree& tree) const; + void Visit(void*, const tree::UnrankedPattern& tree) const; public: static const label::LabelToXMLComposer labelComposer; diff --git a/alib2data/src/alphabet/RankedSymbol.cpp b/alib2data/src/alphabet/RankedSymbol.cpp index 68f30a69cc..284e2367eb 100644 --- a/alib2data/src/alphabet/RankedSymbol.cpp +++ b/alib2data/src/alphabet/RankedSymbol.cpp @@ -25,6 +25,10 @@ RankedSymbol::RankedSymbol(alphabet::Symbol symbol, primitive::Unsigned rank) : } +RankedSymbol::RankedSymbol(alphabet::Symbol symbol, int rank) : symbol(std::move(symbol)), rank(primitive::Unsigned(rank)) { + +} + SymbolBase* RankedSymbol::clone() const { return new RankedSymbol(*this); } diff --git a/alib2data/src/alphabet/RankedSymbol.h b/alib2data/src/alphabet/RankedSymbol.h index f9ccfe08f8..3d053b037d 100644 --- a/alib2data/src/alphabet/RankedSymbol.h +++ b/alib2data/src/alphabet/RankedSymbol.h @@ -35,6 +35,7 @@ public: * @param rank of the symbol */ explicit RankedSymbol(alphabet::Symbol symbol, primitive::Unsigned rank); + explicit RankedSymbol(alphabet::Symbol symbol, int rank); virtual SymbolBase* clone() const; virtual SymbolBase* plunder() &&; diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index eebd4da7ae..c5ca3a2d39 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -141,6 +141,7 @@ class RankedTree; class RankedPattern; class PrefixRankedNotation; class UnrankedTree; +class UnrankedPattern; } @@ -150,7 +151,7 @@ namespace alib { class ObjectBase; -typedef std::tuple< tree::RankedTree, tree::RankedPattern, tree::PrefixRankedNotation, tree::UnrankedTree +typedef std::tuple< tree::RankedTree, tree::RankedPattern, tree::PrefixRankedNotation, tree::UnrankedTree, tree::UnrankedPattern > TreeTypes; typedef std::tuple< primitive::String, primitive::Integer, primitive::Character, primitive::Unsigned, primitive::Bool diff --git a/alib2data/src/tree/TreeFeatures.h b/alib2data/src/tree/TreeFeatures.h index d21502e8ea..5aafc5bf79 100644 --- a/alib2data/src/tree/TreeFeatures.h +++ b/alib2data/src/tree/TreeFeatures.h @@ -11,7 +11,7 @@ namespace tree { enum class FEATURES { - RANKED_TREE, RANKED_PATTERN, PREFIX_RANKED_NOTATION, UNRANKED_TREE + RANKED_TREE, RANKED_PATTERN, PREFIX_RANKED_NOTATION, UNRANKED_TREE, UNRANKED_PATTERN }; } /* namespace tree */ diff --git a/alib2data/src/tree/TreeFromXMLParser.cpp b/alib2data/src/tree/TreeFromXMLParser.cpp index 033ff79de9..620c218400 100644 --- a/alib2data/src/tree/TreeFromXMLParser.cpp +++ b/alib2data/src/tree/TreeFromXMLParser.cpp @@ -14,7 +14,7 @@ namespace tree { Tree TreeFromXMLParser::parseTree(std::deque<sax::Token> &input) const { - return parseTree(input, std::set<FEATURES>({FEATURES::RANKED_TREE, FEATURES::RANKED_PATTERN, FEATURES::UNRANKED_TREE, FEATURES::PREFIX_RANKED_NOTATION})); + return parseTree(input, std::set<FEATURES>({FEATURES::RANKED_TREE, FEATURES::RANKED_PATTERN, FEATURES::UNRANKED_TREE, FEATURES::UNRANKED_PATTERN, FEATURES::PREFIX_RANKED_NOTATION})); } Tree TreeFromXMLParser::parseTree(std::deque<sax::Token>& input, const std::set<FEATURES>& features) const { @@ -27,20 +27,23 @@ Tree TreeFromXMLParser::parseTree(std::deque<sax::Token>& input, const std::set< } else if(alib::xmlApi<UnrankedTree>::first(input)) { if(!features.count(FEATURES::UNRANKED_TREE)) throw exception::AlibException(); return Tree(parseUnrankedTree(input)); + } else if(alib::xmlApi<UnrankedPattern>::first(input)) { + if(!features.count(FEATURES::UNRANKED_PATTERN)) throw exception::AlibException(); + return Tree(parseUnrankedPattern(input)); } else if(alib::xmlApi<PrefixRankedNotation>::first(input)) { if(!features.count(FEATURES::PREFIX_RANKED_NOTATION)) throw exception::AlibException(); return Tree(parsePrefixRankedNotation(input)); } else - throw sax::ParserException(sax::Token("Tree / RankedTree / RankedPattern / PrefixRankedNotation / UnrankedTree", sax::Token::TokenType::START_ELEMENT), input.front()); + throw sax::ParserException(sax::Token("Tree / RankedTree / RankedPattern / PrefixRankedNotation / UnrankedTree / UnrankedPattern", sax::Token::TokenType::START_ELEMENT), input.front()); } RankedPattern TreeFromXMLParser::parseRankedPattern(std::deque<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::TREE_RANKED_PATTERN); - alphabet::RankedSymbol subtreeVariable = parseSubtreeVariable<alphabet::RankedSymbol>(input); + alphabet::RankedSymbol subtreeWildcard = parseSubtreeVariable<alphabet::RankedSymbol>(input); std::set<alphabet::RankedSymbol> rankedAlphabet = parseRankedAlphabet(input); RankedNode * root = parseRankedNode(input); - RankedPattern tree(subtreeVariable, std::move(rankedAlphabet), std::move(*root)); + RankedPattern tree(subtreeWildcard, std::move(rankedAlphabet), std::move(*root)); delete root; popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::TREE_RANKED_PATTERN); return tree; @@ -68,6 +71,18 @@ PrefixRankedNotation TreeFromXMLParser::parsePrefixRankedNotation(std::deque<sax return tree; } +UnrankedPattern TreeFromXMLParser::parseUnrankedPattern(std::deque<sax::Token>& input) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::TREE_UNRANKED_PATTERN); + + alphabet::Symbol subtreeWildcard = parseSubtreeVariable<alphabet::Symbol>(input); + std::set<alphabet::Symbol> alphabet = parseAlphabet(input); + UnrankedNode * root = parseUnrankedNode(input); + UnrankedPattern tree(subtreeWildcard, std::move(alphabet), std::move(*root)); + delete root; + popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::TREE_UNRANKED_PATTERN); + return tree; +} + UnrankedTree TreeFromXMLParser::parseUnrankedTree(std::deque<sax::Token>& input) const { popToken(input, sax::Token::TokenType::START_ELEMENT, alib::Names::TREE_UNRANKED_TREE); @@ -81,10 +96,10 @@ UnrankedTree TreeFromXMLParser::parseUnrankedTree(std::deque<sax::Token>& input) template<class T> T TreeFromXMLParser::parseSubtreeVariable(std::deque<sax::Token>& input) const { - popToken(input, sax::Token::TokenType::START_ELEMENT, "subtreeVariable"); - alphabet::RankedSymbol subtreeVariable(alib::xmlApi<T>::parse(input)); - popToken(input, sax::Token::TokenType::END_ELEMENT, "subtreeVariable"); - return subtreeVariable; + popToken(input, sax::Token::TokenType::START_ELEMENT, "subtreeWildcard"); + T subtreeWildcard(alib::xmlApi<T>::parse(input)); + popToken(input, sax::Token::TokenType::END_ELEMENT, "subtreeWildcard"); + return subtreeWildcard; } std::set<alphabet::RankedSymbol> TreeFromXMLParser::parseRankedAlphabet(std::deque<sax::Token> &input) const { @@ -144,7 +159,7 @@ UnrankedNode * TreeFromXMLParser::parseUnrankedNode(std::deque<sax::Token> &inpu } bool TreeFromXMLParser::first(const std::deque<sax::Token>& input) const { - if (alib::xmlApi<RankedTree>::first(input) || alib::xmlApi<RankedPattern>::first(input) || alib::xmlApi<PrefixRankedNotation>::first(input) || alib::xmlApi<UnrankedTree>::first(input)) { + if (alib::xmlApi<RankedTree>::first(input) || alib::xmlApi<RankedPattern>::first(input) || alib::xmlApi<PrefixRankedNotation>::first(input) || alib::xmlApi<UnrankedTree>::first(input) || alib::xmlApi<UnrankedPattern>::first(input)) { return true; } else { return false; diff --git a/alib2data/src/tree/TreeFromXMLParser.h b/alib2data/src/tree/TreeFromXMLParser.h index c3d9452443..c354e33626 100644 --- a/alib2data/src/tree/TreeFromXMLParser.h +++ b/alib2data/src/tree/TreeFromXMLParser.h @@ -52,6 +52,7 @@ private: RankedPattern parseRankedPattern(std::deque<sax::Token>& input) const; PrefixRankedNotation parsePrefixRankedNotation(std::deque<sax::Token>& input) const; UnrankedTree parseUnrankedTree(std::deque<sax::Token>& input) const; + UnrankedPattern parseUnrankedPattern(std::deque<sax::Token>& input) const; template<typename T> friend struct alib::xmlApi; public: diff --git a/alib2data/src/tree/TreeToRawComposer.cpp b/alib2data/src/tree/TreeToRawComposer.cpp index a45c241072..c70ae6b0d9 100644 --- a/alib2data/src/tree/TreeToRawComposer.cpp +++ b/alib2data/src/tree/TreeToRawComposer.cpp @@ -95,6 +95,10 @@ void TreeToRawComposer::Visit(void* userData, const UnrankedTree& tree) const { this->compose(res, tree); } +void TreeToRawComposer::Visit(void*, const UnrankedPattern&) const { + throw tree::TreeException("Cant compose UnrankedPattern to raw representation"); +} + const TreeToRawComposer TreeToRawComposer::TREE_TO_RAW_COMPOSER; } /* namespace automaton */ diff --git a/alib2data/src/tree/TreeToRawComposer.h b/alib2data/src/tree/TreeToRawComposer.h index 049c5d5958..3d61de4201 100644 --- a/alib2data/src/tree/TreeToRawComposer.h +++ b/alib2data/src/tree/TreeToRawComposer.h @@ -34,6 +34,7 @@ public: void Visit(void*, const RankedPattern& tree) const; void Visit(void*, const PrefixRankedNotation& tree) const; void Visit(void*, const UnrankedTree& tree) const; + void Visit(void*, const UnrankedPattern& tree) const; void compose(std::deque<sax::Token>& out, const Tree& tree) const; diff --git a/alib2data/src/tree/TreeToXMLComposer.cpp b/alib2data/src/tree/TreeToXMLComposer.cpp index 4127e0bb6f..9aa599b44d 100644 --- a/alib2data/src/tree/TreeToXMLComposer.cpp +++ b/alib2data/src/tree/TreeToXMLComposer.cpp @@ -12,10 +12,10 @@ namespace tree { template<class T> -void TreeToXMLComposer::composeSubtreeVariable(std::deque<sax::Token>& out, const T& symbol) const { - out.emplace_back(sax::Token("subtreeVariable", sax::Token::TokenType::START_ELEMENT)); +void TreeToXMLComposer::composeSubtreeWildCard(std::deque<sax::Token>& out, const T& symbol) const { + out.emplace_back(sax::Token("subtreeWildcard", sax::Token::TokenType::START_ELEMENT)); alib::xmlApi<T>::compose(out, symbol); - out.emplace_back(sax::Token("subtreeVariable", sax::Token::TokenType::END_ELEMENT)); + out.emplace_back(sax::Token("subtreeWildcard", sax::Token::TokenType::END_ELEMENT)); } void TreeToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::RankedSymbol>& symbols) const { @@ -54,7 +54,7 @@ void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const RankedTree& t void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const RankedPattern& tree) const { out.emplace_back(sax::Token(alib::Names::TREE_RANKED_PATTERN, sax::Token::TokenType::START_ELEMENT)); - composeSubtreeVariable(out, tree.getSubtreeVariable()); + composeSubtreeWildCard(out, tree.getSubtreeWildCard()); composeAlphabet(out, tree.getAlphabet()); composeNode(out, tree.getRoot()); @@ -83,6 +83,16 @@ void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const UnrankedTree& out.emplace_back(sax::Token(alib::Names::TREE_UNRANKED_TREE, sax::Token::TokenType::END_ELEMENT)); } +void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const UnrankedPattern& tree) const { + out.emplace_back(sax::Token(alib::Names::TREE_UNRANKED_PATTERN, sax::Token::TokenType::START_ELEMENT)); + + composeSubtreeWildCard(out, tree.getSubtreeWildCard()); + composeAlphabet(out, tree.getAlphabet()); + composeNode(out, tree.getRoot()); + + out.emplace_back(sax::Token(alib::Names::TREE_UNRANKED_PATTERN, sax::Token::TokenType::END_ELEMENT)); +} + void TreeToXMLComposer::composeNode(std::deque<sax::Token>& out, const RankedNode& node) const { out.emplace_back(sax::Token("rankedNode", sax::Token::TokenType::START_ELEMENT)); alib::xmlApi<alphabet::RankedSymbol>::compose(out, node.getSymbol()); diff --git a/alib2data/src/tree/TreeToXMLComposer.h b/alib2data/src/tree/TreeToXMLComposer.h index 6fa6d8c812..deeed832b0 100644 --- a/alib2data/src/tree/TreeToXMLComposer.h +++ b/alib2data/src/tree/TreeToXMLComposer.h @@ -15,6 +15,7 @@ #include "ranked/RankedPattern.h" #include "ranked/PrefixRankedNotation.h" #include "unranked/UnrankedTree.h" +#include "unranked/UnrankedPattern.h" #include "../sax/Token.h" namespace alib { @@ -37,7 +38,7 @@ private: void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::RankedSymbol>& symbols) const; void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::Symbol>& symbols) const; template<class T> - void composeSubtreeVariable(std::deque<sax::Token>& out, const T& symbol) const; + void composeSubtreeWildCard(std::deque<sax::Token>& out, const T& symbol) const; /** * Prints XML representation of Tree to the output stream. @@ -51,6 +52,7 @@ private: void compose(std::deque<sax::Token>& out, const RankedPattern& tree) const; void compose(std::deque<sax::Token>& out, const PrefixRankedNotation& tree) const; void compose(std::deque<sax::Token>& out, const UnrankedTree& tree) const; + void compose(std::deque<sax::Token>& out, const UnrankedPattern& tree) const; void composeNode(std::deque<sax::Token>& out, const RankedNode& node) const; void composeNode(std::deque<sax::Token>& out, const UnrankedNode& node) const; diff --git a/alib2data/src/tree/common/RankedPatternAlphabet.cpp b/alib2data/src/tree/common/RankedPatternAlphabet.cpp index 47ec625957..30720fb67f 100644 --- a/alib2data/src/tree/common/RankedPatternAlphabet.cpp +++ b/alib2data/src/tree/common/RankedPatternAlphabet.cpp @@ -12,20 +12,20 @@ namespace tree { -RankedPatternAlphabet::RankedPatternAlphabet(alphabet::RankedSymbol subtreeVariable) : subtreeVariable(subtreeVariable) { - alphabet.insert(std::move(subtreeVariable)); +RankedPatternAlphabet::RankedPatternAlphabet(alphabet::RankedSymbol subtreeWildcard) : subtreeWildcard(subtreeWildcard) { + alphabet.insert(std::move(subtreeWildcard)); } -void RankedPatternAlphabet::setSubtreeVariable(alphabet::RankedSymbol symbol) { +void RankedPatternAlphabet::setSubtreeWildCard(alphabet::RankedSymbol symbol) { if (!alphabet.count(symbol)) - throw TreeException("Blank symbol \"" + (std::string) symbol + "\" is not in tape alphabet."); + throw TreeException("Subtree wildcard symbol \"" + (std::string) symbol + "\" is not in the alphabet."); - subtreeVariable = std::move(symbol); + subtreeWildcard = std::move(symbol); } -const alphabet::RankedSymbol& RankedPatternAlphabet::getSubtreeVariable() const { - return subtreeVariable; +const alphabet::RankedSymbol& RankedPatternAlphabet::getSubtreeWildCard() const { + return subtreeWildcard; } } /* namespace tree */ diff --git a/alib2data/src/tree/common/RankedPatternAlphabet.h b/alib2data/src/tree/common/RankedPatternAlphabet.h index 23c01adca5..c174b33674 100644 --- a/alib2data/src/tree/common/RankedPatternAlphabet.h +++ b/alib2data/src/tree/common/RankedPatternAlphabet.h @@ -17,21 +17,21 @@ namespace tree { */ class RankedPatternAlphabet : public RankedAlphabet { protected: - alphabet::RankedSymbol subtreeVariable; + alphabet::RankedSymbol subtreeWildcard; public: - RankedPatternAlphabet(alphabet::RankedSymbol subtreeVariable); + RankedPatternAlphabet(alphabet::RankedSymbol subtreeWildcard); /** * Sets the subtree variable = symbol representing subtree substitution place in the pattern * @param symbol Symbol to set */ - void setSubtreeVariable(alphabet::RankedSymbol symbol); + void setSubtreeWildCard(alphabet::RankedSymbol symbol); /** * @return symbol representing subtree variable */ - const alphabet::RankedSymbol& getSubtreeVariable() const; + const alphabet::RankedSymbol& getSubtreeWildCard() const; }; diff --git a/alib2data/src/tree/common/UnrankedPatternAlphabet.cpp b/alib2data/src/tree/common/UnrankedPatternAlphabet.cpp new file mode 100644 index 0000000000..31bd6c3fdc --- /dev/null +++ b/alib2data/src/tree/common/UnrankedPatternAlphabet.cpp @@ -0,0 +1,32 @@ +/* + * UnrankedAlphabet.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "UnrankedPatternAlphabet.h" +#include "../TreeException.h" + +#include <algorithm> + +namespace tree { + +UnrankedPatternAlphabet::UnrankedPatternAlphabet(alphabet::Symbol subtreeWildcard) : subtreeWildcard(subtreeWildcard) { + alphabet.insert(std::move(subtreeWildcard)); +} + +void UnrankedPatternAlphabet::setSubtreeWildCard(alphabet::Symbol symbol) { + if (!alphabet.count(symbol)) + throw TreeException("Subtree wildcard symbol \"" + (std::string) symbol + "\" is not in the alphabet."); + + subtreeWildcard = std::move(symbol); + +} + +const alphabet::Symbol& UnrankedPatternAlphabet::getSubtreeWildCard() const { + return subtreeWildcard; +} + +} /* namespace tree */ + diff --git a/alib2data/src/tree/common/UnrankedPatternAlphabet.h b/alib2data/src/tree/common/UnrankedPatternAlphabet.h new file mode 100644 index 0000000000..6843852264 --- /dev/null +++ b/alib2data/src/tree/common/UnrankedPatternAlphabet.h @@ -0,0 +1,41 @@ +/* + * UnrankedPatternAlphabet.h + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#ifndef UNRANKED_PATTERN_ALPHABET_H_ +#define UNRANKED_PATTERN_ALPHABET_H_ + +#include "UnrankedAlphabet.h" + +namespace tree { + +/** + * Abstract base class for all strings. Contains common elements of strings. + */ +class UnrankedPatternAlphabet : public UnrankedAlphabet { +protected: + alphabet::Symbol subtreeWildcard; + +public: + UnrankedPatternAlphabet(alphabet::Symbol subtreeWildcard); + + /** + * Sets the subtree variable = symbol representing subtree substitution place in the pattern + * @param symbol Symbol to set + */ + void setSubtreeWildCard(alphabet::Symbol symbol); + + /** + * @return symbol representing subtree variable + */ + const alphabet::Symbol& getSubtreeWildCard() const; + +}; + +} /* namespace tree */ + +#endif /* UNRANKED_PATTERN_ALPHABET_H_ */ + diff --git a/alib2data/src/tree/ranked/RankedPattern.cpp b/alib2data/src/tree/ranked/RankedPattern.cpp index 8bfcfd33e7..9e46a13755 100644 --- a/alib2data/src/tree/ranked/RankedPattern.cpp +++ b/alib2data/src/tree/ranked/RankedPattern.cpp @@ -2,7 +2,7 @@ * RankedPattern.cpp * * Created on: Nov 23, 2013 - * Author: Stepan Plachy + * Author: Jan Travnicek */ #include "RankedPattern.h" @@ -24,13 +24,13 @@ namespace tree { delete element; }*/ -RankedPattern::RankedPattern(alphabet::RankedSymbol subtreeVariable, std::set<alphabet::RankedSymbol> alphabet, RankedNode pattern) : RankedPatternAlphabet(std::move(subtreeVariable)) { +RankedPattern::RankedPattern(alphabet::RankedSymbol subtreeWildcard, std::set<alphabet::RankedSymbol> alphabet, RankedNode pattern) : RankedPatternAlphabet(std::move(subtreeWildcard)) { setAlphabet(std::move(alphabet)); this->pattern = NULL; setTree(std::move(pattern)); } -RankedPattern::RankedPattern(alphabet::RankedSymbol subtreeVariable, RankedNode pattern) : RankedPatternAlphabet(std::move(subtreeVariable)) { +RankedPattern::RankedPattern(alphabet::RankedSymbol subtreeWildcard, RankedNode pattern) : RankedPatternAlphabet(std::move(subtreeWildcard)) { pattern.computeMinimalAlphabet(alphabet); this->pattern = NULL; setTree(std::move(pattern)); @@ -66,7 +66,7 @@ RankedPattern& RankedPattern::operator=(const RankedPattern& other) { RankedPattern& RankedPattern::operator=(RankedPattern&& other) noexcept { std::swap(this->pattern, other.pattern); std::swap(this->alphabet, other.alphabet); - std::swap(this->subtreeVariable, other.subtreeVariable); + std::swap(this->subtreeWildcard, other.subtreeWildcard); return *this; } @@ -95,8 +95,8 @@ bool RankedPattern::removeSymbolFromAlphabet(const alphabet::RankedSymbol & symb if(this->pattern->testSymbol(symbol)) throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); - if(this->subtreeVariable == symbol) - throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is subtreeVariable."); + if(this->subtreeWildcard == symbol) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is subtreeWildcard."); return alphabet.erase(symbol); } @@ -109,7 +109,7 @@ int RankedPattern::compare(const RankedPattern& other) const { int res = pattern->compare(*other.pattern); if(res == 0) { std::compare<alphabet::RankedSymbol> comp; - res = comp(subtreeVariable, other.subtreeVariable); + res = comp(subtreeWildcard, other.subtreeWildcard); } if(res == 0) { std::compare<std::set<alphabet::RankedSymbol>> comp; diff --git a/alib2data/src/tree/ranked/RankedPattern.h b/alib2data/src/tree/ranked/RankedPattern.h index d80fb4a2cb..d807b8e4b0 100644 --- a/alib2data/src/tree/ranked/RankedPattern.h +++ b/alib2data/src/tree/ranked/RankedPattern.h @@ -2,7 +2,7 @@ * RankedPattern.h * * Created on: Nov 23, 2013 - * Author: Stepan Plachy + * Author: Jan Travnicek */ #ifndef RANKED_PATTERN_H_ @@ -40,8 +40,8 @@ public: virtual TreeBase* plunder() &&; // explicit RankedPattern(const UnrankedPattern& other); - explicit RankedPattern(alphabet::RankedSymbol subtreeVariable, std::set<alphabet::RankedSymbol> alphabet, RankedNode pattern); - explicit RankedPattern(alphabet::RankedSymbol subtreeVariable, RankedNode pattern); + explicit RankedPattern(alphabet::RankedSymbol subtreeWildcard, std::set<alphabet::RankedSymbol> alphabet, RankedNode pattern); + explicit RankedPattern(alphabet::RankedSymbol subtreeWildcard, RankedNode pattern); /** * Copy constructor. diff --git a/alib2data/src/tree/unranked/UnrankedNode.h b/alib2data/src/tree/unranked/UnrankedNode.h index 2183265ff0..3acbdc64be 100644 --- a/alib2data/src/tree/unranked/UnrankedNode.h +++ b/alib2data/src/tree/unranked/UnrankedNode.h @@ -111,6 +111,7 @@ public: void nicePrint(std::ostream &, const std::string & = "", const bool = true) const; friend class UnrankedTree; + friend class UnrankedPattern; friend class RankedTree; }; diff --git a/alib2data/src/tree/unranked/UnrankedPattern.cpp b/alib2data/src/tree/unranked/UnrankedPattern.cpp new file mode 100644 index 0000000000..9ab01b3f6e --- /dev/null +++ b/alib2data/src/tree/unranked/UnrankedPattern.cpp @@ -0,0 +1,131 @@ +/* + * UnrankedPattern.cpp + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#include "UnrankedPattern.h" +#include "../../exception/AlibException.h" + +#include <iostream> +#include <algorithm> +#include <sstream> + +//#include "../unranked/RankedPattern.h" + +namespace tree { + +/*UnrankedPattern::UnrankedPattern(const RankedPattern& other) { + this->pattern = NULL; + UnrankedNode* element = other.getRoot().cloneAsRanked(); + element->computeMinimalAlphabet(alphabet); + setTree(std::move(*element)); + delete element; +}*/ + +UnrankedPattern::UnrankedPattern(alphabet::Symbol subtreeWildcard, std::set<alphabet::Symbol> alphabet, UnrankedNode pattern) : UnrankedPatternAlphabet(std::move(subtreeWildcard)) { + setAlphabet(std::move(alphabet)); + this->pattern = NULL; + setTree(std::move(pattern)); +} + +UnrankedPattern::UnrankedPattern(alphabet::Symbol subtreeWildcard, UnrankedNode pattern) : UnrankedPatternAlphabet(std::move(subtreeWildcard)) { + pattern.computeMinimalAlphabet(alphabet); + this->pattern = NULL; + setTree(std::move(pattern)); +} + +UnrankedPattern::UnrankedPattern(const UnrankedPattern& other) : UnrankedPatternAlphabet(other), pattern(other.pattern->clone()) { + this->pattern->attachTree(this); +} + +UnrankedPattern::UnrankedPattern(UnrankedPattern&& other) noexcept : UnrankedPatternAlphabet(other), pattern(other.pattern) { + this->pattern->attachTree(this); + other.pattern = NULL; +} + +TreeBase* UnrankedPattern::clone() const { + return new UnrankedPattern(*this); +} + +TreeBase* UnrankedPattern::plunder() && { + return new UnrankedPattern(std::move(*this)); +} + +UnrankedPattern& UnrankedPattern::operator=(const UnrankedPattern& other) { + if (this == &other) { + return *this; + } + + *this = UnrankedPattern(other); + + return *this; +} + +UnrankedPattern& UnrankedPattern::operator=(UnrankedPattern&& other) noexcept { + std::swap(this->pattern, other.pattern); + std::swap(this->alphabet, other.alphabet); + std::swap(this->subtreeWildcard, other.subtreeWildcard); + return *this; +} + +UnrankedPattern::~UnrankedPattern() noexcept { + delete pattern; +} + +const UnrankedNode& UnrankedPattern::getRoot() const { + return *pattern; +} + +UnrankedNode& UnrankedPattern::getRoot() { + return *pattern; +} + +void UnrankedPattern::setTree(UnrankedNode pattern) { + delete this->pattern; + this->pattern = std::move(pattern).plunder(); + if(!this->pattern->attachTree(this)) { + delete this->pattern; + throw exception::AlibException("Input symbols not in the alphabet."); + } +} + +bool UnrankedPattern::removeSymbolFromAlphabet(const alphabet::Symbol & symbol) { + if(this->pattern->testSymbol(symbol)) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is used."); + + if(this->subtreeWildcard == symbol) + throw exception::AlibException("Input symbol \"" + (std::string) symbol + "\" is subtreeWildcard."); + + return alphabet.erase(symbol); +} + +void UnrankedPattern::operator >>(std::ostream& out) const { + out << "(UnrankedPattern " << *(this->pattern) << ")"; +} + +int UnrankedPattern::compare(const UnrankedPattern& other) const { + int res = pattern->compare(*other.pattern); + if(res == 0) { + std::compare<alphabet::Symbol> comp; + res = comp(subtreeWildcard, other.subtreeWildcard); + } + if(res == 0) { + std::compare<std::set<alphabet::Symbol>> comp; + res = comp(alphabet, other.alphabet); + } + return res; +} + +void UnrankedPattern::nicePrint(std::ostream & os) const { + pattern -> nicePrint(os); +} + +UnrankedPattern::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/unranked/UnrankedPattern.h b/alib2data/src/tree/unranked/UnrankedPattern.h new file mode 100644 index 0000000000..d671ae5282 --- /dev/null +++ b/alib2data/src/tree/unranked/UnrankedPattern.h @@ -0,0 +1,113 @@ +/* + * UnrankedPattern.h + * + * Created on: Nov 23, 2013 + * Author: Jan Travnicek + */ + +#ifndef UNRANKED_PATTERN_H_ +#define UNRANKED_PATTERN_H_ + +#include <vector> +#include <list> +#include <string> +#include <set> +#include "UnrankedNode.h" +#include "../TreeBase.h" +#include "../common/UnrankedPatternAlphabet.h" + +namespace tree { + +class UnrankedNode; + +/** + * Represents regular expression parsed from the XML. Regular expression is stored + * as a pattern of RegExpElement. + */ +class UnrankedPattern : public std::acceptor<UnrankedPattern, VisitableTreeBase, std::acceptor<UnrankedPattern, alib::VisitableObjectBase, TreeBase> >, public UnrankedPatternAlphabet { +protected: + UnrankedNode* pattern; + +public: + /** + * @copydoc UnrankedNode::clone() const + */ + virtual TreeBase* clone() const; + + /** + * @copydoc UnrankedNode::plunder() const + */ + virtual TreeBase* plunder() &&; + +// explicit UnrankedPattern(const RankedPattern& other); + explicit UnrankedPattern(alphabet::Symbol subtreeWildcard, std::set<alphabet::Symbol> alphabet, UnrankedNode pattern); + explicit UnrankedPattern(alphabet::Symbol subtreeWildcard, UnrankedNode pattern); + + /** + * Copy constructor. + * @param other pattern to copy + */ + UnrankedPattern(const UnrankedPattern& other); + UnrankedPattern(UnrankedPattern&& other) noexcept; + UnrankedPattern& operator =(const UnrankedPattern& other); + UnrankedPattern& operator =(UnrankedPattern&& other) noexcept; + ~UnrankedPattern() noexcept; + + /** + * @return Root node of the regular expression pattern + */ + const UnrankedNode& getRoot() const; + + /** + * @return Root node of the regular expression pattern + */ + UnrankedNode& getRoot(); + + /** + * Sets the root node of the regular expression pattern + * @param pattern root node to set + */ + void setTree(UnrankedNode pattern); + + /** + * Removes symbol from the alphabet of symbol available in the regular expression + * @param symbol removed symbol from the alphabet + */ + bool removeSymbolFromAlphabet(const alphabet::Symbol & symbol); + + /** + * Prints XML representation of the pattern to the output stream. + * @param out output stream to which print the pattern + * @param pattern pattern to print + */ + virtual void operator>>(std::ostream& out) const; + + virtual int compare(const ObjectBase& other) const { + return -other.compare(*this); + } + + virtual int compare(const UnrankedPattern& other) const; + + void nicePrint(std::ostream & os) const; + + virtual explicit operator std::string() const; + + virtual int selfTypeId() const { + return typeId(*this); + } +}; + +} /* namespace tree */ + +namespace std { + +template<> +struct compare<tree::UnrankedPattern> { + int operator()(const tree::UnrankedPattern& first, const tree::UnrankedPattern& second) const { + return first.compare(second); + } +}; + +} /* namespace std */ + +#endif /* UNRANKED_PATTERN_H_ */ diff --git a/alib2data/test-src/tree/TreeTest.cpp b/alib2data/test-src/tree/TreeTest.cpp index 2c9d910974..59c0516f0b 100644 --- a/alib2data/test-src/tree/TreeTest.cpp +++ b/alib2data/test-src/tree/TreeTest.cpp @@ -11,6 +11,7 @@ #include "factory/XmlDataFactory.hpp" #include "alphabet/RankedSymbol.h" +#include "alphabet/SubtreeWildcardSymbol.h" #define CPPUNIT_IMPLY(x, y) CPPUNIT_ASSERT(!(x) || (y)) @@ -381,7 +382,7 @@ void TreeTest::testRankedPatternParser() { const alphabet::RankedSymbol b ('b', 1); const alphabet::RankedSymbol c ('c', 0); - const alphabet::RankedSymbol S ('S', 0); + const alphabet::RankedSymbol S (alphabet::Symbol { alphabet::SubtreeWildcardSymbol {} }, 0); const std::set<alphabet::RankedSymbol> alphabet {a, b, c, S}; tree::RankedNode * node3 = new tree::RankedNode(c, {}); @@ -408,3 +409,35 @@ void TreeTest::testRankedPatternParser() { } } +void TreeTest::testUnrankedPatternParser() { + const alphabet::Symbol a = alphabet::symbolFrom('a'); + const alphabet::Symbol b = alphabet::symbolFrom('b'); + const alphabet::Symbol c = alphabet::symbolFrom('c'); + + const alphabet::Symbol S { alphabet::SubtreeWildcardSymbol {} }; + const std::set<alphabet::Symbol> alphabet {a, b, c, S}; + + tree::UnrankedNode * node3 = new tree::UnrankedNode(c, {}); + tree::UnrankedNode * node4 = new tree::UnrankedNode(S, {}); + tree::UnrankedNode * node2 = new tree::UnrankedNode(b, {node3}); + tree::UnrankedNode node1(a, {node2, node4}); + + tree::UnrankedPattern tree(S, alphabet, std::move(node1)); + + CPPUNIT_ASSERT( tree == tree ); + tree.getRoot().nicePrint(std::cout); + { + std::deque<sax::Token> tokens = alib::XmlDataFactory::toTokens(tree); + std::string tmp; + sax::SaxComposeInterface::printMemory(tmp, tokens); + + std::deque<sax::Token> tokens2; + sax::SaxParseInterface::parseMemory(tmp, tokens2); + tree::UnrankedPattern tree2 = alib::XmlDataFactory::fromTokens<tree::UnrankedPattern>(tokens2); + + CPPUNIT_ASSERT( tree == tree2 ); + std::cout << std::endl; + tree2.getRoot().nicePrint(std::cout); + } +} + diff --git a/alib2data/test-src/tree/TreeTest.h b/alib2data/test-src/tree/TreeTest.h index ba03a6d218..71d0cb4096 100644 --- a/alib2data/test-src/tree/TreeTest.h +++ b/alib2data/test-src/tree/TreeTest.h @@ -15,6 +15,7 @@ class TreeTest : public CppUnit::TestFixture CPPUNIT_TEST( testUnrankedTreeSymbolValidityCheck ); CPPUNIT_TEST( testUnrankedTreeSubtreeSwitch ); CPPUNIT_TEST( testRankedPatternParser ); + CPPUNIT_TEST( testUnrankedPatternParser ); CPPUNIT_TEST_SUITE_END(); public: @@ -32,6 +33,7 @@ public: void testUnrankedTreeSubtreeSwitch(); void testRankedPatternParser(); + void testUnrankedPatternParser(); }; #endif // TREE_TEST_H_ -- GitLab