From 9d34022924aaa0a18c02e48ca899c996bc3cdf16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz>
Date: Thu, 18 Sep 2014 20:23:08 +0200
Subject: [PATCH] algo: Thompson API

---
 aconversions2/src/ConversionHandler.cpp      |   3 +-
 alib2algo/src/conversions/re2fa/Thompson.cpp | 348 ++++++++++---------
 alib2algo/src/conversions/re2fa/Thompson.h   |  50 +--
 3 files changed, 207 insertions(+), 194 deletions(-)

diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index d523dced31..150544a0c7 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -208,8 +208,7 @@ void ConversionHandler::convertREtoFSM( void )
 			break;
 		}
 	case THOMPSON_NFA: {
-			conversions::re2fa::Thompson conv;
-			alib::DataFactory::toStdout(conv.convert(regexp));
+			alib::DataFactory::toStdout(conversions::re2fa::Thompson::convert(regexp));
 			break;
 		}
 	case GLUSHKOV_NFA:
diff --git a/alib2algo/src/conversions/re2fa/Thompson.cpp b/alib2algo/src/conversions/re2fa/Thompson.cpp
index 48b8abedc3..092f08422b 100644
--- a/alib2algo/src/conversions/re2fa/Thompson.cpp
+++ b/alib2algo/src/conversions/re2fa/Thompson.cpp
@@ -2,11 +2,10 @@
  * Thompson.cpp
  *
  *  Created on: 11. 1. 2014
- *      Author: tomas
+ *	  Author: Tomas Pecka
  */
 #include "Thompson.h"
 #include <tuple>
-#include <automaton/Automaton.h>
 
 namespace conversions
 {
@@ -14,252 +13,263 @@ namespace conversions
 namespace re2fa
 {
 
-Thompson::Thompson(void){}
-Thompson::~Thompson(void){}
-
 automaton::EpsilonNFA Thompson::convert(const regexp::RegExp& regexp)
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> out(automaton::EpsilonNFA(), 0, nullptr, nullptr);
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA* out = NULL;
+	regexp.getData().Accept((void*) &out, Thompson::THOMPSON);
+	automaton::EpsilonNFA res = std::move(*out);
+	delete out;
+	return res;
+}
+
+template<class T>
+automaton::EpsilonNFA Thompson::convert(const T& regexp)
+{
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> out(automaton::EpsilonNFA(), 0, nullptr, nullptr);
 
-    regexp.getData().Accept((void*) &out, *this);
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton.setInputSymbols(regexp.getAlphabet());
 
-    automaton.setInitialStates({*std::get<2>(out)});
-    automaton.setFinalStates(std::set<automaton::State>{*std::get<3>(out)});
+	regexp.getRegExp().Accept((void*) &out, Thompson::THOMPSON);
 
-    return std::get<0>(out);
+	automaton.setInitialStates({*std::get<2>(out)});
+	automaton.setFinalStates(std::set<automaton::State>{*std::get<3>(out)});
+
+	return automaton;
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp)
+// ----------------------------------------------------------------------------
+
+void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData);
+	out = new automaton::EpsilonNFA(this->convert(regexp));
+}
 
-    automaton.setInputSymbols(regexp.getAlphabet());
-    regexp.getRegExp().Accept((void*) &out, *this);
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+	automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData);
+	out = new automaton::EpsilonNFA(this->convert(regexp));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation)
+// ----------------------------------------------------------------------------
+
+void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(userData, *this);
-    automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
-    automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
+	static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(userData, *this);
+	automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
+	automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
 
-    static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(userData, *this);
-    automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
-    automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
+	static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(userData, *this);
+	automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
+	automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
 
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation)
+void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(userData, *this);
-    const automaton::State* leftHead = std::get<2>(out);
-    const automaton::State* leftTail = std::get<3>(out);
+	static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(userData, *this);
+	const automaton::State* leftHead = std::get<2>(out);
+	const automaton::State* leftTail = std::get<3>(out);
 
