diff --git a/alib2algo/src/grammar/simplify/ToCNF.cpp b/alib2algo/src/grammar/simplify/ToCNF.cpp
index 3b5fc083ac040c715269a5f9e4a866f00a304a62..4c658b89f0b172147021179c453f37b42ceaf5d6 100644
--- a/alib2algo/src/grammar/simplify/ToCNF.cpp
+++ b/alib2algo/src/grammar/simplify/ToCNF.cpp
@@ -11,7 +11,6 @@
 #include "SimpleRulesRemover.h"
 #include <common/DefaultSymbolsPairType.h>
 #include <exception/CommonException.h>
-#include <common/createUnique.hpp>
 #include <registration/AlgoRegistration.hpp>
 
 #include <grammar/RawRules.h>
@@ -128,10 +127,6 @@ grammar::CNF < > ToCNF::convert(const grammar::EpsilonFreeCFG < > & origGrammar)
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(origGrammar));
 }
 
-grammar::CNF < > ToCNF::convert(const grammar::CNF < > & origGrammar) {
-	return origGrammar;
-}
-
 grammar::CNF < > ToCNF::convert(const grammar::GNF < > & origGrammar) {
 	return convertInternal(origGrammar);
 }
@@ -144,18 +139,10 @@ grammar::CNF < > ToCNF::convert(const grammar::LeftLG< > & origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
 }
 
-grammar::CNF < > ToCNF::convert(const grammar::LeftRG < > & origGrammar) {
-	return convertInternal(origGrammar);
-}
-
 grammar::CNF < > ToCNF::convert(const grammar::RightLG < > & origGrammar) {
 	return convertInternal(grammar::simplify::SimpleRulesRemover::remove(grammar::simplify::EpsilonRemover::remove(origGrammar)));
 }
 
-grammar::CNF < > ToCNF::convert(const grammar::RightRG < > & origGrammar) {
-	return convertInternal(origGrammar);
-}
-
 auto ToCNFCFG = registration::AbstractRegister < ToCNF, grammar::CNF < >, const grammar::CFG < > & > ( ToCNF::convert );
 auto ToCNFEpsilonFreeCFG = registration::AbstractRegister < ToCNF, grammar::CNF < >, const grammar::EpsilonFreeCFG < > & > ( ToCNF::convert );
 auto ToCNFCNF = registration::AbstractRegister < ToCNF, grammar::CNF < >, const grammar::CNF < > & > ( ToCNF::convert );
diff --git a/alib2algo/src/grammar/simplify/ToCNF.h b/alib2algo/src/grammar/simplify/ToCNF.h
index d1d96976f384a27150b9840bc38ab1a77b3cb5c4..88165da16012c3d875affa9fdc54e0ad9186d01c 100644
--- a/alib2algo/src/grammar/simplify/ToCNF.h
+++ b/alib2algo/src/grammar/simplify/ToCNF.h
@@ -18,6 +18,8 @@
 #include <grammar/Regular/RightLG.h>
 #include <grammar/Regular/RightRG.h>
 
