From 6ffdddfa6707d3de67c0542280a147bc832a2462 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sat, 4 Apr 2020 17:46:37 +0200
Subject: [PATCH] ranked tree to dot

---
 alib2aux/src/convert/DotConverter.cpp         |  1 +
 alib2aux/src/convert/DotConverter.h           | 17 +++++--
 alib2aux/src/convert/DotConverterRTEPart.hxx  | 30 ++++++------
 alib2aux/src/convert/DotConverterTreePart.hxx | 48 +++++++++++++++++++
 4 files changed, 77 insertions(+), 19 deletions(-)
 create mode 100644 alib2aux/src/convert/DotConverterTreePart.hxx

diff --git a/alib2aux/src/convert/DotConverter.cpp b/alib2aux/src/convert/DotConverter.cpp
index aca2c3f1a9..f4b8675c59 100644
--- a/alib2aux/src/convert/DotConverter.cpp
+++ b/alib2aux/src/convert/DotConverter.cpp
@@ -33,5 +33,6 @@ auto DotConverterSinglePopNPDA = registration::AbstractRegister < convert::DotCo
 auto DotConverterOneTapeDTM = registration::AbstractRegister < convert::DotConverter, std::string, const automaton::OneTapeDTM < > & > ( convert::DotConverter::convert );
 auto DotConverterExtendedNFTA = registration::AbstractRegister < convert::DotConverter, std::string, const automaton::ExtendedNFTA < > & > ( convert::DotConverter::convert );
 auto DotConverterFormalRTE = registration::AbstractRegister < convert::DotConverter, std::string, const rte::FormalRTE < > & > ( convert::DotConverter::convert );
+auto DotConverterRankedTree = registration::AbstractRegister < convert::DotConverter, std::string, const tree::RankedTree < > & > ( convert::DotConverter::convert );
 
 } /* namespace */
diff --git a/alib2aux/src/convert/DotConverter.h b/alib2aux/src/convert/DotConverter.h
index 4312a54736..aba10d9e89 100644
--- a/alib2aux/src/convert/DotConverter.h
+++ b/alib2aux/src/convert/DotConverter.h
@@ -47,6 +47,7 @@
 #include <string/string/LinearString.h>
 #include <regexp/string/UnboundedRegExp.h>
 