-    static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this);
-    automaton.addTransition(*leftTail, string::Epsilon::EPSILON, *std::get<2>(out));
+	static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this);
+	automaton.addTransition(*leftTail, string::Epsilon::EPSILON, *std::get<2>(out));
 
-    std::get<2>(out) = &(*automaton.getStates().find(*leftHead));
-    // std::get<3>(out) = std::get<3>(out);
+	std::get<2>(out) = &(*automaton.getStates().find(*leftHead));
+	// std::get<3>(out) = std::get<3>(out);
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration)
+void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    static_cast<const regexp::FormalRegExpElement&>(iteration.getElement()).Accept(userData, *this);
-    automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
-    automaton.addTransition(head, string::Epsilon::EPSILON, tail);
-    automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
-    automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, *std::get<2>(out));
+	static_cast<const regexp::FormalRegExpElement&>(iteration.getElement()).Accept(userData, *this);
+	automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
+	automaton.addTransition(head, string::Epsilon::EPSILON, tail);
+	automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
+	automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, *std::get<2>(out));
 
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol)
+void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    automaton.addTransition(head, symbol.getSymbol(), tail);
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	automaton.addTransition(head, symbol.getSymbol(), tail);
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&)
+void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    automaton.addTransition(head, string::Epsilon::EPSILON, tail);
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	automaton.addTransition(head, string::Epsilon::EPSILON, tail);
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&)
+void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
 
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State head = automaton::State(std::get<1>(out)++);
 
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp)
-{
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
-
-    automaton.setInputSymbols(regexp.getAlphabet());
-    regexp.getRegExp().Accept((void*) &out, *this);
-}
+// ----------------------------------------------------------------------------
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation)
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
-
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
-
-    for(const auto& element : alternation.getElements())
-    {
-        static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this);
-        automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
-        automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
-    }
-
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
+
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
+
+	for(const auto& element : alternation.getElements())
+	{
+		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this);
+		automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
+		automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
+	}
+
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation)
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    std::vector<std::pair<const automaton::State*, const automaton::State*>> tails;
-    for(const auto& element : concatenation.getElements())
-    {
-        static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this);
-        tails.push_back(std::make_pair(std::get<2>(out), std::get<3>(out)));
-    }
+	std::vector<std::pair<const automaton::State*, const automaton::State*>> tails;
+	for(const auto& element : concatenation.getElements())
+	{
+		static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this);
+		tails.push_back(std::make_pair(std::get<2>(out), std::get<3>(out)));
+	}
 
-    for(size_t i = 1; i < tails.size(); i++)
-        automaton.addTransition(*tails[i-1].second, string::Epsilon::EPSILON, *tails[i].first);
+	for(size_t i = 1; i < tails.size(); i++)
+		automaton.addTransition(*tails[i-1].second, string::Epsilon::EPSILON, *tails[i].first);
 
-    std::get<2>(out) = tails[0].first;
-    std::get<3>(out) = tails[tails.size()-1].second;
+	std::get<2>(out) = tails[0].first;
+	std::get<3>(out) = tails[tails.size()-1].second;
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration)
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
-
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
-
-    static_cast<const regexp::UnboundedRegExpElement&>(iteration.getElement()).Accept(userData, *this);
-    automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
-    automaton.addTransition(head, string::Epsilon::EPSILON, tail);
-    automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
-    automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, *std::get<2>(out));
-
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
+
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
+
+	static_cast<const regexp::UnboundedRegExpElement&>(iteration.getElement()).Accept(userData, *this);
+	automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out));
+	automaton.addTransition(head, string::Epsilon::EPSILON, tail);
+	automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, tail);
+	automaton.addTransition(*std::get<3>(out), string::Epsilon::EPSILON, *std::get<2>(out));
+
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol)
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    automaton.addTransition(head, symbol.getSymbol(), tail);
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	automaton.addTransition(head, symbol.getSymbol(), tail);
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&)
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    automaton.addTransition(head, string::Epsilon::EPSILON, tail);
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	automaton.addTransition(head, string::Epsilon::EPSILON, tail);
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
-void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&)
+void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const
 {
-    std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
-    automaton::EpsilonNFA& automaton = std::get<0>(out);
+	std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData;
+	automaton::EpsilonNFA& automaton = std::get<0>(out);
 
-    automaton::State head = automaton::State(std::get<1>(out)++);
-    automaton::State tail = automaton::State(std::get<1>(out)++);
-    automaton.addState(head);
-    automaton.addState(tail);
+	automaton::State head = automaton::State(std::get<1>(out)++);
+	automaton::State tail = automaton::State(std::get<1>(out)++);
+	automaton.addState(head);
+	automaton.addState(tail);
 
-    std::get<2>(out) = &(*automaton.getStates().find(head));
-    std::get<3>(out) = &(*automaton.getStates().find(tail));
+	std::get<2>(out) = &(*automaton.getStates().find(head));
+	std::get<3>(out) = &(*automaton.getStates().find(tail));
 }
 
