From 40ad032e8cd6d13ed27853d1660c1091a65d4472 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sun, 20 Sep 2015 21:28:21 +0200
Subject: [PATCH] parse trees from string representation

---
 aconvert2/src/aconvert.cpp                 | 274 +++++++++++----------
 alib2str/src/StringApi.cpp                 |  73 +++---
 alib2str/src/StringApi.hpp                 |  79 +++---
 alib2str/src/tree/TreeFromStringLexer.cpp  |  90 +++++++
 alib2str/src/tree/TreeFromStringLexer.h    |  34 +++
 alib2str/src/tree/TreeFromStringParser.cpp | 103 ++++++++
 alib2str/src/tree/TreeFromStringParser.h   |  44 ++++
 alib2str/src/tree/TreeToStringComposer.cpp |  18 ++
 alib2str/src/tree/TreeToStringComposer.h   |  40 +++
 9 files changed, 562 insertions(+), 193 deletions(-)
 create mode 100644 alib2str/src/tree/TreeFromStringLexer.cpp
 create mode 100644 alib2str/src/tree/TreeFromStringLexer.h
 create mode 100644 alib2str/src/tree/TreeFromStringParser.cpp
 create mode 100644 alib2str/src/tree/TreeFromStringParser.h
 create mode 100644 alib2str/src/tree/TreeToStringComposer.cpp
 create mode 100644 alib2str/src/tree/TreeToStringComposer.h

diff --git a/aconvert2/src/aconvert.cpp b/aconvert2/src/aconvert.cpp
index f1369ee304..1989751617 100644
--- a/aconvert2/src/aconvert.cpp
+++ b/aconvert2/src/aconvert.cpp
@@ -8,7 +8,6 @@
 #include <tclap/CmdLine.h>
 #include <fstream>
 
-#include "automaton/Automaton.h"
 #include "factory/XmlDataFactory.hpp"
 #include "factory/StringDataFactory.hpp"
 #include "exception/AlibException.h"
@@ -16,199 +15,224 @@
 #include "DotConverter.h"
 #include "GasTexConverter.h"
 