+#include <common/createUnique.hpp>
+
 namespace grammar {
 
 namespace simplify {
@@ -25,16 +27,90 @@ namespace simplify {
 class ToCNF {
 public:
 	static grammar::CNF < > convert( const grammar::CFG < > & grammar );
+
 	static grammar::CNF < > convert( const grammar::EpsilonFreeCFG < > & grammar );
+
 	static grammar::CNF < > convert( const grammar::GNF < > & grammar );
-	static grammar::CNF < > convert( const grammar::CNF < > & grammar );
+
+	template < class SymbolType >
+	static grammar::CNF < SymbolType > convert( const grammar::CNF < SymbolType > & grammar );
+
 	static grammar::CNF < > convert( const grammar::LG < > & grammar );
+
 	static grammar::CNF < > convert( const grammar::LeftLG < > & grammar );
-	static grammar::CNF < > convert( const grammar::LeftRG < > & grammar );
+
+	template < class SymbolType >
+	static grammar::CNF < SymbolType > convert( const grammar::LeftRG < SymbolType > & grammar );
+
 	static grammar::CNF < > convert( const grammar::RightLG < > & grammar );
-	static grammar::CNF < > convert( const grammar::RightRG < > & grammar );
+
+	template < class SymbolType >
+	static grammar::CNF < SymbolType > convert( const grammar::RightRG < SymbolType > & grammar );
 };
 
+template < class SymbolType >
+grammar::CNF < SymbolType > ToCNF::convert(const grammar::CNF < SymbolType > & origGrammar) {
+	return origGrammar;
+}
+
+template < class SymbolType >
+grammar::CNF < SymbolType > ToCNF::convert ( const grammar::LeftRG < SymbolType > & origGrammar ) {
+	grammar::CNF < SymbolType > result ( origGrammar.getInitialSymbol ( ) );
+
+	result.setNonterminalAlphabet ( origGrammar.getNonterminalAlphabet ( ) );
+	result.setTerminalAlphabet ( origGrammar.getTerminalAlphabet ( ) );
+
+	ext::map < SymbolType, SymbolType > terminalToShadowNonterminal;
+	for ( const SymbolType & symbol : origGrammar.getTerminalAlphabet ( ) ) {
+		SymbolType shadowSymbol = common::createUnique ( symbol, result.getTerminalAlphabet ( ), result.getNonterminalAlphabet ( ) );
+		terminalToShadowNonterminal.insert ( std::make_pair ( symbol, shadowSymbol ) );
+		result.addNonterminalSymbol ( shadowSymbol );
+		result.addRule ( std::move ( shadowSymbol ), symbol );
+	}
+
+	for ( const std::pair < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & rules : origGrammar.getRules ( ) ) {
+		for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rhs : rules.second ) {
+			if ( rhs.template is < SymbolType > ( ) ) {
+				result.addRule ( rules.first, rhs );
+			} else {
+				const ext::pair < SymbolType, SymbolType > & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( );
+				result.addRule ( rules.first, ext::make_pair ( rhsPair.first, terminalToShadowNonterminal.at ( rhsPair.second ) ) );
+			}
+		}
+	}
+
+	return result;
+}
+
+template < class SymbolType >
+grammar::CNF < SymbolType > ToCNF::convert ( const grammar::RightRG < SymbolType > & origGrammar ) {
+	grammar::CNF < SymbolType > result ( origGrammar.getInitialSymbol ( ) );
+
+	result.setNonterminalAlphabet ( origGrammar.getNonterminalAlphabet ( ) );
+	result.setTerminalAlphabet ( origGrammar.getTerminalAlphabet ( ) );
+
+	ext::map < SymbolType, SymbolType > terminalToShadowNonterminal;
+	for ( const SymbolType & symbol : origGrammar.getTerminalAlphabet ( ) ) {
+		SymbolType shadowSymbol = common::createUnique ( symbol, result.getTerminalAlphabet ( ), result.getNonterminalAlphabet ( ) );
+		terminalToShadowNonterminal.insert ( std::make_pair ( symbol, shadowSymbol ) );
+		result.addNonterminalSymbol ( shadowSymbol );
+		result.addRule ( std::move ( shadowSymbol ), symbol );
+	}
+
+	for ( const std::pair < SymbolType, ext::set < ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > > > & rules : origGrammar.getRules ( ) ) {
+		for ( const ext::variant < SymbolType, ext::pair < SymbolType, SymbolType > > & rhs : rules.second ) {
+			if ( rhs.template is < SymbolType > ( ) ) {
+				result.addRule ( rules.first, rhs );
+			} else {
+				const ext::pair < SymbolType, SymbolType > & rhsPair = rhs.template get < ext::pair < SymbolType, SymbolType > > ( );
+				result.addRule ( rules.first, ext::make_pair ( terminalToShadowNonterminal.at ( rhsPair.first ), rhsPair.second ) );
+			}
+		}
+	}
+
+	return result;
+}
+
 } /* namespace simplify */
 
 } /* namespace grammar */