From b0d97d1408f57a483fe4a20ca6e209a36f9e8fe8 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Wed, 22 Oct 2014 18:38:52 +0200
Subject: [PATCH] unify default convertors

---
 alib2algo/src/automaton/convert/ToGrammar.cpp |  94 +++++++
 alib2algo/src/automaton/convert/ToGrammar.h   |  55 +++++
 alib2algo/src/automaton/convert/ToRegExp.cpp  |  98 ++++++++
 alib2algo/src/automaton/convert/ToRegExp.h    |  56 +++++
 alib2algo/src/grammar/convert/ToAutomaton.cpp | 232 ++++++++++--------
 alib2algo/src/grammar/convert/ToAutomaton.h   |  46 ++--
 alib2algo/src/grammar/convert/ToRegExp.cpp    |  87 +++++++
 alib2algo/src/grammar/convert/ToRegExp.h      |  52 ++++
 alib2algo/src/regexp/convert/ToAutomaton.cpp  |  40 +++
 alib2algo/src/regexp/convert/ToAutomaton.h    |  42 ++++
 .../regexp/convert/ToAutomatonGlushkov.cpp    |   5 +
 alib2algo/src/regexp/convert/ToGrammar.cpp    |  41 ++++
 alib2algo/src/regexp/convert/ToGrammar.h      |  38 +++
 .../convert/ToGrammarRightRGDerivation.cpp    |   2 +-
 .../convert/ToGrammarRightRGGlushkov.cpp      |   3 +
 15 files changed, 773 insertions(+), 118 deletions(-)
 create mode 100644 alib2algo/src/automaton/convert/ToGrammar.cpp
 create mode 100644 alib2algo/src/automaton/convert/ToGrammar.h
 create mode 100644 alib2algo/src/automaton/convert/ToRegExp.cpp
 create mode 100644 alib2algo/src/automaton/convert/ToRegExp.h
 create mode 100644 alib2algo/src/grammar/convert/ToRegExp.cpp
 create mode 100644 alib2algo/src/grammar/convert/ToRegExp.h
 create mode 100644 alib2algo/src/regexp/convert/ToAutomaton.cpp
 create mode 100644 alib2algo/src/regexp/convert/ToAutomaton.h
 create mode 100644 alib2algo/src/regexp/convert/ToGrammar.cpp
 create mode 100644 alib2algo/src/regexp/convert/ToGrammar.h