-void automatonFromString(std::istream& in, std::ostream& out) {
-	automaton::Automaton automaton = alib::StringDataFactory::fromStream<automaton::Automaton>(in);
+void automatonFromString ( std::istream & in, std::ostream & out ) {
+	automaton::Automaton automaton = alib::StringDataFactory::fromStream < automaton::Automaton > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::XmlDataFactory::toStream( automaton, out);
+	alib::XmlDataFactory::toStream ( automaton, out );
 }
 
-void grammarFromString(std::istream& in, std::ostream& out) {
-	grammar::Grammar grammar = alib::StringDataFactory::fromStream<grammar::Grammar>(in);
+void grammarFromString ( std::istream & in, std::ostream & out ) {
+	grammar::Grammar grammar = alib::StringDataFactory::fromStream < grammar::Grammar > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::XmlDataFactory::toStream( grammar, out);
+	alib::XmlDataFactory::toStream ( grammar, out );
 }
 
-void regexpFromString(std::istream& in, std::ostream& out) {
-	regexp::RegExp regexp = alib::StringDataFactory::fromStream<regexp::RegExp>(in);
+void regexpFromString ( std::istream & in, std::ostream & out ) {
+	regexp::RegExp regexp = alib::StringDataFactory::fromStream < regexp::RegExp > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::XmlDataFactory::toStream( regexp, out );
+	alib::XmlDataFactory::toStream ( regexp, out );
 }
 
-void stringFromString(std::istream& in, std::ostream& out) {
-	string::String string = alib::StringDataFactory::fromStream<string::String>(in);
+void stringFromString ( std::istream & in, std::ostream & out ) {
+	string::String string = alib::StringDataFactory::fromStream < string::String > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::XmlDataFactory::toStream(string, out);
+	alib::XmlDataFactory::toStream ( string, out );
 }
 
-void automatonToString(std::istream& in, std::ostream& out) {
-	automaton::Automaton automaton = alib::XmlDataFactory::fromStream<automaton::Automaton>(in);
+void treeFromString ( std::istream & in, std::ostream & out ) {
+	tree::Tree tree = alib::StringDataFactory::fromStream < tree::Tree > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::StringDataFactory::toStream( automaton, out);
+	alib::XmlDataFactory::toStream ( tree, out );
 }
 
-void grammarToString(std::istream& in, std::ostream& out) {
-	grammar::Grammar grammar = alib::XmlDataFactory::fromStream<grammar::Grammar>(in);
+void automatonToString ( std::istream & in, std::ostream & out ) {
+	automaton::Automaton automaton = alib::XmlDataFactory::fromStream < automaton::Automaton > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::StringDataFactory::toStream( grammar, out);
+	alib::StringDataFactory::toStream ( automaton, out );
 }
 
-void regexpToString(std::istream& in, std::ostream& out) {
-	regexp::RegExp regexp = alib::XmlDataFactory::fromStream<regexp::RegExp>(in);
+void grammarToString ( std::istream & in, std::ostream & out ) {
+	grammar::Grammar grammar = alib::XmlDataFactory::fromStream < grammar::Grammar > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::StringDataFactory::toStream( regexp, out);
+	alib::StringDataFactory::toStream ( grammar, out );
 }
 
-void stringToString(std::istream& in, std::ostream& out) {
-	string::String string = alib::XmlDataFactory::fromStream<string::String>(in);
+void regexpToString ( std::istream & in, std::ostream & out ) {
+	regexp::RegExp regexp = alib::XmlDataFactory::fromStream < regexp::RegExp > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	alib::StringDataFactory::toStream( string, out);
+	alib::StringDataFactory::toStream ( regexp, out );
 }
 
-void automatonToDot(std::istream& in, std::ostream& out) {
-	automaton::Automaton automaton = alib::XmlDataFactory::fromStream<automaton::Automaton>(in);
+void stringToString ( std::istream & in, std::ostream & out ) {
+	string::String string = alib::XmlDataFactory::fromStream < string::String > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	DotConverter::convert(out, automaton);
+	alib::StringDataFactory::toStream ( string, out );
 }
 
-void automatonToGasTex(std::istream& in, std::ostream& out) {
-	automaton::Automaton automaton = alib::XmlDataFactory::fromStream<automaton::Automaton>(in);
+void treeToString ( std::istream & in, std::ostream & out ) {
+	tree::Tree tree = alib::XmlDataFactory::fromStream < tree::Tree > ( in );
 
-	std::chrono::measurements::end();
-	std::chrono::measurements::start("Output write", std::chrono::measurements::Type::AUXILARY);
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
 
-	GasTexConverter::convert(out, automaton);
+	alib::StringDataFactory::toStream ( tree, out );
 }
 
-int main(int argc, char* argv[]) {
+void automatonToDot ( std::istream & in, std::ostream & out ) {
+	automaton::Automaton automaton = alib::XmlDataFactory::fromStream < automaton::Automaton > ( in );
+
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
+
+	DotConverter::convert ( out, automaton );
+}
+
+void automatonToGasTex ( std::istream & in, std::ostream & out ) {
+	automaton::Automaton automaton = alib::XmlDataFactory::fromStream < automaton::Automaton > ( in );
+
+	std::chrono::measurements::end ( );
+	std::chrono::measurements::start ( "Output write", std::chrono::measurements::Type::AUXILARY );
+
+	GasTexConverter::convert ( out, automaton );
+}
+
+int main ( int argc, char * argv[] ) {
 	try {
-		TCLAP::CmdLine cmd("Convert binary", ' ', "0.01");
+		TCLAP::CmdLine cmd ( "Convert binary", ' ', "0.01" );
 
-		TCLAP::SwitchArg automaton_from_string(	"", "automaton_from_string",	"Convert automaton from string representation");
-		cmd.add( automaton_from_string );
+		TCLAP::SwitchArg automaton_from_string ( "", "automaton_from_string", "Convert automaton from string representation" );
+		cmd.add ( automaton_from_string );
 
-		TCLAP::SwitchArg automaton_to_string(	"", "automaton_to_string",	"Convert automaton to string representation");
-		cmd.add( automaton_to_string );
+		TCLAP::SwitchArg automaton_to_string ( "", "automaton_to_string", "Convert automaton to string representation" );
+		cmd.add ( automaton_to_string );
 
-		TCLAP::SwitchArg automaton_to_dot(	"", "automaton_to_dot",		"Convert automaton to dot representation");
-		cmd.add( automaton_to_dot );
+		TCLAP::SwitchArg automaton_to_dot ( "", "automaton_to_dot", "Convert automaton to dot representation" );
+		cmd.add ( automaton_to_dot );
 
-		TCLAP::SwitchArg automaton_to_gastex(	"", "automaton_to_gastex",	"Convert automaton to gastex representation");
-		cmd.add( automaton_to_gastex );
+		TCLAP::SwitchArg automaton_to_gastex ( "", "automaton_to_gastex", "Convert automaton to gastex representation" );
+		cmd.add ( automaton_to_gastex );
 
-		TCLAP::SwitchArg grammar_from_string(	"", "grammar_from_string",	"Convert grammar from string representation");
-		cmd.add( grammar_from_string );
+		TCLAP::SwitchArg grammar_from_string ( "", "grammar_from_string", "Convert grammar from string representation" );
+		cmd.add ( grammar_from_string );
 
-		TCLAP::SwitchArg grammar_to_string(	"", "grammar_to_string",	"Convert grammar to string representation");
-		cmd.add( grammar_to_string );
+		TCLAP::SwitchArg grammar_to_string ( "", "grammar_to_string", "Convert grammar to string representation" );
+		cmd.add ( grammar_to_string );
 
-		TCLAP::SwitchArg regexp_from_string(	"", "regexp_from_string",	"Convert regexp from string representation");
-		cmd.add( regexp_from_string );
+		TCLAP::SwitchArg regexp_from_string ( "", "regexp_from_string", "Convert regexp from string representation" );
+		cmd.add ( regexp_from_string );
 
-		TCLAP::SwitchArg regexp_to_string(	"", "regexp_to_string",		"Convert regexp to string representation");
-		cmd.add( regexp_to_string );
+		TCLAP::SwitchArg regexp_to_string ( "", "regexp_to_string", "Convert regexp to string representation" );
+		cmd.add ( regexp_to_string );
 
-		TCLAP::SwitchArg string_from_string(	"", "string_from_string",	"Convert string from string representation");
-		cmd.add( string_from_string );
+		TCLAP::SwitchArg string_from_string ( "", "string_from_string", "Convert string from string representation" );
+		cmd.add ( string_from_string );
 
-		TCLAP::SwitchArg string_to_string(	"","string_to_string",		"Convert string to string representation");
-		cmd.add( string_to_string );
+		TCLAP::SwitchArg string_to_string ( "", "string_to_string", "Convert string to string representation" );
+		cmd.add ( string_to_string );
 
-		TCLAP::ValueArg<std::string> input(	"i", "input", "Input file", false, "-", "file");
-		cmd.add( input );
+		TCLAP::SwitchArg tree_from_string ( "", "tree_from_string", "Convert tree from string representation" );
+		cmd.add ( tree_from_string );
 
-		TCLAP::SwitchArg measure(		"m",	"measure",	"Measure times",		false);
-		cmd.add( measure );
+		TCLAP::SwitchArg tree_to_string ( "", "tree_to_string", "Convert tree to string representation" );
+		cmd.add ( tree_to_string );
 
-		TCLAP::SwitchArg verbose(		"v",	"verbose",	"Be verbose",			false);
-		cmd.add( verbose );
+		TCLAP::ValueArg < std::string > input ( "i", "input", "Input file", false, "-", "file" );
+		cmd.add ( input );
 
-		cmd.parse(argc, argv);
+		TCLAP::SwitchArg measure ( "m", "measure", "Measure times", false );
+		cmd.add ( measure );
 
-		std::chrono::measurements::start("Overal", std::chrono::measurements::Type::OVERALL);
-		std::chrono::measurements::start("Input read", std::chrono::measurements::Type::AUXILARY);
+		TCLAP::SwitchArg verbose ( "v", "verbose", "Be verbose", false );
+		cmd.add ( verbose );
 
-		std::istream* in = NULL;
-		if(input.isSet()) {
-			if(input.getValue() == "-") {
-				in = &std::cin;
-			} else {
-				in = new std::ifstream(input.getValue());
-			}
-		} else {
-			in = &std::cin;
-		}
+		cmd.parse ( argc, argv );
+
+		std::chrono::measurements::start ( "Overal", std::chrono::measurements::Type::OVERALL );
+		std::chrono::measurements::start ( "Input read", std::chrono::measurements::Type::AUXILARY );
+
+		std::istream * in = NULL;
 
-		if(automaton_from_string.getValue()) {
-			automatonFromString(*in, std::cout);
-		} else if(automaton_to_string.getValue()) {
-			automatonToString(*in, std::cout);
-		} else if(automaton_to_dot.getValue()) {
-			automatonToDot(*in, std::cout);
-		} else if(automaton_to_gastex.getValue()) {
-			automatonToGasTex(*in, std::cout);
-		} else if(grammar_from_string.getValue()) {
-			grammarFromString(*in, std::cout);
-		} else if(grammar_to_string.getValue()) {
-			grammarToString(*in, std::cout);
-		} else if(regexp_from_string.getValue()) {
-			regexpFromString(*in, std::cout);
-		} else if(regexp_to_string.getValue()) {
-			regexpToString(*in, std::cout);
-		} else if(string_from_string.getValue()) {
-			stringFromString(*in, std::cout);
-		} else if(string_to_string.getValue()) {
-			stringToString(*in, std::cout);
+		if ( input.isSet ( ) ) {
+			if ( input.getValue ( ) == "-" )
+				in = & std::cin;
+			else
+				in = new std::ifstream ( input.getValue ( ) );
+		} else {
+			in = & std::cin;
 		}
 
-		if(input.isSet() && input.getValue() != "-") {
+		if ( automaton_from_string.getValue ( ) )
+			automatonFromString ( * in, std::cout );
+		else if ( automaton_to_string.getValue ( ) )
+			automatonToString ( * in, std::cout );
+		else if ( automaton_to_dot.getValue ( ) )
+			automatonToDot ( * in, std::cout );
+		else if ( automaton_to_gastex.getValue ( ) )
+			automatonToGasTex ( * in, std::cout );
+		else if ( grammar_from_string.getValue ( ) )
+			grammarFromString ( * in, std::cout );
+		else if ( grammar_to_string.getValue ( ) )
+			grammarToString ( * in, std::cout );
+		else if ( regexp_from_string.getValue ( ) )
+			regexpFromString ( * in, std::cout );
+		else if ( regexp_to_string.getValue ( ) )
+			regexpToString ( * in, std::cout );
+		else if ( string_from_string.getValue ( ) )
+			stringFromString ( * in, std::cout );
+		else if ( string_to_string.getValue ( ) )
+			stringToString ( * in, std::cout );
+		else if ( tree_from_string.getValue ( ) )
+			treeFromString ( * in, std::cout );
+		else if ( tree_to_string.getValue ( ) )
+			treeToString ( * in, std::cout );
+
+		if ( input.isSet ( ) && ( input.getValue ( ) != "-" ) )
 			delete in;
-		}
 
-		std::chrono::measurements::end();
-		std::chrono::measurements::end();
+		std::chrono::measurements::end ( );
+		std::chrono::measurements::end ( );
 
-		if(measure.getValue()) std::clog << std::chrono::measurements::results() << std::endl;
+		if ( measure.getValue ( ) ) std::clog << std::chrono::measurements::results ( ) << std::endl;
 
 		return 0;
-	} catch (const exception::AlibException& exception) {
-		alib::XmlDataFactory::toStdout(exception);
+	} catch ( const exception::AlibException & exception ) {
+		alib::XmlDataFactory::toStdout ( exception );
 		return 1;
-	} catch(const TCLAP::ArgException& exception) {
-		std::cerr << exception.error() << std::endl;
+	} catch ( const TCLAP::ArgException & exception ) {
+		std::cerr << exception.error ( ) << std::endl;
 		return 2;
-	} catch (const std::exception& exception) {
-		std::cerr << "Exception caught: " << exception.what() << std::endl;
+	} catch ( const std::exception & exception ) {
+		std::cerr << "Exception caught: " << exception.what ( ) << std::endl;
 		return 3;
-	} catch(...) {
+	} catch ( ... ) {
 		std::cerr << "Unknown exception caught." << std::endl;
 		return 127;
 	}
 }
-
diff --git a/alib2str/src/StringApi.cpp b/alib2str/src/StringApi.cpp
index 19b1af90c4..a3c97bbb23 100644
--- a/alib2str/src/StringApi.cpp
+++ b/alib2str/src/StringApi.cpp
@@ -19,69 +19,78 @@ const automaton::AutomatonFromStringParser FromStringParsers::automatonParser;
 const grammar::GrammarFromStringParser FromStringParsers::grammarParser;
 const graph::GraphFromStringParser FromStringParsers::graphParser;
 const primitive::PrimitiveFromStringParser FromStringParsers::primitiveParser;
+const tree::TreeFromStringParser FromStringParsers::treeParser;
 
-alphabet::Symbol stringApi<alphabet::Symbol>::parse(std::istream& input) {
-	return FromStringParsers::symbolParser.parseSymbol(input);
+alphabet::Symbol stringApi < alphabet::Symbol >::parse ( std::istream & input ) {
+	return FromStringParsers::symbolParser.parseSymbol ( input );
 }
 
-void stringApi<alphabet::Symbol>::compose(std::ostream& output, const alphabet::Symbol& data) {
-	return alphabet::SymbolToStringComposer::compose(output, data);
+void stringApi < alphabet::Symbol >::compose ( std::ostream & output, const alphabet::Symbol & data ) {
+	return alphabet::SymbolToStringComposer::compose ( output, data );
 }
 
-automaton::Automaton stringApi<automaton::Automaton>::parse(std::istream& input) {
-	return FromStringParsers::automatonParser.parseAutomaton(input);
+automaton::Automaton stringApi < automaton::Automaton >::parse ( std::istream & input ) {
+	return FromStringParsers::automatonParser.parseAutomaton ( input );
 }
 
-void stringApi<automaton::Automaton>::compose(std::ostream& output, const automaton::Automaton& data) {
-	return automaton::AutomatonToStringComposer::compose(output, data);
+void stringApi < automaton::Automaton >::compose ( std::ostream & output, const automaton::Automaton & data ) {
+	return automaton::AutomatonToStringComposer::compose ( output, data );
 }
 
-grammar::Grammar stringApi<grammar::Grammar>::parse(std::istream& input) {
-	return FromStringParsers::grammarParser.parseGrammar(input);
+grammar::Grammar stringApi < grammar::Grammar >::parse ( std::istream & input ) {
+	return FromStringParsers::grammarParser.parseGrammar ( input );
 }
 
-void stringApi<grammar::Grammar>::compose(std::ostream& output, const grammar::Grammar& data) {
-	return grammar::GrammarToStringComposer::compose(output, data);
+void stringApi < grammar::Grammar >::compose ( std::ostream & output, const grammar::Grammar & data ) {
+	return grammar::GrammarToStringComposer::compose ( output, data );
 }
 
-graph::Graph stringApi<graph::Graph>::parse(std::istream& input) {
-	return FromStringParsers::graphParser.parseGraph(input);
+graph::Graph stringApi < graph::Graph >::parse ( std::istream & input ) {
+	return FromStringParsers::graphParser.parseGraph ( input );
 }
 
-void stringApi<graph::Graph>::compose(std::ostream& output, const graph::Graph& data) {
-	return graph::GraphToStringComposer::compose(output, data);
+void stringApi < graph::Graph >::compose ( std::ostream & output, const graph::Graph & data ) {
+	return graph::GraphToStringComposer::compose ( output, data );
 }
 
-label::Label stringApi<label::Label>::parse(std::istream& input) {
-	return FromStringParsers::labelParser.parseLabel(input);
+label::Label stringApi < label::Label >::parse ( std::istream & input ) {
+	return FromStringParsers::labelParser.parseLabel ( input );
 }
 
-void stringApi<label::Label>::compose(std::ostream& output, const label::Label& data) {
-	return label::LabelToStringComposer::compose(output, data);
+void stringApi < label::Label >::compose ( std::ostream & output, const label::Label & data ) {
+	return label::LabelToStringComposer::compose ( output, data );
 }
 
-regexp::RegExp stringApi<regexp::RegExp>::parse(std::istream& input) {
-	return FromStringParsers::regexpParser.parseRegExp(input);
+regexp::RegExp stringApi < regexp::RegExp >::parse ( std::istream & input ) {
+	return FromStringParsers::regexpParser.parseRegExp ( input );
 }
 
-void stringApi<regexp::RegExp>::compose(std::ostream& output, const regexp::RegExp& data) {
-	return regexp::RegExpToStringComposer::compose(output, data);
+void stringApi < regexp::RegExp >::compose ( std::ostream & output, const regexp::RegExp & data ) {
+	return regexp::RegExpToStringComposer::compose ( output, data );
 }
 
-string::String stringApi<string::String>::parse(std::istream& input) {
-	return FromStringParsers::stringParser.parseString(input);
+string::String stringApi < string::String >::parse ( std::istream & input ) {
+	return FromStringParsers::stringParser.parseString ( input );
 }
 
-void stringApi<string::String>::compose(std::ostream& output, const string::String& data) {
-	return string::StringToStringComposer::compose(output, data);
+void stringApi < string::String >::compose ( std::ostream & output, const string::String & data ) {
+	return string::StringToStringComposer::compose ( output, data );
 }
 
-primitive::Primitive stringApi<primitive::Primitive>::parse(std::istream& input) {
-	return FromStringParsers::primitiveParser.parsePrimitive(input);
+primitive::Primitive stringApi < primitive::Primitive >::parse ( std::istream & input ) {
+	return FromStringParsers::primitiveParser.parsePrimitive ( input );
 }
 
-void stringApi<primitive::Primitive>::compose(std::ostream& output, const primitive::Primitive& data) {
-	return primitive::PrimitiveToStringComposer::compose(output, data);
+void stringApi < primitive::Primitive >::compose ( std::ostream & output, const primitive::Primitive & data ) {
+	return primitive::PrimitiveToStringComposer::compose ( output, data );
+}
+
+tree::Tree stringApi < tree::Tree >::parse ( std::istream & input ) {
+	return FromStringParsers::treeParser.parseTree ( input );
+}
+
+void stringApi < tree::Tree >::compose ( std::ostream & output, const tree::Tree & data ) {
+	return tree::TreeToStringComposer::compose ( output, data );
 }
 
 } /* namespace alib */
diff --git a/alib2str/src/StringApi.hpp b/alib2str/src/StringApi.hpp
index 6420ad1b8c..bd6042c24b 100644
--- a/alib2str/src/StringApi.hpp
+++ b/alib2str/src/StringApi.hpp
@@ -16,6 +16,7 @@
 #include "grammar/GrammarFromStringParser.h"
 #include "graph/GraphFromStringParser.h"
 #include "primitive/PrimitiveFromStringParser.h"
+#include "tree/TreeFromStringParser.h"
 
 #include "label/LabelToStringComposer.h"
 #include "alphabet/SymbolToStringComposer.h"
@@ -25,64 +26,70 @@
 #include "grammar/GrammarToStringComposer.h"
 #include "graph/GraphToStringComposer.h"
 #include "primitive/PrimitiveToStringComposer.h"
+#include "tree/TreeToStringComposer.h"
 
 #include "object/ObjectBase.h"
 
 namespace alib {
 
-template<typename T>
+template < typename T >
 struct stringApi {
-	static T parse(std::istream& input);
-	static void compose(std::ostream& output, const T& data);
+	static T	parse ( std::istream & input );
+	static void compose ( std::ostream & output, const T & data );
 };
 
-template<>
-struct stringApi<alphabet::Symbol> {
-	static alphabet::Symbol parse(std::istream& input);
-	static void compose(std::ostream& output, const alphabet::Symbol& data);
+template < >
+struct stringApi < alphabet::Symbol > {
+	static alphabet::Symbol parse ( std::istream & input );
+	static void compose ( std::ostream & output, const alphabet::Symbol & data );
 };
 
+template < >
+struct stringApi < automaton::Automaton > {
+	static automaton::Automaton parse ( std::istream & input );
+	static void compose ( std::ostream & output, const automaton::Automaton & data );
+};
 
-template<>
-struct stringApi<automaton::Automaton> {
-	static automaton::Automaton parse(std::istream& input);
-	static void compose(std::ostream& output, const automaton::Automaton& data);
+template < >
+struct stringApi < grammar::Grammar > {
+	static grammar::Grammar parse ( std::istream & input );
+	static void compose ( std::ostream & output, const grammar::Grammar & data );
 };
 
-template<>
-struct stringApi<grammar::Grammar> {
-	static grammar::Grammar parse(std::istream& input);
-	static void compose(std::ostream& output, const grammar::Grammar& data);
+template < >
+struct stringApi < graph::Graph > {
+	static graph::Graph parse ( std::istream & input );
+	static void compose ( std::ostream & output, const graph::Graph & data );
 };
 
-template<>
-struct stringApi<graph::Graph> {
-	static graph::Graph parse(std::istream& input);
-	static void compose(std::ostream& output, const graph::Graph& data);
+template < >
+struct stringApi < label::Label > {
+	static label::Label parse ( std::istream & input );
+	static void compose ( std::ostream & output, const label::Label & data );
 };
 
-template<>
-struct stringApi<label::Label> {
-	static label::Label parse(std::istream& input);
-	static void compose(std::ostream& output, const label::Label& data);
+template < >
+struct stringApi < regexp::RegExp > {
+	static regexp::RegExp parse ( std::istream & input );
+	static void compose ( std::ostream & output, const regexp::RegExp & data );
 };
 
-template<>
-struct stringApi<regexp::RegExp> {
-	static regexp::RegExp parse(std::istream& input);
-	static void compose(std::ostream& output, const regexp::RegExp& data);
+template < >
+struct stringApi < string::String > {
+	static string::String parse ( std::istream & input );
+	static void compose ( std::ostream & output, const string::String & data );
 };
 
-template<>
-struct stringApi<string::String> {
-	static string::String parse(std::istream& input);
-	static void compose(std::ostream& output, const string::String& data);
+template < >
+struct stringApi < primitive::Primitive > {
+	static primitive::Primitive parse ( std::istream & input );
+	static void compose ( std::ostream & output, const primitive::Primitive & data );
 };
 
-template<>
-struct stringApi<primitive::Primitive> {
-	static primitive::Primitive parse(std::istream& input);
-	static void compose(std::ostream& output, const primitive::Primitive& data);
+template < >
+struct stringApi < tree::Tree > {
+	static tree::Tree parse ( std::istream & input );
+	static void compose ( std::ostream & output, const tree::Tree & data );
 };
 
 class FromStringParsers {
@@ -95,7 +102,7 @@ public:
 	static const grammar::GrammarFromStringParser grammarParser;
 	static const graph::GraphFromStringParser graphParser;
 	static const primitive::PrimitiveFromStringParser primitiveParser;
-
+	static const tree::TreeFromStringParser treeParser;
 };
 
 } /* namespace alib */
diff --git a/alib2str/src/tree/TreeFromStringLexer.cpp b/alib2str/src/tree/TreeFromStringLexer.cpp
new file mode 100644
index 0000000000..8a4fab3c1f
--- /dev/null
+++ b/alib2str/src/tree/TreeFromStringLexer.cpp
@@ -0,0 +1,90 @@
+/*
+ * TreeFromStringLexer.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "TreeFromStringLexer.h"
+
+namespace tree {
+
+TreeFromStringLexer::Token TreeFromStringLexer::next ( std::istream & in ) const {
+	TreeFromStringLexer::Token token;
+
+	token.type	= TokenType::ERROR;
+	token.value = "";
+	token.raw = "";
+	char character;
+
+L0:	character = in.get ( );
+
+	if ( in.eof ( ) ) {
+		token.type = TokenType::TEOF;
+		return token;
+	} else if ( ( character == ' ' ) || ( character == '\n' ) || ( character == '\t' ) ) {
+		token.raw += character;
+		goto L0;
+	} else if ( character == '#' ) {
+		token.value += character;
+		token.raw += character;
+		goto L1;
+	} else if ( character == '|' ) {
+		token.type	 = TokenType::BAR;
+		token.value += character;
+		token.raw += character;
+		return token;
+	} else if ( ( character >= '0' ) && ( character <= '9' ) ) {
+		token.type	 = TokenType::RANK;
+		token.value += character;
+		token.raw += character;
+		goto L2;
+	} else {
+		in.putback ( character );
+		putback ( in, std::move ( token ) );
+		in.clear ( );
+		token.type = TokenType::ERROR;
+		return token;
+	}
+
+L1:	character = in.get ( );
+
+	if ( in.eof ( ) ) {
+		token.type = TokenType::TEOF;
+		return token;
+	} else if ( character == 'S' ) {
+		token.type	 = TokenType::SUBTREE_WILDCARD;
+		token.value += character;
+		token.raw += character;
+		return token;
+	} else {
+		in.putback ( character );
+		putback ( in, std::move ( token ) );
+		token.type = TokenType::ERROR;
+		return token;
+	}
+
+L2:	character = in.get ( );
+
+	if ( in.eof ( ) ) {
+		return token;
+	} else if ( ( character >= '0' ) && ( character <= '9' ) ) {
+		token.value += character;
+		token.raw += character;
+		goto L1;
+	} else {
+		in.unget ( );
+		return token;
+	}
+}
+
+void TreeFromStringLexer::putback ( std::istream & in, TreeFromStringLexer::Token token ) const {
+	while ( !token.raw.empty ( ) ) {
+		in.putback ( token.raw.back ( ) );
+		token.raw.pop_back ( );
+	}
+
+	in.clear ( );
+}
+
+} /* namespace tree */
diff --git a/alib2str/src/tree/TreeFromStringLexer.h b/alib2str/src/tree/TreeFromStringLexer.h
new file mode 100644
index 0000000000..59990027fa
--- /dev/null
+++ b/alib2str/src/tree/TreeFromStringLexer.h
@@ -0,0 +1,34 @@
+/*
+ * TreeFromStringLexer.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef TREE_FROM_STRING_LEXER_H_
+#define TREE_FROM_STRING_LEXER_H_
+
+#include <string>
+#include <istream>
+
+namespace tree {
+
+class TreeFromStringLexer {
+public:
+	enum class TokenType {
+		BAR, RANK, SUBTREE_WILDCARD, TEOF, ERROR
+	};
+
+	struct Token {
+		TokenType	type;
+		std::string value;
+		std::string raw;
+	};
+
+	Token next ( std::istream & input ) const;
+	void putback ( std::istream &, Token token ) const;
+};
+
+} /* namespace tree */
+
+#endif /* TREE_FROM_STRING_LEXER_H_ */
diff --git a/alib2str/src/tree/TreeFromStringParser.cpp b/alib2str/src/tree/TreeFromStringParser.cpp
new file mode 100644
index 0000000000..8b09091ac9
--- /dev/null
+++ b/alib2str/src/tree/TreeFromStringParser.cpp
@@ -0,0 +1,103 @@
+/*
+ * TreeFromStringParser.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "TreeFromStringParser.h"
+#include "exception/AlibException.h"
+#include "tree/TreeClasses.h"
+
+#include "../StringApi.hpp"
+
+namespace tree {
+
+Tree TreeFromStringParser::parseTree ( std::istream & input ) const {
+	return parseTree ( input, std::set < FEATURES > ( { FEATURES::RANKED_TREE, FEATURES::UNRANKED_TREE } ) );
+}
+
+Tree TreeFromStringParser::parseTree ( std::istream & input, const std::set < FEATURES > & features ) const {
+	alphabet::Symbol symbol = alib::stringApi < alphabet::Symbol >::parse ( input );
+
+	unsigned rank = 0;
+
+	TreeFromStringLexer::Token token = m_TreeLexer.next ( input );
+
+	if ( token.type == TreeFromStringLexer::TokenType::RANK ) {
+		rank = std::stou ( token.value );
+
+		std::vector < tree::RankedNode * > childs;
+
+		for ( unsigned i = 0; i < rank; i++ )
+			childs.push_back ( parseRankedContent ( input ) );
+
+		RankedTree tree ( RankedNode ( alphabet::RankedSymbol ( symbol, rank ), std::move ( childs ) ) );
+
+		if ( features.count ( FEATURES::RANKED_TREE ) ) return Tree {
+					   tree
+			};
+	} else {
+		std::vector < tree::UnrankedNode * > childs;
+
+		while ( token.type != TreeFromStringLexer::TokenType::BAR ) {
+			m_TreeLexer.putback ( input, token );
+			childs.push_back ( parseUnrankedContent ( input ) );
+			rank++;
+			token = m_TreeLexer.next ( input );
+		}
+
+		if ( token.type != TreeFromStringLexer::TokenType::BAR )
+			throw exception::AlibException ( "Missing bar" );
+
+		UnrankedTree tree ( UnrankedNode ( symbol, childs ) );
+
+		if ( features.count ( FEATURES::UNRANKED_TREE ) ) return Tree {
+					   tree
+			};
+	}
+
+	throw exception::AlibException ( "Invalid input" );
+}
+
+tree::RankedNode * TreeFromStringParser::parseRankedContent ( std::istream & input ) const {
+	alphabet::Symbol symbol = alib::stringApi < alphabet::Symbol >::parse ( input );
+
+	unsigned rank = 0;
+	std::vector < tree::RankedNode * > childs;
+
+	TreeFromStringLexer::Token token = m_TreeLexer.next ( input );
+
+	if ( token.type == TreeFromStringLexer::TokenType::RANK )
+		rank = std::stou ( token.value );
+	else
+		throw exception::AlibException ( "Missing rank" );
+
+	for ( unsigned i = 0; i < rank; i++ )
+		childs.push_back ( parseRankedContent ( input ) );
+
+	return new RankedNode ( alphabet::RankedSymbol ( std::move ( symbol ), rank ), std::move ( childs ) );
+}
+
+tree::UnrankedNode * TreeFromStringParser::parseUnrankedContent ( std::istream & input ) const {
+	alphabet::Symbol symbol = alib::stringApi < alphabet::Symbol >::parse ( input );
+
+	unsigned rank = 0;
+	std::vector < tree::UnrankedNode * > childs;
+
+	TreeFromStringLexer::Token token = m_TreeLexer.next ( input );
+
+	while ( token.type != TreeFromStringLexer::TokenType::BAR ) {
+		m_TreeLexer.putback ( input, token );
+		childs.push_back ( parseUnrankedContent ( input ) );
+		rank++;
+		token = m_TreeLexer.next ( input );
+	}
+
+	if ( token.type != TreeFromStringLexer::TokenType::BAR )
+		throw exception::AlibException ( "Missing bar" );
+
+	return new UnrankedNode ( std::move ( symbol ), std::move ( childs ) );
+}
+
+} /* namespace tree */
diff --git a/alib2str/src/tree/TreeFromStringParser.h b/alib2str/src/tree/TreeFromStringParser.h
new file mode 100644
index 0000000000..27c986a392
--- /dev/null
+++ b/alib2str/src/tree/TreeFromStringParser.h
@@ -0,0 +1,44 @@
+/*
+ * TreeFromStringParser.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#ifndef TREE_FROM_STRING_PARSER_H_
+#define TREE_FROM_STRING_PARSER_H_
+
+#include "tree/TreeFeatures.h"
+#include "TreeFromStringLexer.h"
+
+#include <set>
+
+namespace alib {
+
+template < typename T >
+struct stringApi;
+
+} /* namespace alib */
+
+namespace tree {
+
+class TreeFromStringParser {
+public:
+	TreeFromStringParser ( ) { }
+
+private:
+	tree::RankedNode * parseRankedContent ( std::istream & ) const;
+	tree::UnrankedNode * parseUnrankedContent ( std::istream & ) const;
+
+	TreeFromStringLexer m_TreeLexer;
+
+	tree::Tree parseTree ( std::istream & ) const;
+	tree::Tree parseTree ( std::istream &, const std::set < FEATURES > & features ) const;
+
+	template < typename T >
+	friend struct alib::stringApi;
+};
+
+} /* namespace tree */
+
+#endif /* TREE_FROM_STRING_PARSER_H_ */
diff --git a/alib2str/src/tree/TreeToStringComposer.cpp b/alib2str/src/tree/TreeToStringComposer.cpp
new file mode 100644
index 0000000000..f2ee31a8b4
--- /dev/null
+++ b/alib2str/src/tree/TreeToStringComposer.cpp
@@ -0,0 +1,18 @@
+/*
+ * TreeToStringComposer.cpp
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnicek
+ */
+
+#include "TreeToStringComposer.h"
+
+#include "../StringApi.hpp"
+
+namespace tree {
+
+void TreeToStringComposer::compose ( std::ostream & out, const Tree & tree ) {
+	getInstance ( ).dispatch ( out, tree.getData ( ) );
+}
+
+} /* namespace tree */
diff --git a/alib2str/src/tree/TreeToStringComposer.h b/alib2str/src/tree/TreeToStringComposer.h
new file mode 100644
index 0000000000..5afbc0f055
--- /dev/null
+++ b/alib2str/src/tree/TreeToStringComposer.h
@@ -0,0 +1,40 @@
+/*
+ * TreeToStringComposer.h
+ *
+ *  Created on: Nov 23, 2013
+ *      Author: Jan Travnciek
+ */
+
+#ifndef TREE_TO_STRING_COMPOSER_H_
+#define TREE_TO_STRING_COMPOSER_H_
+
+#include <ostream>
+#include <common/multipleDispatch.hpp>
+#include "tree/Tree.h"
+#include "tree/TreeFeatures.h"
+
+namespace tree {
+
+/**
+ * This class contains methods to print XML representation of tree to the output stream.
+ */
+class TreeToStringComposer : public std::SingleDispatchFirstStaticParam < void, std::ostream &, TreeBase > {
+public:
+	/**
+	 * Prints XML representation of String to the output stream.
+	 * @param tree String to print
+	 * @param out output stream to which print the String
+	 */
+	static void compose ( std::ostream & output, const Tree & tree );
+
+	static TreeToStringComposer & getInstance ( ) {
+		static TreeToStringComposer res;
+
+		return res;
+	}
+
+};
+
+} /* namespace tree */
+
+#endif /* TREE_TO_STRING_COMPOSER_H_ */
-- 
GitLab