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