diff --git a/alib2algo/src/automaton/convert/ToGrammar.cpp b/alib2algo/src/automaton/convert/ToGrammar.cpp
new file mode 100644
index 0000000000..14c933d7fe
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToGrammar.cpp
@@ -0,0 +1,94 @@
+/*
+ * ToGrammarLeftRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: ToGrammarmas Pecka
+ */
+
+#include "ToGrammar.h"
+#include "ToGrammarRightRG.h"
+#include <exception/AlibException.h>
+
+namespace automaton {
+
+namespace convert {
+
+grammar::Grammar ToGrammar::convert(const automaton::Automaton& automaton) {
+	grammar::Grammar* out = NULL;
+	automaton.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToGrammar::Visit(void*, const automaton::EpsilonNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type EpsilonNFA");
+}
+
+void ToGrammar::Visit(void*, const automaton::MultiInitialStateNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type MultiInitialStateNFA");
+}
+
+void ToGrammar::Visit(void* data, const automaton::NFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(ToGrammarRightRG::convert(automaton));
+}
+
+void ToGrammar::Visit(void* data, const automaton::DFA& automaton) const {
+	grammar::Grammar* & out = *((grammar::Grammar**) data);
+	out = new grammar::Grammar(ToGrammarRightRG::convert(automaton));
+}
+
+void ToGrammar::Visit(void*, const automaton::ExtendedNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type ExtendedNFA");
+}
+
+void ToGrammar::Visit(void*, const automaton::CompactNFA& ) const {
+	throw exception::AlibException("Unsupported automaton type CompactNFA");
+}
+
+void ToGrammar::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void ToGrammar::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void ToGrammar::Visit(void*, const InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void ToGrammar::Visit(void*, const VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void ToGrammar::Visit(void*, const VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void ToGrammar::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void ToGrammar::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
+}
+
+void ToGrammar::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void ToGrammar::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void ToGrammar::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const ToGrammar ToGrammar::TO_GRAMMAR;
+
+} /* namespace convert */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/convert/ToGrammar.h b/alib2algo/src/automaton/convert/ToGrammar.h
new file mode 100644
index 0000000000..5a25ba02cb
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToGrammar.h
@@ -0,0 +1,55 @@
+/*
+ * ToGrammar.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef _AUTOMATON_TO_GRAMMAR_H__
+#define _AUTOMATON_TO_GRAMMAR_H__
+
+#include <grammar/Regular/LeftRG.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/DFA.h>
+
+#include <grammar/Grammar.h>
+#include <automaton/Automaton.h>
+
+namespace automaton {
+
+namespace convert {
+
+class ToGrammar : public automaton::VisitableAutomatonBase::const_visitor_type {
+public:
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static grammar::Grammar convert(const automaton::Automaton& automaton);
+
+private:
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
+	void Visit(void*, const InputDrivenNPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
+	void Visit(void*, const NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const ToGrammar TO_GRAMMAR;
+};
+
+} /* namespace convert */
+
+} /* namespace automaton */
+
+#endif /* _AUTOMATON_TO_GRAMMAR_H__ */
diff --git a/alib2algo/src/automaton/convert/ToRegExp.cpp b/alib2algo/src/automaton/convert/ToRegExp.cpp
new file mode 100644
index 0000000000..f3aed4a1eb
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToRegExp.cpp
@@ -0,0 +1,98 @@
+/*
+ * ToRegExpLeftRG.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: ToRegExpmas Pecka
+ */
+
+#include "ToRegExp.h"
+#include "ToRegExpStateElimination.h"
+#include <exception/AlibException.h>
+
+namespace automaton {
+
+namespace convert {
+
+regexp::RegExp ToRegExp::convert(const automaton::Automaton& automaton) {
+	regexp::RegExp* out = NULL;
+	automaton.getData().Accept((void*) &out, ToRegExp::TO_REGEXP);
+	regexp::RegExp res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToRegExp::Visit(void* data, const automaton::EpsilonNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::MultiInitialStateNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::NFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::DFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::ExtendedNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void* data, const automaton::CompactNFA& automaton) const {
+	regexp::RegExp* & out = *((regexp::RegExp**) data);
+	out = new regexp::RegExp(ToRegExpStateElimination::convert(automaton));
+}
+
+void ToRegExp::Visit(void*, const DPDA&) const {
+	throw exception::AlibException("Unsupported automaton type DPDA");
+}
+
+void ToRegExp::Visit(void*, const SinglePopDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopDPDA");
+}
+
+void ToRegExp::Visit(void*, const InputDrivenNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type InputDrivenNPDA");
+}
+
+void ToRegExp::Visit(void*, const VisiblyPushdownDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownDPDA");
+}
+
+void ToRegExp::Visit(void*, const VisiblyPushdownNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type VisiblyPushdownNPDA");
+}
+
+void ToRegExp::Visit(void*, const RealTimeHeightDeterministicDPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicDPDA");
+}
+
+void ToRegExp::Visit(void*, const RealTimeHeightDeterministicNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type RealTimeHeightDeterministicNPDA");
+}
+
+void ToRegExp::Visit(void*, const NPDA&) const {
+	throw exception::AlibException("Unsupported automaton type NPDA");
+}
+
+void ToRegExp::Visit(void*, const SinglePopNPDA&) const {
+	throw exception::AlibException("Unsupported automaton type SinglePopNPDA");
+}
+
+void ToRegExp::Visit(void*, const OneTapeDTM&) const {
+	throw exception::AlibException("Unsupported automaton type OneTapeDTM");
+}
+
+const ToRegExp ToRegExp::TO_REGEXP;
+
+} /* namespace convert */
+
+} /* namespace automaton */
diff --git a/alib2algo/src/automaton/convert/ToRegExp.h b/alib2algo/src/automaton/convert/ToRegExp.h
new file mode 100644
index 0000000000..b525181950
--- /dev/null
+++ b/alib2algo/src/automaton/convert/ToRegExp.h
@@ -0,0 +1,56 @@
+/*
+ * ToRegExp.h
+ *
+ *  Created on: 9. 2. 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef _AUTOMATON_TO_REGEXP_H__
+#define _AUTOMATON_TO_REGEXP_H__
+
+#include <automaton/FSM/DFA.h>
+#include <automaton/FSM/NFA.h>
+#include <automaton/FSM/EpsilonNFA.h>
+#include <regexp/unbounded/UnboundedRegExp.h>
+
+#include <automaton/Automaton.h>
+#include <regexp/RegExp.h>
+
+namespace automaton {
+
+namespace convert {
+
+class ToRegExp : public automaton::VisitableAutomatonBase::const_visitor_type {
+public:
+	/**
+	 * Performs conversion.
+	 * @return left regular grammar equivalent to source automaton.
+	 */
+	static regexp::RegExp convert(const automaton::Automaton& automaton);
+
+private:
+	void Visit(void*, const EpsilonNFA& automaton) const;
+	void Visit(void*, const MultiInitialStateNFA& automaton) const;
+	void Visit(void*, const NFA& automaton) const;
+	void Visit(void*, const DFA& automaton) const;
+	void Visit(void*, const ExtendedNFA& automaton) const;
+	void Visit(void*, const CompactNFA& automaton) const;
+	void Visit(void*, const DPDA& automaton) const;
+	void Visit(void*, const SinglePopDPDA& automaton) const;
+	void Visit(void*, const InputDrivenNPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownDPDA& automaton) const;
+	void Visit(void*, const VisiblyPushdownNPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicDPDA& automaton) const;
+	void Visit(void*, const RealTimeHeightDeterministicNPDA& automaton) const;
+	void Visit(void*, const NPDA& automaton) const;
+	void Visit(void*, const SinglePopNPDA& automaton) const;
+	void Visit(void*, const OneTapeDTM& automaton) const;
+
+	static const ToRegExp TO_REGEXP;
+};
+
+} /* namespace convert */
+
+} /* namespace automaton */
+
+#endif /* _AUTOMATON_TO_REGEXP_H__ */
diff --git a/alib2algo/src/grammar/convert/ToAutomaton.cpp b/alib2algo/src/grammar/convert/ToAutomaton.cpp
index e7c6938db3..68a1e5ca47 100644
--- a/alib2algo/src/grammar/convert/ToAutomaton.cpp
+++ b/alib2algo/src/grammar/convert/ToAutomaton.cpp
@@ -15,128 +15,164 @@ namespace convert {
 
 automaton::Automaton ToAutomaton::convert(const grammar::Grammar& grammar)
 {
-     automaton::Automaton* out = NULL;
-     grammar.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON);
-     automaton::Automaton res = std::move(*out);
-     delete out;
-     return res;
+	 automaton::Automaton* out = NULL;
+	 grammar.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON);
+	 automaton::Automaton res = std::move(*out);
+	 delete out;
+	 return res;
 }
 
 automaton::NFA ToAutomaton::convert(const grammar::LeftRG& grammar)
 {
-    std::map<alphabet::Symbol, automaton::State> stateMap;
-    std::set<automaton::State> states;
-
-    // step 2
-    for(const auto& symbol : grammar.getNonterminalAlphabet())
-    {
-        automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
-        states.insert(state);
-        stateMap.insert(std::make_pair(symbol, state));
-    }
-
-    // step 1, 4
-    const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states);
-    states.insert(q0);
-    automaton::NFA automaton(q0);
-    automaton.setInputSymbols(grammar.getTerminalAlphabet());
-    automaton.setStates(states);
-
-    // step 3
-    for(const auto& rule : grammar.getRules())
-    {
-        const alphabet::Symbol& lhs = rule.first;
-        for(const auto& ruleRHS : rule.second)
-        {
-            if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B
-            {
-                const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
-                automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second);
-            }
-            else // if B->a => \delta(StartState,a)=B
-            {
-                const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
-                automaton.addTransition(q0, rhs, stateMap.find(lhs)->second);
-            }
-        }
-    }
-
-    // step 5
-    automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second);
-    if(grammar.getGeneratesEpsilon())
-        automaton.addFinalState(q0);
-
-    return automaton;
+	std::map<alphabet::Symbol, automaton::State> stateMap;
+	std::set<automaton::State> states;
+
+	// step 2
+	for(const auto& symbol : grammar.getNonterminalAlphabet())
+	{
+		automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
+		states.insert(state);
+		stateMap.insert(std::make_pair(symbol, state));
+	}
+
+	// step 1, 4
+	const automaton::State q0 = automaton::createUniqueState(automaton::State("q0"), states);
+	states.insert(q0);
+	automaton::NFA automaton(q0);
+	automaton.setInputSymbols(grammar.getTerminalAlphabet());
+	automaton.setStates(states);
+
+	// step 3
+	for(const auto& rule : grammar.getRules())
+	{
+		const alphabet::Symbol& lhs = rule.first;
+		for(const auto& ruleRHS : rule.second)
+		{
+			if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->Ca => \delta(C,a)=B
+			{
+				const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+				automaton.addTransition(stateMap.find(rhs.first)->second, rhs.second, stateMap.find(lhs)->second);
+			}
+			else // if B->a => \delta(StartState,a)=B
+			{
+				const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
+				automaton.addTransition(q0, rhs, stateMap.find(lhs)->second);
+			}
+		}
+	}
+
+	// step 5
+	automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second);
+	if(grammar.getGeneratesEpsilon())
+		automaton.addFinalState(q0);
+
+	return automaton;
 }
 
 automaton::NFA ToAutomaton::convert(const grammar::RightRG& grammar)
 {
-    std::map<alphabet::Symbol, automaton::State> stateMap;
-    std::set<automaton::State> states;
-
-    // step2
-    for(const auto& symbol : grammar.getNonterminalAlphabet())
-    {
-        automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
-        states.insert(state);
-        stateMap.insert(std::make_pair(symbol, state));
-    }
-
-    // step 1, 4
-    const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states);
-    states.insert(AState);
-    automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second);
-    automaton.setStates(states);
-
-    automaton.setInputSymbols(grammar.getTerminalAlphabet());
-
-    // step 3
-    for(const auto& rule : grammar.getRules())
-    {
-        const alphabet::Symbol& lhs = rule.first;
-        for(const auto& ruleRHS : rule.second)
-        {
-            if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C
-            {
-                const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
-                automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second);
-            }
-            else // if B->a => \delta(B,a)=AState
-            {
-                const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
-                automaton.addTransition(stateMap.find(lhs)->second, rhs, AState);
-            }
-        }
-    }
-
-    // step 5
-    automaton.addFinalState(AState);
-    if(grammar.getGeneratesEpsilon())
-        automaton.addFinalState(automaton.getInitialState());
-
-    return automaton;
+	std::map<alphabet::Symbol, automaton::State> stateMap;
+	std::set<automaton::State> states;
+
+	// step2
+	for(const auto& symbol : grammar.getNonterminalAlphabet())
+	{
+		automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
+		states.insert(state);
+		stateMap.insert(std::make_pair(symbol, state));
+	}
+
+	// step 1, 4
+	const automaton::State AState = automaton::createUniqueState(automaton::State("A"), states);
+	states.insert(AState);
+	automaton::NFA automaton(stateMap.find(grammar.getInitialSymbol())->second);
+	automaton.setStates(states);
+
+	automaton.setInputSymbols(grammar.getTerminalAlphabet());
+
+	// step 3
+	for(const auto& rule : grammar.getRules())
+	{
+		const alphabet::Symbol& lhs = rule.first;
+		for(const auto& ruleRHS : rule.second)
+		{
+			if(ruleRHS.is<std::pair<alphabet::Symbol, alphabet::Symbol>>()) // if B->aC => \delta(B,a)=C
+			{
+				const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = ruleRHS.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+				automaton.addTransition(stateMap.find(lhs)->second, rhs.first, stateMap.find(rhs.second)->second);
+			}
+			else // if B->a => \delta(B,a)=AState
+			{
+				const alphabet::Symbol& rhs = ruleRHS.get<alphabet::Symbol>();
+				automaton.addTransition(stateMap.find(lhs)->second, rhs, AState);
+			}
+		}
+	}
+
+	// step 5
+	automaton.addFinalState(AState);
+	if(grammar.getGeneratesEpsilon())
+		automaton.addFinalState(automaton.getInitialState());
+
+	return automaton;
 }
 
 void ToAutomaton::Visit(void* userData, const grammar::RightRG& grammar) const
 {
-    automaton::Automaton* & out = *((automaton::Automaton**) userData);
-    out = new automaton::Automaton(this->convert(grammar));
+	automaton::Automaton* & out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(grammar));
 }
 
 void ToAutomaton::Visit(void* userData, const grammar::LeftRG& grammar) const
 {
-    automaton::Automaton* & out = *((automaton::Automaton**) userData);
-    out = new automaton::Automaton(this->convert(grammar));
+	automaton::Automaton* & out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(this->convert(grammar));
 }
 
 void ToAutomaton::Visit(void*, const grammar::RightLG&) const
 {
-    throw exception::AlibException("Unsupported grammar type RightLG");
+	throw exception::AlibException("Unsupported grammar type RightLG");
 }
 
 void ToAutomaton::Visit(void*, const grammar::LeftLG&) const
 {
-    throw exception::AlibException("Unsupported grammar type LeftLG");
+	throw exception::AlibException("Unsupported grammar type LeftLG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::LG& ) const {
+	throw exception::AlibException("Unsupported grammar type LG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::CFG& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::EpsilonFreeCFG& ) const {
+	throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::CNF& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::GNF& ) const {
+	throw exception::AlibException("Unsupported grammar type GNF");
+}
+
+void ToAutomaton::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void ToAutomaton::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void ToAutomaton::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void ToAutomaton::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
 }
 
 const ToAutomaton ToAutomaton::TO_AUTOMATON;
diff --git a/alib2algo/src/grammar/convert/ToAutomaton.h b/alib2algo/src/grammar/convert/ToAutomaton.h
index 2f069ef9e6..aeea0edfbc 100644
--- a/alib2algo/src/grammar/convert/ToAutomaton.h
+++ b/alib2algo/src/grammar/convert/ToAutomaton.h
@@ -5,8 +5,8 @@
  * Author: Tomas Pecka
  */
 
-#ifndef _TO_AUTOMATON_H_
-#define _TO_AUTOMATON_H_
+#ifndef _GRAMMAR_TO_AUTOMATON_H_
+#define _GRAMMAR_TO_AUTOMATON_H_
 
 #include <grammar/Grammar.h>
 #include <grammar/Regular/LeftRG.h>
@@ -23,30 +23,38 @@ namespace convert {
  * Converts regular grammar to nondeterministic finite automaton.
  * Sources: Melichar 2.98 (RightRG -> NFA) and 2.102 (LeftRG -> NFA).
  */
-class ToAutomaton : public grammar::VisitableConstRGBase
-{
+class ToAutomaton : public grammar::VisitableGrammarBase::const_visitor_type {
 public:
-    /**
-     * Performs conversion.
-     * @param grammar Regular grammar to convert.
-     * @return FSM equivalent to source grammar.
-     */
-    static automaton::Automaton convert(const grammar::Grammar& grammar);
+	/**
+	 * Performs conversion.
+	 * @param grammar Regular grammar to convert.
+	 * @return FSM equivalent to source grammar.
+	 */
+	static automaton::Automaton convert(const grammar::Grammar& grammar);
 
-    static automaton::NFA convert(const grammar::LeftRG& grammar);
-    static automaton::NFA convert(const grammar::RightRG& grammar);
+	static automaton::NFA convert(const grammar::LeftRG& grammar);
+	static automaton::NFA convert(const grammar::RightRG& grammar);
 
 private:
-    void Visit(void*, const grammar::RightRG& grammar) const;
-    void Visit(void*, const grammar::LeftRG& grammar) const;
-    void Visit(void*, const grammar::RightLG& grammar) const;
-    void Visit(void*, const grammar::LeftLG& grammar) const;
-
-    static const ToAutomaton TO_AUTOMATON;
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::LeftLG& grammar) const;
+	void Visit(void*, const grammar::LG& grammar) const;
+	void Visit(void*, const grammar::CFG& grammar) const;
+	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
+	void Visit(void*, const grammar::CNF& grammar) const;
+	void Visit(void*, const grammar::GNF& grammar) const;
+	void Visit(void*, const grammar::CSG& grammar) const;
+	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
+	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
+	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
+
+	static const ToAutomaton TO_AUTOMATON;
 };
 
 } /* namespace convert */
 
 } /* namespace grammar */
 