+#include "DotConverterTreePart.hxx"
 #include "DotConverterRTEPart.hxx"
 
 namespace convert {
@@ -181,6 +182,9 @@ public:
 	template < class SymbolType >
 	static void convert(std::ostream& out, const rte::FormalRTE < SymbolType > & e );
 
+	template < class SymbolType >
+	static void convert(std::ostream& out, const tree::RankedTree < SymbolType > & e );
+
 	template < class T >
 	static std::string convert ( const T & automaton ) {
 		std::stringstream ss;
@@ -892,8 +896,15 @@ void DotConverter::transitions(const automaton::EpsilonNFA < SymbolType, StateTy
 template < class SymbolType >
 void DotConverter::convert(std::ostream& out, const rte::FormalRTE < SymbolType > & e ) {
 	out << "digraph rte {\n";
-	out << DotConverterRTE::convertInternal ( e ) << '\n';
-	out << "}" << std::endl;
+	DotConverterRTE::convertInternal ( out, e );
+	out << '\n' << "}" << std::endl;
+}
+
+template < class SymbolType >
+void DotConverter::convert(std::ostream& out, const tree::RankedTree < SymbolType > & e ) {
+	out << "digraph tree {\n";
+	DotConverterTree::convertInternal ( out, e );
+	out << '\n' << "}" << std::endl;
 }
 
 template < class SymbolType, class StateType >
@@ -1071,7 +1082,7 @@ void DotConverter::transitions(const automaton::ExtendedNFTA < SymbolType, State
 		out << "subgraph cluster_rte_" << auxNodeCnt << "{" << '\n';
 		out << "label=\"rte_" << auxNodeCnt << "\"\n";
 		out << "color = blue;\n";
-		out << convert::DotConverterRTE::convertInternal ( rte::FormalRTE < ext::variant < SymbolType, StateType > > ( transition.first.first ), "x" + ext::to_string ( auxNodeCnt ) + "x" );
+		convert::DotConverterRTE::convertInternal ( out, rte::FormalRTE < ext::variant < SymbolType, StateType > > ( transition.first.first ), "x" + ext::to_string ( auxNodeCnt ) + "x" );
 		out << "}\n" << std::endl;
 
 		out << "node [shape = point, label=\"\"]; Aux" << auxNodeCnt << ";\n";
diff --git a/alib2aux/src/convert/DotConverterRTEPart.hxx b/alib2aux/src/convert/DotConverterRTEPart.hxx
index 9f607e33ba..7c15d71945 100644
--- a/alib2aux/src/convert/DotConverterRTEPart.hxx
+++ b/alib2aux/src/convert/DotConverterRTEPart.hxx
@@ -16,30 +16,28 @@ namespace convert {
 class DotConverterRTE {
 public:
 	template < class SymbolType >
-	static std::string convertInternal ( const rte::FormalRTE < SymbolType > & rte, const std::string & nodePrefix = "" );
+	static void convertInternal ( std::ostream & oss, const rte::FormalRTE < SymbolType > & rte, const std::string & nodePrefix = "" );
 
 	template < class SymbolType >
 	class Formal {
 	public:
-		static unsigned visit ( const rte::FormalRTEAlternation < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
-		static unsigned visit ( const rte::FormalRTESubstitution < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
-		static unsigned visit ( const rte::FormalRTEIteration < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
-		static unsigned visit ( const rte::FormalRTESymbolAlphabet < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
-		static unsigned visit ( const rte::FormalRTESymbolSubst < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
-		static unsigned visit ( const rte::FormalRTEEmpty < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
+		static unsigned visit ( const rte::FormalRTEAlternation < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
+		static unsigned visit ( const rte::FormalRTESubstitution < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
+		static unsigned visit ( const rte::FormalRTEIteration < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
+		static unsigned visit ( const rte::FormalRTESymbolAlphabet < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
+		static unsigned visit ( const rte::FormalRTESymbolSubst < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
+		static unsigned visit ( const rte::FormalRTEEmpty < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix );
 	};
 };
 
 template < class SymbolType >
-std::string DotConverterRTE::convertInternal ( const rte::FormalRTE < SymbolType > & rte, const std::string & nodePrefix ) {
-	std::stringstream oss;
+void DotConverterRTE::convertInternal ( std::ostream & oss, const rte::FormalRTE < SymbolType > & rte, const std::string & nodePrefix ) {
 	unsigned nodeIdCounter = 0;
 	rte.getRTE ( ).getStructure ( ).template accept < unsigned, DotConverterRTE::Formal < SymbolType > > ( oss, nodeIdCounter, nodePrefix );
-	return oss.str ( );
 }
 
 template < class SymbolType >
-unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEAlternation < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
+unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEAlternation < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
 	unsigned id = nodeIdCounter ++;
 
 	oss << nodePrefix << id << "[label=\"+\", shape=plaintext];" << std::endl;
@@ -53,7 +51,7 @@ unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEAlt
 }
 
 template < class SymbolType >
-unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESubstitution < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
+unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESubstitution < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
 	unsigned id = nodeIdCounter ++;
 
 	oss << nodePrefix << id << "[label=\". " << node.getSubstitutionSymbol( ).getSymbol ( ).getSymbol ( ) << "\", shape=plaintext];" << std::endl;
@@ -67,7 +65,7 @@ unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESub
 }
 
 template < class SymbolType >
-unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEIteration < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
+unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEIteration < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
 	unsigned id = nodeIdCounter ++;
 
 	oss << nodePrefix << id << "[label=\"* " << node.getSubstitutionSymbol( ).getSymbol ( ).getSymbol ( ) << "\", shape=plaintext];" << std::endl;
@@ -79,7 +77,7 @@ unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEIte
 }
 
 template < class SymbolType >
-unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
+unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESymbolAlphabet < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
 	unsigned id = nodeIdCounter ++;
 
 	oss << nodePrefix << id << "[label=\"" << node.getSymbol( ).getSymbol ( ) << "\", shape=plaintext];" << std::endl;
@@ -93,13 +91,13 @@ unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESym
 }
 
 template < class SymbolType >
-unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESymbolSubst < SymbolType > & node, std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
+unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTESymbolSubst < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
 	oss << nodePrefix << nodeIdCounter << "[label=\"" << node.getSymbol ( ).getSymbol ( ) << "\", shape=plaintext];" << std::endl;
 	return nodeIdCounter ++;
 }
 
 template < class SymbolType >
-unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEEmpty < SymbolType > & , std::stringstream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
+unsigned DotConverterRTE::Formal < SymbolType >::visit ( const rte::FormalRTEEmpty < SymbolType > & , std::ostream & oss, unsigned & nodeIdCounter, const std::string & nodePrefix ) {
 	oss << nodePrefix << nodeIdCounter << "[label=\"#0\", shape=plaintext];" << std::endl;
 	return nodeIdCounter ++;
 }
diff --git a/alib2aux/src/convert/DotConverterTreePart.hxx b/alib2aux/src/convert/DotConverterTreePart.hxx
new file mode 100644
index 0000000000..5b551eb6bf
--- /dev/null
+++ b/alib2aux/src/convert/DotConverterTreePart.hxx
@@ -0,0 +1,48 @@
+/*
+ * DotConverterTree.h
+ *
+ *  Created on: 15. 3. 2019
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef _DOT_CONVERTER_TREE_H_
+#define _DOT_CONVERTER_TREE_H_
+
+#include <alphabet/string/RankedSymbol.h>
+
+#include <tree/ranked/RankedTree.h>
+
+namespace convert {
+
+class DotConverterTree {
+	template < class SymbolType >
+	static unsigned convertRecursive ( const ext::tree < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter );
+
+public:
+	template < class SymbolType >
+	static void convertInternal ( std::ostream & oss, const tree::RankedTree < SymbolType > & tree );
+};
+
+template < class SymbolType >
+void DotConverterTree::convertInternal ( std::ostream & oss, const tree::RankedTree < SymbolType > & tree ) {
+	unsigned nodeIdCounter = 0;
+	convertRecursive ( tree.getContent ( ), oss, nodeIdCounter );
+}
+
+template < class SymbolType >
+unsigned DotConverterTree::convertRecursive ( const ext::tree < SymbolType > & node, std::ostream & oss, unsigned & nodeIdCounter ) {
+	unsigned id = nodeIdCounter ++;
+
+	oss << id << "[label=\"" + factory::StringDataFactory::toString ( node.getData ( ) ) + "\", shape=plaintext];" << std::endl;
+
+	for ( const ext::tree < SymbolType > & child : node.getChildren ( ) ) {
+		size_t childId = convertRecursive ( child, oss, nodeIdCounter );
+		oss << id << " -> " << childId << ";" << std::endl;
+	}
+
+	return id;
+}
+
+} /* namespace convert */
+
+#endif /* _DOT_CONVERTER_TREE_H_ */
-- 
GitLab