+const Thompson Thompson::THOMPSON;
+
 } /* namespace re2fa */
 
 } /* namespace conversions */
diff --git a/alib2algo/src/conversions/re2fa/Thompson.h b/alib2algo/src/conversions/re2fa/Thompson.h
index 6b82bc9a7a..d3365ec0b9 100644
--- a/alib2algo/src/conversions/re2fa/Thompson.h
+++ b/alib2algo/src/conversions/re2fa/Thompson.h
@@ -2,7 +2,7 @@
  * Thompson.h
  *
  *  Created on: 11. 1. 2014
- *      Author: tomas
+ *	  Author: Tomas Pecka
  */
 
 #ifndef THOMPSON_H_
@@ -27,34 +27,38 @@ namespace re2fa
  *  http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.21.7450&rep=rep1&type=ps
  *  Melichar 2.112
  */
-class Thompson : public regexp::VisitableRegExpBase::visitor_type, regexp::FormalRegExpElement::visitor_type, regexp::UnboundedRegExpElement::visitor_type
+class Thompson : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type
 {
 public:
-    /**
-     * Performs conversion.
-     * @return nondeterministic finite automaton with epsilon transitions accepting language described by the regexp
-     */
-    Thompson(void);
-    ~Thompson(void);
-    automaton::EpsilonNFA convert(const regexp::RegExp& regexp);
+	/**
+	 * Performs conversion.
+	 * @param regexp regexp to convert
+	 * @return nondeterministic finite automaton with epsilon transitions accepting language described by the regexp
+	 */
+	static automaton::EpsilonNFA convert(const regexp::RegExp& regexp);
+
+	template<class T>
+	static automaton::EpsilonNFA convert(const T& regexp);
 
 private:
-     void Visit(void*, const regexp::UnboundedRegExp& regexp);
-     void Visit(void*, const regexp::FormalRegExp& regexp);
+	 void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
+	 void Visit(void*, const regexp::FormalRegExp& regexp) const;
+
+	 void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const;
+	 void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const;
+	 void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const;
+	 void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const;
+	 void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const;
+	 void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const;
 
-     void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation);
-     void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation);
-     void Visit(void*, const regexp::UnboundedRegExpIteration& iteration);
-     void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol);
-     void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon);
-     void Visit(void*, const regexp::UnboundedRegExpEmpty& empty);
+	 void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const;
+	 void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const;
+	 void Visit(void*, const regexp::FormalRegExpIteration& iteration) const;
+	 void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const;
+	 void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const;
+	 void Visit(void*, const regexp::FormalRegExpEmpty& empty) const;
 
-     void Visit(void*, const regexp::FormalRegExpAlternation& alternation);
-     void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation);
-     void Visit(void*, const regexp::FormalRegExpIteration& iteration);
-     void Visit(void*, const regexp::FormalRegExpSymbol& symbol);
-     void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon);
-     void Visit(void*, const regexp::FormalRegExpEmpty& empty);
+	 static const Thompson THOMPSON;
 };
 
 } /* namespace re2fa */
-- 
GitLab