-#endif /* _TO_AUTOMATON_H_ */
+#endif /* _GRAMMAR_TO_AUTOMATON_H_ */
diff --git a/alib2algo/src/grammar/convert/ToRegExp.cpp b/alib2algo/src/grammar/convert/ToRegExp.cpp
new file mode 100644
index 0000000000..fe2696f7f4
--- /dev/null
+++ b/alib2algo/src/grammar/convert/ToRegExp.cpp
@@ -0,0 +1,87 @@
+/*
+ * ToRegExp.cpp
+ *
+ *  Created on: 4. 3. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#include "ToRegExp.h"
+#include "ToRegExpAlgebraic.h"
+#include <exception/AlibException.h>
+
+namespace grammar {
+
+namespace convert {
+
+regexp::RegExp ToRegExp::convert(const grammar::Grammar& grammar)
+{
+	regexp::RegExp* out = NULL;
+	grammar.getData().Accept((void*) &out, ToRegExp::TO_REG_EXP);
+	regexp::RegExp res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToRegExp::Visit(void* userData, const grammar::RightRG& grammar) const
+{
+	regexp::RegExp* & out = *((regexp::RegExp**) userData);
+	out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar));
+}
+
+void ToRegExp::Visit(void* userData, const grammar::LeftRG& grammar) const
+{
+	regexp::RegExp* & out = *((regexp::RegExp**) userData);
+	out = new regexp::RegExp(ToRegExpAlgebraic::convert(grammar));
+}
+
+void ToRegExp::Visit(void*, const grammar::RightLG&) const
+{
+	throw exception::AlibException("Unsupported grammar type RightLG");
+}
+
+void ToRegExp::Visit(void*, const grammar::LeftLG&) const
+{
+	throw exception::AlibException("Unsupported grammar type LeftLG");
+}
+
+void ToRegExp::Visit(void*, const grammar::LG& ) const {
+	throw exception::AlibException("Unsupported grammar type LG");
+}
+
+void ToRegExp::Visit(void*, const grammar::CFG& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToRegExp::Visit(void*, const grammar::EpsilonFreeCFG& ) const {
+	throw exception::AlibException("Unsupported grammar type EpsilonFreeCFG");
+}
+
+void ToRegExp::Visit(void*, const grammar::CNF& ) const {
+	throw exception::AlibException("Unsupported grammar type CFG");
+}
+
+void ToRegExp::Visit(void*, const grammar::GNF& ) const {
+	throw exception::AlibException("Unsupported grammar type GNF");
+}
+
+void ToRegExp::Visit(void*, const grammar::CSG&) const {
+	throw exception::AlibException("Unsupported grammar type CSG");
+}
+
+void ToRegExp::Visit(void*, const grammar::NonContractingGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type NonConctractingGrammar");
+}
+
+void ToRegExp::Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type ContextPreservingUnrestrictedGrammar");
+}
+
+void ToRegExp::Visit(void*, const grammar::UnrestrictedGrammar&) const {
+	throw exception::AlibException("Unsupported grammar type UnrestrictedGrammar");
+}
+
+const ToRegExp ToRegExp::TO_REG_EXP;
+
+} /* namespace convert */
+
+} /* namespace grammar */
diff --git a/alib2algo/src/grammar/convert/ToRegExp.h b/alib2algo/src/grammar/convert/ToRegExp.h
new file mode 100644
index 0000000000..aace07b45d
--- /dev/null
+++ b/alib2algo/src/grammar/convert/ToRegExp.h
@@ -0,0 +1,52 @@
+/*
+ * ToRegExp.h
+ *
+ *  Created on: 4. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef GRAMMAR_TO_REG_EXP_H_
+#define GRAMMAR_TO_REG_EXP_H_
+
+#include <grammar/Grammar.h>
+#include <grammar/Regular/RightRG.h>
+#include <grammar/Regular/LeftRG.h>
+
+#include <regexp/RegExp.h>
+
+namespace grammar {
+
+namespace convert {
+
+class ToRegExp : public grammar::VisitableConstRGBase
+{
+public:
+	/**
+	 * @return regexp equivalent to source right regular grammar.
+	 * @param grammar Grammar to convert
+	 */
+	static regexp::RegExp convert(const grammar::Grammar& grammar);
+
+protected:
+	void Visit(void*, const grammar::RightRG& grammar) const;
+	void Visit(void*, const grammar::LeftRG& grammar) const;
+	void Visit(void*, const grammar::RightLG& grammar) const;
+	void Visit(void*, const grammar::LeftLG& grammar) const;
+	void Visit(void*, const grammar::LG& grammar) const;
+	void Visit(void*, const grammar::CFG& grammar) const;
+	void Visit(void*, const grammar::EpsilonFreeCFG& grammar) const;
+	void Visit(void*, const grammar::CNF& grammar) const;
+	void Visit(void*, const grammar::GNF& grammar) const;
+	void Visit(void*, const grammar::CSG& grammar) const;
+	void Visit(void*, const grammar::NonContractingGrammar& grammar) const;
+	void Visit(void*, const grammar::ContextPreservingUnrestrictedGrammar& grammar) const;
+	void Visit(void*, const grammar::UnrestrictedGrammar& grammar) const;
+
+	static const ToRegExp TO_REG_EXP;
+};
+
+} /* namespace covert */
+
+} /* namespace grammar */
+
+#endif /* GRAMMAR_TO_REG_EXP_H_ */
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.cpp b/alib2algo/src/regexp/convert/ToAutomaton.cpp
new file mode 100644
index 0000000000..781ecccc3f
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToAutomaton.cpp
@@ -0,0 +1,40 @@
+/*
+ * ToAutomaton.cpp
+ *
+ *  Created on: 11. 1. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "ToAutomaton.h"
+#include "ToAutomatonGlushkov.h"
+#include <exception/AlibException.h>
+
+namespace regexp {
+
+namespace convert {
+
+automaton::Automaton ToAutomaton::convert(const regexp::RegExp& regexp)
+{
+	automaton::Automaton* out = NULL;
+	regexp.getData().Accept((void*) &out, ToAutomaton::TO_AUTOMATON);
+	automaton::Automaton res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToAutomaton::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+{
+	automaton::Automaton* &out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
+}
+void ToAutomaton::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+	automaton::Automaton* &out = *((automaton::Automaton**) userData);
+	out = new automaton::Automaton(ToAutomatonGlushkov::convert(regexp));
+}
+
+const ToAutomaton ToAutomaton::TO_AUTOMATON;
+
+} /* namespace convert */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/convert/ToAutomaton.h b/alib2algo/src/regexp/convert/ToAutomaton.h
new file mode 100644
index 0000000000..9894aff997
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToAutomaton.h
@@ -0,0 +1,42 @@
+/*
+ * RegExpToAutomaton.h
+ *
+ *  Created on: 11. 1. 2014
+ *	  Author: Tomas Pecka
+ */
+
+#ifndef REG_EXP_TO_AUTOMATON_H_
+#define REG_EXP_TO_AUTOMATON_H_
+
+#include <regexp/RegExp.h>
+#include <regexp/formal/FormalRegExp.h>
+#include <regexp/unbounded/UnboundedRegExp.h>
+
+#include <automaton/Automaton.h>
+#include <automaton/FSM/NFA.h>
+
+namespace regexp {
+
+namespace convert {
+
+class ToAutomaton : public regexp::VisitableRegExpBase::const_visitor_type
+{
+public:
+	/**
+	 * Performs conversion.
+	 * @return FSM equivalent to original regular expression.
+	 */
+	static automaton::Automaton convert(const regexp::RegExp& regexp);
+
+private:
+	void Visit(void*, const regexp::FormalRegExp& regexp) const;
+	void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
+
+	static const ToAutomaton TO_AUTOMATON;
+};
+
+} /* namespace convert */
+
+} /* namespace regexp */
+
+#endif /* REG_EXP_TO_AUTOMATON_H_ */
diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
index 7f25196efd..fb75db1789 100644
--- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
+++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp
@@ -83,6 +83,11 @@ automaton::NFA ToAutomatonGlushkov::convert(const regexp::UnboundedRegExp& regex
 	return automaton;
 }
 
