diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp index fb89ade3de11afdc731fffcc60283112980273fd..7322aae1c3522fc4999e621b1cb66708c1a0d151 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.cpp @@ -96,6 +96,10 @@ void ExactSubtreeMatch::Visit(void* data, const tree::RankedTree& subject, const res = this->match(subject, pattern); } +void ExactSubtreeMatch::Visit(void*, const tree::RankedPattern&, const tree::RankedPattern&) const { + throw exception::AlibException("Unsupported tree type RankedPattern"); +} + void ExactSubtreeMatch::Visit(void* data, const tree::PrefixRankedNotation& subject, const tree::PrefixRankedNotation& pattern) const { std::set<unsigned> & res = *((std::set<unsigned>*) data); res = this->match(subject, pattern); diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h index de77fa513eece28ba5c45e330fc8adfcef56e17f..b350a48635cf0542459282f0fb3984b3cbb80892 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatch.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatch.h @@ -40,6 +40,7 @@ private: void Visit(void*, const tree::UnrankedTree& subject, const tree::UnrankedTree& pattern) const; 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; static const ExactSubtreeMatch EXACT_SUBTREE_MATCH; diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp index eab632d6db45776a9d868e77da552246d47be769..3b6c9502e9f85c322a3ae2ad0649f0a006c10f10 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.cpp @@ -53,6 +53,10 @@ void ExactSubtreeMatchingAutomaton::Visit(void* data, const tree::PrefixRankedNo out = new automaton::Automaton(this->construct(pattern)); } +void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::RankedPattern&) const { + throw exception::AlibException("Unsupported tree type RankedPattern"); +} + void ExactSubtreeMatchingAutomaton::Visit(void*, const tree::UnrankedTree&) const { throw exception::AlibException("Unsupported tree type UnrankedTree"); } diff --git a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h index 95f4dab3bc8254df8f5ddc1030b97c6956cd09f0..7810129072c51f292a16363c4f08d3d591c07c6d 100644 --- a/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h +++ b/alib2algo/src/arbology/exact/ExactSubtreeMatchingAutomaton.h @@ -29,6 +29,7 @@ public: static automaton::InputDrivenNPDA construct(const tree::PrefixRankedNotation& pattern); private: void Visit(void*, const tree::RankedTree& pattern) const; + void Visit(void*, const tree::RankedPattern& subject) const; void Visit(void*, const tree::PrefixRankedNotation& pattern) const; void Visit(void*, const tree::UnrankedTree& pattern) const; diff --git a/alib2data/src/XmlApi.cpp b/alib2data/src/XmlApi.cpp index 7dec84a15ae1ae12ba02ca9f675ebb73cfccec44..f475913d0727861b14e66ad6d4481ee9e671d957 100644 --- a/alib2data/src/XmlApi.cpp +++ b/alib2data/src/XmlApi.cpp @@ -107,6 +107,7 @@ const std::string Names::PRIMITIVE_CHARACTER = "Character"; const std::string Names::PRIMITIVE_UNSIGNED = "Unsigned"; const std::string Names::PRIMITIVE_BOOL = "Bool"; 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"; @@ -1161,6 +1162,18 @@ void xmlApi<tree::RankedTree>::compose(std::deque<sax::Token>& output, const tre ToXMLComposers::treeComposer.compose(output, data); } +tree::RankedPattern xmlApi<tree::RankedPattern>::parse(std::deque<sax::Token>& input) { + return FromXMLParsers::treeParser.parseRankedPattern(input); +} + +bool xmlApi<tree::RankedPattern>::first(const std::deque<sax::Token>& input) { + return sax::FromXMLParserHelper::isToken(input, sax::Token::TokenType::START_ELEMENT, Names::TREE_RANKED_TREE); +} + +void xmlApi<tree::RankedPattern>::compose(std::deque<sax::Token>& output, const tree::RankedPattern& data) { + ToXMLComposers::treeComposer.compose(output, data); +} + tree::UnrankedTree xmlApi<tree::UnrankedTree>::parse(std::deque<sax::Token>& input) { return FromXMLParsers::treeParser.parseUnrankedTree(input); } @@ -1449,6 +1462,10 @@ void ToXMLComposers::Visit(void* data, const tree::RankedTree& tree) const { xmlApi<tree::RankedTree>::compose(*((std::deque<sax::Token>*) data), tree); } +void ToXMLComposers::Visit(void* data, const tree::RankedPattern& tree) const { + xmlApi<tree::RankedPattern>::compose(*((std::deque<sax::Token>*) data), tree); +} + void ToXMLComposers::Visit(void* data, const tree::PrefixRankedNotation& tree) const { xmlApi<tree::PrefixRankedNotation>::compose(*((std::deque<sax::Token>*) data), tree); } diff --git a/alib2data/src/XmlApi.hpp b/alib2data/src/XmlApi.hpp index 7eb140fe3b7505389019d61a984c41c5e270a1c8..6b646031bc8eeac517669ec455f4b9904279624a 100644 --- a/alib2data/src/XmlApi.hpp +++ b/alib2data/src/XmlApi.hpp @@ -108,6 +108,7 @@ public: const static std::string PRIMITIVE_UNSIGNED; const static std::string PRIMITIVE_BOOL; const static std::string TREE_RANKED_TREE; + const static std::string TREE_RANKED_PATTERN; const static std::string TREE_PREFIX_RANKED_NOTATION; const static std::string TREE_UNRANKED_TREE; @@ -764,6 +765,13 @@ struct xmlApi<tree::RankedTree> { static void compose(std::deque<sax::Token>& output, const tree::RankedTree& data); }; +template<> +struct xmlApi<tree::RankedPattern> { + static tree::RankedPattern 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::RankedPattern& data); +}; + template<> struct xmlApi<tree::PrefixRankedNotation> { static tree::PrefixRankedNotation parse(std::deque<sax::Token>& input); @@ -899,6 +907,7 @@ private: void Visit(void*, const primitive::Bool& primitive) const; void Visit(void*, const tree::RankedTree& tree) const; + void Visit(void*, const tree::RankedPattern& tree) const; void Visit(void*, const tree::PrefixRankedNotation& tree) const; void Visit(void*, const tree::UnrankedTree& tree) const; diff --git a/alib2data/src/object/ObjectBase.h b/alib2data/src/object/ObjectBase.h index 05250ce6755ca87187750c303091c074c020659e..48061a90d03e019fa8d0cb724647f5465cef233d 100644 --- a/alib2data/src/object/ObjectBase.h +++ b/alib2data/src/object/ObjectBase.h @@ -139,6 +139,7 @@ class Bool; namespace tree { class RankedTree; +class RankedPattern; class PrefixRankedNotation; class UnrankedTree; @@ -150,7 +151,7 @@ namespace alib { class ObjectBase; -typedef std::tuple< tree::RankedTree, tree::PrefixRankedNotation, tree::UnrankedTree +typedef std::tuple< tree::RankedTree, tree::RankedPattern, tree::PrefixRankedNotation, tree::UnrankedTree > 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 5021cb77bfc931924cf12aeac79291173c310b1a..d21502e8ea4d2805984144344aadd00145473014 100644 --- a/alib2data/src/tree/TreeFeatures.h +++ b/alib2data/src/tree/TreeFeatures.h @@ -11,7 +11,7 @@ namespace tree { enum class FEATURES { - RANKED_TREE, PREFIX_RANKED_NOTATION, UNRANKED_TREE + RANKED_TREE, RANKED_PATTERN, PREFIX_RANKED_NOTATION, UNRANKED_TREE }; } /* namespace tree */ diff --git a/alib2data/src/tree/TreeFromXMLParser.cpp b/alib2data/src/tree/TreeFromXMLParser.cpp index 1dc3ba23d63d047025a45c3fcc1758940538bf1f..5e89d0da0b7669c9bf4842c7c6d54fa818692ad0 100644 --- a/alib2data/src/tree/TreeFromXMLParser.cpp +++ b/alib2data/src/tree/TreeFromXMLParser.cpp @@ -14,13 +14,16 @@ namespace tree { Tree TreeFromXMLParser::parseTree(std::deque<sax::Token> &input) const { - return parseTree(input, std::set<FEATURES>({FEATURES::RANKED_TREE, FEATURES::UNRANKED_TREE, FEATURES::PREFIX_RANKED_NOTATION})); + return parseTree(input, std::set<FEATURES>({FEATURES::RANKED_TREE, FEATURES::RANKED_PATTERN, FEATURES::UNRANKED_TREE, FEATURES::PREFIX_RANKED_NOTATION})); } Tree TreeFromXMLParser::parseTree(std::deque<sax::Token>& input, const std::set<FEATURES>& features) const { if(alib::xmlApi<RankedTree>::first(input)) { if(!features.count(FEATURES::RANKED_TREE)) throw exception::AlibException(); return Tree(parseRankedTree(input)); + } else if(alib::xmlApi<RankedPattern>::first(input)) { + if(!features.count(FEATURES::RANKED_PATTERN)) throw exception::AlibException(); + return Tree(parseRankedPattern(input)); } else if(alib::xmlApi<UnrankedTree>::first(input)) { if(!features.count(FEATURES::UNRANKED_TREE)) throw exception::AlibException(); return Tree(parseUnrankedTree(input)); @@ -28,7 +31,19 @@ Tree TreeFromXMLParser::parseTree(std::deque<sax::Token>& input, const std::set< if(!features.count(FEATURES::PREFIX_RANKED_NOTATION)) throw exception::AlibException(); return Tree(parsePrefixRankedNotation(input)); } else - throw sax::ParserException(sax::Token("Tree / RankedTree / PrefixRankedNotation / UnrankedTree", sax::Token::TokenType::START_ELEMENT), input.front()); + throw sax::ParserException(sax::Token("Tree / RankedTree / RankedPattern / PrefixRankedNotation / UnrankedTree", 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); + std::set<alphabet::RankedSymbol> rankedAlphabet = parseRankedAlphabet(input); + RankedNode * root = parseRankedNode(input); + RankedPattern tree(subtreeVariable, std::move(rankedAlphabet), std::move(*root)); + delete root; + popToken(input, sax::Token::TokenType::END_ELEMENT, alib::Names::TREE_RANKED_PATTERN); + return tree; } RankedTree TreeFromXMLParser::parseRankedTree(std::deque<sax::Token>& input) const { @@ -64,6 +79,14 @@ UnrankedTree TreeFromXMLParser::parseUnrankedTree(std::deque<sax::Token>& input) return tree; } +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; +} + std::set<alphabet::RankedSymbol> TreeFromXMLParser::parseRankedAlphabet(std::deque<sax::Token> &input) const { std::set<alphabet::RankedSymbol> rankedSymbols; popToken(input, sax::Token::TokenType::START_ELEMENT, "rankedAlphabet"); @@ -121,7 +144,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<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)) { return true; } else { return false; diff --git a/alib2data/src/tree/TreeFromXMLParser.h b/alib2data/src/tree/TreeFromXMLParser.h index 346e3620c33dc488c9010fffaecb55f9de5f78bb..1540a65fba6078aabf90dfd9ed2f878b3a686408 100644 --- a/alib2data/src/tree/TreeFromXMLParser.h +++ b/alib2data/src/tree/TreeFromXMLParser.h @@ -42,10 +42,14 @@ private: std::set<alphabet::RankedSymbol> parseRankedAlphabet(std::deque<sax::Token> &input) const; std::set<alphabet::LabeledSymbol> parseAlphabet(std::deque<sax::Token> &input) const; + template<class T> + T parseSubtreeVariable(std::deque<sax::Token> &input) const; + Tree parseTree(std::deque<sax::Token>& input) const; Tree parseTree(std::deque<sax::Token>& input, const std::set<FEATURES>& features) const; RankedTree parseRankedTree(std::deque<sax::Token>& input) const; + RankedPattern parseRankedPattern(std::deque<sax::Token>& input) const; PrefixRankedNotation parsePrefixRankedNotation(std::deque<sax::Token>& input) const; UnrankedTree parseUnrankedTree(std::deque<sax::Token>& input) const; diff --git a/alib2data/src/tree/TreeToRawComposer.cpp b/alib2data/src/tree/TreeToRawComposer.cpp index b5a664e45b6159c0dcc683fab0760b2d449bbca3..a45c24107231d37e80527958cc67bfee31a234b1 100644 --- a/alib2data/src/tree/TreeToRawComposer.cpp +++ b/alib2data/src/tree/TreeToRawComposer.cpp @@ -6,6 +6,7 @@ */ #include "TreeToRawComposer.h" +#include "TreeException.h" #include "../XmlApi.hpp" @@ -80,6 +81,10 @@ void TreeToRawComposer::Visit(void* userData, const RankedTree& tree) const { this->compose(res, tree); } +void TreeToRawComposer::Visit(void*, const RankedPattern&) const { + throw tree::TreeException("Cant compose RankedPattern to raw representation"); +} + void TreeToRawComposer::Visit(void* userData, const PrefixRankedNotation& tree) const { std::deque<sax::Token> &res = *((std::deque<sax::Token>*) userData); this->compose(res, tree); diff --git a/alib2data/src/tree/TreeToRawComposer.h b/alib2data/src/tree/TreeToRawComposer.h index daf6236121d3c0f3dd9198e61616a6ecc4e4aae4..049c5d5958d0431949ce42ada857f7675f270b7f 100644 --- a/alib2data/src/tree/TreeToRawComposer.h +++ b/alib2data/src/tree/TreeToRawComposer.h @@ -30,9 +30,10 @@ class TreeToRawComposer : public VisitableTreeBase::const_visitor_type { public: TreeToRawComposer() {} - void Visit(void*, const RankedTree& empty) const; - void Visit(void*, const PrefixRankedNotation& empty) const; - void Visit(void*, const UnrankedTree& empty) const; + void Visit(void*, const RankedTree& tree) const; + void Visit(void*, const RankedPattern& tree) const; + void Visit(void*, const PrefixRankedNotation& tree) const; + void Visit(void*, const UnrankedTree& 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 f385fbffd68bce8d8364ba54b42d5a4adb6409b8..637e0d95d1e5bca3a079c08df810c0b399dd994c 100644 --- a/alib2data/src/tree/TreeToXMLComposer.cpp +++ b/alib2data/src/tree/TreeToXMLComposer.cpp @@ -11,6 +11,13 @@ 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)); + alib::xmlApi<T>::compose(out, symbol); + out.emplace_back(sax::Token("subtreeVariable", sax::Token::TokenType::END_ELEMENT)); +} + void TreeToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::RankedSymbol>& symbols) const { out.emplace_back(sax::Token("rankedAlphabet", sax::Token::TokenType::START_ELEMENT)); for (const auto& symbol : symbols) { @@ -44,6 +51,16 @@ void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const RankedTree& t out.emplace_back(sax::Token(alib::Names::TREE_RANKED_TREE, sax::Token::TokenType::END_ELEMENT)); } +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()); + composeAlphabet(out, tree.getAlphabet()); + composeNode(out, tree.getRoot()); + + out.emplace_back(sax::Token(alib::Names::TREE_RANKED_PATTERN, sax::Token::TokenType::END_ELEMENT)); +} + void TreeToXMLComposer::compose(std::deque<sax::Token>& out, const PrefixRankedNotation& tree) const { out.emplace_back(sax::Token(alib::Names::TREE_PREFIX_RANKED_NOTATION, sax::Token::TokenType::START_ELEMENT)); diff --git a/alib2data/src/tree/TreeToXMLComposer.h b/alib2data/src/tree/TreeToXMLComposer.h index 6aed53c6408bf7b4a7f522807cdb4bcc5fed2f98..6a5ccc8db9bd3130438bf53462b64ca4c2e27ed2 100644 --- a/alib2data/src/tree/TreeToXMLComposer.h +++ b/alib2data/src/tree/TreeToXMLComposer.h @@ -12,6 +12,7 @@ #include <deque> #include "Tree.h" #include "ranked/RankedTree.h" +#include "ranked/RankedPattern.h" #include "ranked/PrefixRankedNotation.h" #include "unranked/UnrankedTree.h" #include "../sax/Token.h" @@ -35,6 +36,8 @@ public: 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::LabeledSymbol>& symbols) const; + template<class T> + void composeSubtreeVariable(std::deque<sax::Token>& out, const T& symbol) const; /** * Prints XML representation of Tree to the output stream. @@ -45,6 +48,7 @@ private: void compose(std::deque<sax::Token>& out, const Tree& tree) const; void compose(std::deque<sax::Token>& out, const RankedTree& tree) const; + 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; diff --git a/alib2data/src/tree/common/RankedPatternAlphabet.cpp b/alib2data/src/tree/common/RankedPatternAlphabet.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47ec62595743c7ebdc77520b52b5126f6d275c97 --- /dev/null +++ b/alib2data/src/tree/common/RankedPatternAlphabet.cpp @@ -0,0 +1,32 @@ +/* + * RankedAlphabet.cpp + * + * Created on: Apr 16, 2013 + * Author: Jan Travnicek + */ + +#include "RankedPatternAlphabet.h" +#include "../TreeException.h" + +#include <algorithm> + +namespace tree { + +RankedPatternAlphabet::RankedPatternAlphabet(alphabet::RankedSymbol subtreeVariable) : subtreeVariable(subtreeVariable) { + alphabet.insert(std::move(subtreeVariable)); +} + +void RankedPatternAlphabet::setSubtreeVariable(alphabet::RankedSymbol symbol) { + if (!alphabet.count(symbol)) + throw TreeException("Blank symbol \"" + (std::string) symbol + "\" is not in tape alphabet."); + + subtreeVariable = std::move(symbol); + +} + +const alphabet::RankedSymbol& RankedPatternAlphabet::getSubtreeVariable() const { + return subtreeVariable; +} + +} /* namespace tree */ + diff --git a/alib2data/src/tree/common/RankedPatternAlphabet.h b/alib2data/src/tree/common/RankedPatternAlphabet.h new file mode 100644 index 0000000000000000000000000000000000000000..23c01adca5f390b4c05168baf1fe144284af4618 --- /dev/null +++ b/alib2data/src/tree/common/RankedPatternAlphabet.h @@ -0,0 +1,41 @@ +/* + * RankedPatternAlphabet.h + * + * Created on: Apr 10, 2013 + * Author: Jan Travnicek + */ + +#ifndef RANKED_PATTERN_ALPHABET_H_ +#define RANKED_PATTERN_ALPHABET_H_ + +#include "RankedAlphabet.h" + +namespace tree { + +/** + * Abstract base class for all strings. Contains common elements of strings. + */ +class RankedPatternAlphabet : public RankedAlphabet { +protected: + alphabet::RankedSymbol subtreeVariable; + +public: + RankedPatternAlphabet(alphabet::RankedSymbol subtreeVariable); + + /** + * Sets the subtree variable = symbol representing subtree substitution place in the pattern + * @param symbol Symbol to set + */ + void setSubtreeVariable(alphabet::RankedSymbol symbol); + + /** + * @return symbol representing subtree variable + */ + const alphabet::RankedSymbol& getSubtreeVariable() const; + +}; + +} /* namespace tree */ + +#endif /* RANKED_PATTERN_ALPHABET_H_ */ + diff --git a/alib2data/src/tree/ranked/RankedNode.cpp b/alib2data/src/tree/ranked/RankedNode.cpp index 381eafda14c25016f2f084d166cd0982448be02a..062f0d5af00cdd794e2518aad574b0bbe4b43d14 100644 --- a/alib2data/src/tree/ranked/RankedNode.cpp +++ b/alib2data/src/tree/ranked/RankedNode.cpp @@ -95,8 +95,8 @@ void RankedNode::setSymbol(alphabet::RankedSymbol symbol) { } void RankedNode::swap(RankedNode& other) { - const RankedTree* thisParentTree = this->parentTree; - const RankedTree* otherParentTree = other.parentTree; + const RankedAlphabet* thisParentTree = this->parentTree; + const RankedAlphabet* otherParentTree = other.parentTree; RankedNode tmp = std::move(other); other = std::move(*this); @@ -153,7 +153,7 @@ bool RankedNode::testSymbol( const alphabet::RankedSymbol & symbol ) const { return symbol == this->symbol; } -bool RankedNode::attachTree(const RankedTree * tree ) { +bool RankedNode::attachTree(const RankedAlphabet * tree ) { if(this->parentTree == tree) return true; this->parentTree = tree; diff --git a/alib2data/src/tree/ranked/RankedNode.h b/alib2data/src/tree/ranked/RankedNode.h index 235d22a29913c767f3694b76dda6e2754fbbe091..36f8e1620255d737401781f9d0df10e12af4119e 100644 --- a/alib2data/src/tree/ranked/RankedNode.h +++ b/alib2data/src/tree/ranked/RankedNode.h @@ -12,6 +12,7 @@ #include "../../alphabet/RankedSymbol.h" #include <vector> #include <set> +#include "../common/RankedAlphabet.h" namespace tree { @@ -29,9 +30,9 @@ protected: RankedNode* parent; /** - * Parent tree contanining this instance of RegExpElement + * Parent tree contanining this instance of RankedTree */ - const RankedTree * parentTree; + const RankedAlphabet * parentTree; /** * @copydoc RankedNode::cloneAsUnranked() const @@ -46,7 +47,7 @@ protected: /** * @copydoc RankedNode::attachTree() */ - bool attachTree ( const RankedTree * tree ); + bool attachTree ( const RankedAlphabet * tree ); /** * @copydoc RankedNode::computeMinimalAlphabet() @@ -109,6 +110,7 @@ public: friend class UnrankedTree; friend class RankedTree; + friend class RankedPattern; }; } /* namespace tree */ diff --git a/alib2data/src/tree/ranked/RankedPattern.cpp b/alib2data/src/tree/ranked/RankedPattern.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8bfcfd33e76db021e49f37d5e05949eff8e84123 --- /dev/null +++ b/alib2data/src/tree/ranked/RankedPattern.cpp @@ -0,0 +1,131 @@ +/* + * RankedPattern.cpp + * + * Created on: Nov 23, 2013 + * Author: Stepan Plachy + */ + +#include "RankedPattern.h" +#include "../../exception/AlibException.h" + +#include <iostream> +#include <algorithm> +#include <sstream> + +//#include "../unranked/UnrankedPattern.h" + +namespace tree { + +/*RankedPattern::RankedPattern(const UnrankedPattern& other) { + this->pattern = NULL; + RankedNode* element = other.getRoot().cloneAsRanked(); + element->computeMinimalAlphabet(alphabet); + setTree(std::move(*element)); + delete element; +}*/ + +RankedPattern::RankedPattern(alphabet::RankedSymbol subtreeVariable, std::set<alphabet::RankedSymbol> alphabet, RankedNode pattern) : RankedPatternAlphabet(std::move(subtreeVariable)) { + setAlphabet(std::move(alphabet)); + this->pattern = NULL; + setTree(std::move(pattern)); +} + +RankedPattern::RankedPattern(alphabet::RankedSymbol subtreeVariable, RankedNode pattern) : RankedPatternAlphabet(std::move(subtreeVariable)) { + pattern.computeMinimalAlphabet(alphabet); + this->pattern = NULL; + setTree(std::move(pattern)); +} + +RankedPattern::RankedPattern(const RankedPattern& other) : RankedPatternAlphabet(other), pattern(other.pattern->clone()) { + this->pattern->attachTree(this); +} + +RankedPattern::RankedPattern(RankedPattern&& other) noexcept : RankedPatternAlphabet(other), pattern(other.pattern) { + this->pattern->attachTree(this); + other.pattern = NULL; +} + +TreeBase* RankedPattern::clone() const { + return new RankedPattern(*this); +} + +TreeBase* RankedPattern::plunder() && { + return new RankedPattern(std::move(*this)); +} + +RankedPattern& RankedPattern::operator=(const RankedPattern& other) { + if (this == &other) { + return *this; + } + + *this = RankedPattern(other); + + return *this; +} + +RankedPattern& RankedPattern::operator=(RankedPattern&& other) noexcept { + std::swap(this->pattern, other.pattern); + std::swap(this->alphabet, other.alphabet); + std::swap(this->subtreeVariable, other.subtreeVariable); + return *this; +} + +RankedPattern::~RankedPattern() noexcept { + delete pattern; +} + +const RankedNode& RankedPattern::getRoot() const { + return *pattern; +} + +RankedNode& RankedPattern::getRoot() { + return *pattern; +} + +void RankedPattern::setTree(RankedNode 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 RankedPattern::removeSymbolFromAlphabet(const alphabet::RankedSymbol & symbol) { + 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."); + + return alphabet.erase(symbol); +} + +void RankedPattern::operator >>(std::ostream& out) const { + out << "(RankedPattern " << *(this->pattern) << ")"; +} + +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); + } + if(res == 0) { + std::compare<std::set<alphabet::RankedSymbol>> comp; + res = comp(alphabet, other.alphabet); + } + return res; +} + +void RankedPattern::nicePrint(std::ostream & os) const { + pattern -> nicePrint(os); +} + +RankedPattern::operator std::string () const { + std::stringstream ss; + ss << *this; + return ss.str(); +} + +} /* namespace tree */ diff --git a/alib2data/src/tree/ranked/RankedPattern.h b/alib2data/src/tree/ranked/RankedPattern.h new file mode 100644 index 0000000000000000000000000000000000000000..d80fb4a2cb453a867a883584d73723821944b2f5 --- /dev/null +++ b/alib2data/src/tree/ranked/RankedPattern.h @@ -0,0 +1,113 @@ +/* + * RankedPattern.h + * + * Created on: Nov 23, 2013 + * Author: Stepan Plachy + */ + +#ifndef RANKED_PATTERN_H_ +#define RANKED_PATTERN_H_ + +#include <vector> +#include <list> +#include <string> +#include <set> +#include "RankedNode.h" +#include "../TreeBase.h" +#include "../common/RankedPatternAlphabet.h" + +namespace tree { + +class RankedNode; + +/** + * Represents regular expression parsed from the XML. Regular expression is stored + * as a pattern of RegExpElement. + */ +class RankedPattern : public std::acceptor<RankedPattern, VisitableTreeBase, std::acceptor<RankedPattern, alib::VisitableObjectBase, TreeBase> >, public RankedPatternAlphabet { +protected: + RankedNode* pattern; + +public: + /** + * @copydoc RankedNode::clone() const + */ + virtual TreeBase* clone() const; + + /** + * @copydoc RankedNode::plunder() const + */ + 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); + + /** + * Copy constructor. + * @param other pattern to copy + */ + RankedPattern(const RankedPattern& other); + RankedPattern(RankedPattern&& other) noexcept; + RankedPattern& operator =(const RankedPattern& other); + RankedPattern& operator =(RankedPattern&& other) noexcept; + ~RankedPattern() noexcept; + + /** + * @return Root node of the regular expression pattern + */ + const RankedNode& getRoot() const; + + /** + * @return Root node of the regular expression pattern + */ + RankedNode& getRoot(); + + /** + * Sets the root node of the regular expression pattern + * @param pattern root node to set + */ + void setTree(RankedNode pattern); + + /** + * Removes symbol from the alphabet of symbol available in the regular expression + * @param symbol removed symbol from the alphabet + */ + bool removeSymbolFromAlphabet(const alphabet::RankedSymbol & 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 RankedPattern& 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::RankedPattern> { + int operator()(const tree::RankedPattern& first, const tree::RankedPattern& second) const { + return first.compare(second); + } +}; + +} /* namespace std */ + +#endif /* RANKED_PATTERN_H_ */ diff --git a/alib2data/src/tree/unranked/UnrankedNode.cpp b/alib2data/src/tree/unranked/UnrankedNode.cpp index 6013ea8c4b1e8321486d24c235a89120172244bd..0f28b7e6e0f2c205d49c7623d44dc46fc40ed5ff 100644 --- a/alib2data/src/tree/unranked/UnrankedNode.cpp +++ b/alib2data/src/tree/unranked/UnrankedNode.cpp @@ -97,8 +97,8 @@ void UnrankedNode::pushBackChild(const UnrankedNode & node) { } void UnrankedNode::swap(UnrankedNode& other) { - const UnrankedTree* thisParentTree = this->parentTree; - const UnrankedTree* otherParentTree = other.parentTree; + const UnrankedAlphabet* thisParentTree = this->parentTree; + const UnrankedAlphabet* otherParentTree = other.parentTree; UnrankedNode tmp = std::move(other); other = std::move(*this); @@ -155,7 +155,7 @@ bool UnrankedNode::testSymbol( const alphabet::LabeledSymbol & symbol ) const { return symbol == this->symbol; } -bool UnrankedNode::attachTree(const UnrankedTree * tree ) { +bool UnrankedNode::attachTree(const UnrankedAlphabet * tree ) { if(this->parentTree == tree) return true; this->parentTree = tree; diff --git a/alib2data/src/tree/unranked/UnrankedNode.h b/alib2data/src/tree/unranked/UnrankedNode.h index e947a0d9858282a127199d4259eb607ffa87df75..d9d33cc1929df8991b0fff0c40c94818f1fc55eb 100644 --- a/alib2data/src/tree/unranked/UnrankedNode.h +++ b/alib2data/src/tree/unranked/UnrankedNode.h @@ -12,6 +12,7 @@ #include "../../alphabet/RankedSymbol.h" #include <vector> #include <set> +#include "../common/UnrankedAlphabet.h" namespace tree { @@ -31,7 +32,7 @@ protected: /** * Parent tree contanining this instance of RegExpElement */ - const UnrankedTree * parentTree; + const UnrankedAlphabet * parentTree; /** * @copydoc UnrankedNode::cloneAsUnranked() const @@ -46,7 +47,7 @@ protected: /** * @copydoc UnrankedNode::attachTree() */ - bool attachTree ( const UnrankedTree * tree ); + bool attachTree ( const UnrankedAlphabet * tree ); /** * @copydoc UnrankedNode::computeMinimalAlphabet() diff --git a/alib2data/src/tree/unranked/UnrankedTree.cpp b/alib2data/src/tree/unranked/UnrankedTree.cpp index cd3d1ebe768e1096cfaf6057305e025b57c5cf9d..4f7ac90f3499a7898f268e575fc285b45ad68b0d 100644 --- a/alib2data/src/tree/unranked/UnrankedTree.cpp +++ b/alib2data/src/tree/unranked/UnrankedTree.cpp @@ -25,7 +25,7 @@ UnrankedTree::UnrankedTree(const RankedTree& other) { } UnrankedTree::UnrankedTree(std::set<alphabet::LabeledSymbol> alphabet, UnrankedNode tree) { - this->alphabet = std::move(alphabet); + setAlphabet(std::move(alphabet)); this->tree = NULL; setTree(std::move(tree)); } diff --git a/alib2data/test-src/tree/TreeTest.cpp b/alib2data/test-src/tree/TreeTest.cpp index 4003a5ceca3dda9893f5c0f16b3f71190fc62a3f..d79f1e779a4b85be40d48a8bddca33ec04ee5b01 100644 --- a/alib2data/test-src/tree/TreeTest.cpp +++ b/alib2data/test-src/tree/TreeTest.cpp @@ -4,6 +4,7 @@ #include "sax/SaxComposeInterface.h" #include "tree/ranked/RankedTree.h" +#include "tree/ranked/RankedPattern.h" #include "tree/TreeException.h" @@ -375,3 +376,35 @@ void TreeTest::testUnrankedTreeSubtreeSwitch() { CPPUNIT_ASSERT(tree4 == tree1Copy); } +void TreeTest::testRankedPatternParser() { + const alphabet::RankedSymbol a ('a', 2); + const alphabet::RankedSymbol b ('b', 1); + const alphabet::RankedSymbol c ('c', 0); + + const alphabet::RankedSymbol S ('S', 0); + const std::set<alphabet::RankedSymbol> alphabet {a, b, c, S}; + + tree::RankedNode * node3 = new tree::RankedNode(c, {}); + tree::RankedNode * node4 = new tree::RankedNode(S, {}); + tree::RankedNode * node2 = new tree::RankedNode(b, {node3}); + tree::RankedNode node1(a, {node2, node4}); + + tree::RankedPattern 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::RankedPattern tree2 = alib::XmlDataFactory::fromTokens<tree::RankedPattern>(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 842c4a60183fed811bedfceb67fd2be0fcc63f0e..ba03a6d218af232364a49dfc9b68d8d80d497f90 100644 --- a/alib2data/test-src/tree/TreeTest.h +++ b/alib2data/test-src/tree/TreeTest.h @@ -14,6 +14,7 @@ class TreeTest : public CppUnit::TestFixture CPPUNIT_TEST( testUnrankedTreeCompare ); CPPUNIT_TEST( testUnrankedTreeSymbolValidityCheck ); CPPUNIT_TEST( testUnrankedTreeSubtreeSwitch ); + CPPUNIT_TEST( testRankedPatternParser ); CPPUNIT_TEST_SUITE_END(); public: @@ -29,6 +30,8 @@ public: void testUnrankedTreeCompare(); void testUnrankedTreeSymbolValidityCheck(); void testUnrankedTreeSubtreeSwitch(); + + void testRankedPatternParser(); }; #endif // TREE_TEST_H_