+automaton::NFA ToAutomatonGlushkov::convert(const regexp::FormalRegExp& regexp)
+{
+	throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO
+}
+
 void ToAutomatonGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
 	/*
diff --git a/alib2algo/src/regexp/convert/ToGrammar.cpp b/alib2algo/src/regexp/convert/ToGrammar.cpp
new file mode 100644
index 0000000000..0eb7d88c9b
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToGrammar.cpp
@@ -0,0 +1,41 @@
+/*
+ * ToGrammar.cpp
+ *
+ *  Created on: 6. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#include "ToGrammar.h"
+#include "ToGrammarRightRGGlushkov.h"
+#include <exception/AlibException.h>
+
+namespace regexp {
+
+namespace convert {
+
+grammar::Grammar ToGrammar::convert(const regexp::RegExp& regexp)
+{
+	grammar::Grammar* out = NULL;
+	regexp.getData().Accept((void*) &out, ToGrammar::TO_GRAMMAR);
+	grammar::Grammar res = std::move(*out);
+	delete out;
+	return res;
+}
+
+void ToGrammar::Visit(void* userData, const regexp::FormalRegExp& regexp) const
+{
+	grammar::Grammar* &out = *((grammar::Grammar**) userData);
+	out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
+}
+
+void ToGrammar::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const
+{
+	grammar::Grammar* &out = *((grammar::Grammar**) userData);
+	out = new grammar::Grammar(ToGrammarRightRGGlushkov::convert(regexp));
+}
+
+const ToGrammar ToGrammar::TO_GRAMMAR;
+
+} /* namespace convert */
+
+} /* namespace regexp */
diff --git a/alib2algo/src/regexp/convert/ToGrammar.h b/alib2algo/src/regexp/convert/ToGrammar.h
new file mode 100644
index 0000000000..de8438c541
--- /dev/null
+++ b/alib2algo/src/regexp/convert/ToGrammar.h
@@ -0,0 +1,38 @@
+/*
+ * ToGrammar.h
+ *
+ *  Created on: 6. 3. 2014
+ *	  Author: Jan Travnicek
+ */
+
+#ifndef REG_EXP_TO_GRAMMAR_H_
+#define REG_EXP_TO_GRAMMAR_H_
+
+#include <grammar/Grammar.h>
+#include <regexp/RegExp.h>
+
+namespace regexp {
+
+namespace convert {
+
+class ToGrammar : public regexp::VisitableRegExpBase::const_visitor_type
+{
+public:
+	/**
+	 * Performs conversion.
+	 * @return right regular grammar equivalent to source regexp.
+	 */
+	static grammar::Grammar convert(const regexp::RegExp& regexp);
+
+private:
+	void Visit(void*, const regexp::FormalRegExp& regexp) const;
+	void Visit(void*, const regexp::UnboundedRegExp& regexp) const;
+
+	static const ToGrammar TO_GRAMMAR;
+};
+
+} /* namespace convert */
+
+} /* namespace regexp */
+
+#endif /* REG_EXP_TO_GRAMMAR_H_ */
diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
index 1268ed6f7e..1f9106c2a9 100644
--- a/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGDerivation.cpp
@@ -2,7 +2,7 @@
  * ToGrammarRightRGDerivation.cpp
  *
  *  Created on: 6. 3. 2014
- *	  Author: tomas
+ *	  Author: Tomas Pecka
  */
 
 #include "ToGrammarRightRGDerivation.h"
diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
index d60fa098d1..cb1ba5388b 100644
--- a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
+++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp
@@ -93,6 +93,9 @@ grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::UnboundedRegExp
     return grammar;
 }
 
+grammar::RightRG ToGrammarRightRGGlushkov::convert(const regexp::FormalRegExp& regexp) {
+    throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO
+}
 
 void ToGrammarRightRGGlushkov::Visit(void* userData, const regexp::FormalRegExp& regexp) const
 {
-- 
GitLab