From 13a74df01e9142ad6da6316488253f07862147ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz>
Date: Sun, 16 Mar 2014 15:42:23 +0100
Subject: [PATCH] Rewrite aconversion executable, see help

---
 .../src/aconversion/ConversionHandler.cpp     | 574 +++++++++++-------
 .../src/aconversion/ConversionHandler.h       |  91 ++-
 aconversions/src/aconversion/aconversion.cpp  |  66 +-
 3 files changed, 464 insertions(+), 267 deletions(-)

diff --git a/aconversions/src/aconversion/ConversionHandler.cpp b/aconversions/src/aconversion/ConversionHandler.cpp
index b18f150a4a..bc8b8084bc 100644
--- a/aconversions/src/aconversion/ConversionHandler.cpp
+++ b/aconversions/src/aconversion/ConversionHandler.cpp
@@ -17,204 +17,338 @@ using namespace std;
 namespace conversions
 {
 
-ConversionHandler::ConversionHandler( list<Token> & tokens, const string & target, const string & algorithm ) : m_tokens( tokens )
+ConversionHandler::ConversionHandler( list<Token> & tokens, const string & target, const string & algorithm, ostream & out ) :
+    m_tokens( tokens ),
+    m_source( parseFormalismFromTokens( ) ),
+    m_target( parseFormalismFromString( target ) ),
+    m_algorithm( parseAlgorithmFromString( algorithm ) ),
+    m_out( out )
 {
-    m_source = parseFormalismFromString( m_tokens.front( ).getData( ) );
-    m_target = parseFormalismFromString( target );
 
-    if( m_source == m_target && m_source != REGULAR_GRAMMAR )
-        throw AlibException( "Cannot convert between same formalisms." );
-
-    m_algorithm = parseAlgorithmFromString( algorithm );
-    if( m_algorithm == DEFAULT )
-        m_algorithm = getDefaultAlgorithm( );
-
-    if( ! checkAlgorithm( ) )
-        throw AlibException( "Invalid conversion. See help." );
 }
 
-void ConversionHandler::convert( ostream & out )
+void ConversionHandler::convert( void )
 {
     if( m_source == FINITE_AUTOMATA )
-        convertAutomata( out );
-    if( m_source == REGULAR_EXPRESSION )
-        convertRegExp( out );
-    if( m_source == REGULAR_GRAMMAR )
-        convertGrammar( out );
+        convertFSM( );
+    else if( m_source == REGULAR_EXPRESSION )
+        convertRE( );
+    else if( isGrammar( m_source ) )
+        convertRG( );
+    else
+        throw AlibException( "ConversionHandler: Unknown source formalism." );
 }
 
-void ConversionHandler::convertGrammar( ostream & out )
+// ----------------------------------------------------------------------------
+
+void ConversionHandler::convertFSM( void )
 {
-    const UnknownGrammar ug = GrammarParser::parse( m_tokens );
+    if( m_target == FINITE_AUTOMATA )
+        throw AlibException( "ConversionHandler: No valid conversion from FSM to FSM." );
+    else if( m_target == REGULAR_EXPRESSION )
+        convertFSMtoRE( );
+    else if( isGrammar( m_target ) )
+        convertFSMtoRG( );
+    else
+        throw AlibException( "ConversionHandler: Unknown target formalism." );
+}
 
+void ConversionHandler::convertRE( void )
+{
     if( m_target == FINITE_AUTOMATA )
-    {
-        AbstractRGtoFAConverter* conv;
-        RightRegularGrammar rrg;
-        LeftRegularGrammar lrg;
-        bool rightGrammar = true;
+        convertREtoFSM( );
+    else if( m_target == REGULAR_EXPRESSION )
+        throw AlibException( "ConversionHandler: No valid conversion from RE to RE." );
+    else if( isGrammar( m_target ) )
+        convertREtoRG( );
+    else
+        throw AlibException( "ConversionHandler: Unknown target formalism." );
+}
 
-        try
-        {
-            GrammarFactory::buildRightRegularGrammar( ug );
-        }
-        catch( AlibException & e )
-        {
-            rightGrammar = false;
-        }
+void ConversionHandler::convertRG( void )
+{
+    if( m_target == FINITE_AUTOMATA )
+        convertRGtoFSM( );
+    else if( m_target == REGULAR_EXPRESSION )
+        convertRGtoRE( );
+    else if( isGrammar( m_target ) )
+        convertRGtoRG( );
+    else
+        throw AlibException( "ConversionHandler: Unknown target formalism." );
+}
 
-        if( rightGrammar )
-        {
-            rrg = GrammarFactory::buildRightRegularGrammar( ug );
-            conv = new RRGtoFAConverter( rrg );
-        }
-        else
-        {
-            lrg = GrammarFactory::buildLeftRegularGrammar( ug );
-            conv = new LRGtoFAConverter( lrg );
-        }
+// ----------------------------------------------------------------------------
+
+void ConversionHandler::convertFSMtoRE( void )
+{
+    const FSM fsm = AutomatonFactory::buildFSM( AutomatonParser::parse( m_tokens ) );
 
-        conv->convert( ).toXML( out );
-        delete conv;
+    AbstractFAtoREConverter* conv;
 
-    }
-    else if( m_target == REGULAR_EXPRESSION )
+    switch( m_algorithm )
     {
-        AbstractRGtoREConverter* conv;
-        RightRegularGrammar rrg;
-        LeftRegularGrammar lrg;
-        bool rightGrammar = true;
+    case BRZOZOWSKI_ALGEBRAIC:
+        conv = new BrzozowskiAlgebraic( fsm );
+        break;
+
+    case STATE_ELIMINATION:
+    default:
+        conv = new StateElimination( fsm );
+        break;
+    }
 
-        try
-        {
-            GrammarFactory::buildRightRegularGrammar( ug );
-        }
-        catch( AlibException & e )
-        {
-            rightGrammar = false;
-        }
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
 
-        if( m_algorithm == BRZOZOWSKI_ALGEBRAIC && rightGrammar )
-        {
-            rrg = GrammarFactory::buildRightRegularGrammar( ug );
-            conv = new RRGAlgebraic( rrg );
-        }
-        else if( m_algorithm == BRZOZOWSKI_ALGEBRAIC && ! rightGrammar )
-        {
-            lrg = GrammarFactory::buildLeftRegularGrammar( ug );
-            conv = new LRGAlgebraic( lrg );
-        }
-        else throw AlibException( "wtf?" );
+void ConversionHandler::convertFSMtoRG( void )
+{
+    if( m_target == RIGHT_REGULAR_GRAMMAR || REGULAR_GRAMMAR )
+        convertFSMtoRRG( );
+    else if( m_target == LEFT_REGULAR_GRAMMAR )
+        convertFSMtoLRG( );
+    else
+        throw AlibException( "ConversionHandler::Unknown target formalism" );
+}
+
+void ConversionHandler::convertFSMtoRRG( void )
+{
+    const FSM fsm = AutomatonFactory::buildFSM( AutomatonParser::parse( m_tokens ) );
 
-        conv->convert( ).toXML( out );
-        delete conv;
+    AbstractFAtoRRGConverter* conv;
+
+    switch( m_algorithm )
+    {
+    default:
+        conv = new FAtoRRGConverter( fsm );
+        break;
     }
-    else if( m_target == REGULAR_GRAMMAR )
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
+
+void ConversionHandler::convertFSMtoLRG( void )
+{
+    const FSM fsm = AutomatonFactory::buildFSM( AutomatonParser::parse( m_tokens ) );
+
+    AbstractFAtoLRGConverter* conv;
+
+    switch( m_algorithm )
     {
-        RightRegularGrammar rrg;
-        LeftRegularGrammar lrg;
-        bool rightGrammar = true;
+    default:
+        conv = new FAtoLRGConverter( fsm );
+        break;
+    }
 
-        try
-        {
-            GrammarFactory::buildRightRegularGrammar( ug );
-        }
-        catch( AlibException & e )
-        {
-            rightGrammar = false;
-        }
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
 
-        if( rightGrammar )
-        {
-            AbstractRRGtoLRGConverter* conv;
-            rrg = GrammarFactory::buildRightRegularGrammar( ug );
-            conv = new RightToLeftRegularGrammar( rrg );
-            conv->convert( ).toXML( out );
-            delete conv;
-        }
-        else
-        {
-            AbstractLRGtoRRGConverter* conv;
-            lrg = GrammarFactory::buildLeftRegularGrammar( ug );
-            conv = new LeftToRightRegularGrammar( lrg );
-            conv->convert( ).toXML( out );
-            delete conv;
-        }
+// ----------------------------------------------------------------------------
+
+void ConversionHandler::convertREtoFSM( void )
+{
+    const RegExp regexp = RegExpParser::parse( m_tokens );
+    AbstractREtoFAConverter* conv;
+
+    switch( m_algorithm )
+    {
+    case BRZOZOWSKI_DERIVATION:
+        conv = new Brzozowski( regexp );
+        break;
+    case THOMPSON_NFA:
+        conv = new Thompson( regexp );
+        break;
+    case GLUSHKOV_NFA:
+    default:
+        conv = new Glushkov( regexp );
+        break;
     }
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
+
+void ConversionHandler::convertREtoRG( void )
+{
+    if( m_target == RIGHT_REGULAR_GRAMMAR || REGULAR_GRAMMAR )
+        convertREtoRRG( );
+    else if( m_target == LEFT_REGULAR_GRAMMAR )
+        throw AlibException( "ConversionHandler:: RE to LRG is not implemented. Please convert to RRG and then to LRG." );
+    else
+        throw AlibException( "ConversionHandler::Unknown target formalism" );
 }
 
-void ConversionHandler::convertRegExp( ostream & out )
+void ConversionHandler::convertREtoRRG( void )
 {
     const RegExp regexp = RegExpParser::parse( m_tokens );
+    AbstractREtoRRGConverter* conv;
 
-    if( m_target == FINITE_AUTOMATA )
+    switch( m_algorithm )
     {
-        AbstractREtoFAConverter* conv;
-        if( m_algorithm == THOMPSON )
-            conv = new Thompson( regexp );
-        else if( m_algorithm == BRZOZOWSKI_DERIVATION )
-            conv = new Brzozowski( regexp );
-        else
-            conv = new Glushkov( regexp );
+    case BRZOZOWSKI_DERIVATION:
+        conv = new BrzozowskiDerivationRRG( regexp );
+        break;
+    default:
+        conv = new GlushkovRRG( regexp );
+        break;
+    }
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
+
+// ----------------------------------------------------------------------------
+
+void ConversionHandler::convertRGtoFSM( void )
+{
+    if( m_source == LEFT_REGULAR_GRAMMAR )
+        convertLRGtoFSM( );
+    else if( m_source == RIGHT_REGULAR_GRAMMAR )
+        convertRRGtoFSM( );
+    else if( m_source == LEFT_LINEAR_GRAMMAR )
+        throw AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
+    else if( m_source == RIGHT_LINEAR_GRAMMAR )
+        throw AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
+    else
+        throw AlibException( "ConversionHandler: Unknown target formalism." );
+}
+
+void ConversionHandler::convertRGtoRG( void )
+{
+    if( m_source == LEFT_REGULAR_GRAMMAR )
+        convertLRGtoRRG( );
+    else if( m_source == RIGHT_REGULAR_GRAMMAR )
+        convertRRGtoLRG( );
+    else if( m_source == LEFT_LINEAR_GRAMMAR )
+        throw AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
+    else if( m_source == RIGHT_LINEAR_GRAMMAR )
+        throw AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
+    else
+        throw AlibException( "ConversionHandler: Unknown target formalism." );
+}
+
+void ConversionHandler::convertRGtoRE( void )
+{
+    if( m_source == LEFT_REGULAR_GRAMMAR )
+        convertLRGtoRE( );
+    else if( m_source == RIGHT_REGULAR_GRAMMAR )
+        convertRRGtoRE( );
+    else if( m_source == LEFT_LINEAR_GRAMMAR )
+        throw AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
+    else if( m_source == RIGHT_LINEAR_GRAMMAR )
+        throw AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
+    else
+        throw AlibException( "ConversionHandler: Unknown target formalism." );
+}
+
+void ConversionHandler::convertLRGtoFSM( void )
+{
+    const LeftRegularGrammar lrg = GrammarFactory::buildLeftRegularGrammar( GrammarParser::parse( m_tokens ) );
 
-        conv->convert( ).toXML( out );
-        delete conv;
+    AbstractLRGtoFAConverter* conv;
 
+    switch( m_algorithm )
+    {
+    default:
+        conv = new LRGtoFAConverter( lrg );
+        break;
     }
-    else if( m_target == REGULAR_GRAMMAR )
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
+
+void ConversionHandler::convertRRGtoFSM( void )
+{
+    const RightRegularGrammar rrg = GrammarFactory::buildRightRegularGrammar( GrammarParser::parse( m_tokens ) );
+
+    AbstractRRGtoFAConverter* conv;
+
+    switch( m_algorithm )
     {
-        if( m_algorithm == BRZOZOWSKI_RRG )
-        {
-            AbstractREtoRRGConverter* conv;
+    default:
+        conv = new RRGtoFAConverter( rrg );
+        break;
+    }
 
-            conv = new BrzozowskiDerivationRRG( regexp );
-            conv->convert( ).toXML( out );
-            delete conv;
-        }
-        else if ( m_algorithm == GLUSHKOV_RRG )
-        {
-            AbstractREtoRRGConverter* conv;
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
 
-            conv = new GlushkovRRG( regexp );
-            conv->convert( ).toXML( out );
-            delete conv;
-        }
+void ConversionHandler::convertLRGtoRE( void )
+{
+    const LeftRegularGrammar lrg = GrammarFactory::buildLeftRegularGrammar( GrammarParser::parse( m_tokens ) );
+
+    AbstractLRGtoREConverter* conv;
+
+    switch( m_algorithm )
+    {
+    case BRZOZOWSKI_ALGEBRAIC:
+    default:
+        conv = new LRGAlgebraic( lrg );
+        break;
     }
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
 }
 
-void ConversionHandler::convertAutomata( ostream & out )
+void ConversionHandler::convertRRGtoRE( void )
 {
-    const FSM fsm = AutomatonFactory::buildFSM( AutomatonParser::parse( m_tokens ) );
+    const RightRegularGrammar rrg = GrammarFactory::buildRightRegularGrammar( GrammarParser::parse( m_tokens ) );
+
+    AbstractRRGtoREConverter* conv;
 
-    if( m_target == REGULAR_EXPRESSION )
+    switch( m_algorithm )
     {
-        AbstractFAtoREConverter* conv;
+    case BRZOZOWSKI_ALGEBRAIC:
+    default:
+        conv = new RRGAlgebraic( rrg );
+        break;
+    }
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
 
-        if( m_algorithm == BRZOZOWSKI_ALGEBRAIC )
-            conv = new BrzozowskiAlgebraic( fsm );
-        else
-            conv = new StateElimination( fsm );
+void ConversionHandler::convertLRGtoRRG( void )
+{
+    const LeftRegularGrammar lrg = GrammarFactory::buildLeftRegularGrammar( GrammarParser::parse( m_tokens ) );
+
+    AbstractLRGtoRRGConverter* conv;
 
-        conv->convert( ).toXML( out );
-        delete conv;
+    switch( m_algorithm )
+    {
+    default:
+        conv = new LeftToRightRegularGrammar( lrg );
+        break;
     }
-    else if( m_target == REGULAR_GRAMMAR )
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
+}
+
+void ConversionHandler::convertRRGtoLRG( void )
+{
+    const RightRegularGrammar rrg = GrammarFactory::buildRightRegularGrammar( GrammarParser::parse( m_tokens ) );
+
+    AbstractRRGtoLRGConverter* conv;
+
+    switch( m_algorithm )
     {
-        if( m_algorithm == FA_LRG )
-        {
-            AbstractFAtoLRGConverter* conv = new FAtoLRGConverter( fsm );
-            conv->convert( ).toXML( out );
-            delete conv;
-        }
-        else
-        {
-            AbstractFAtoRRGConverter* conv = new FAtoRRGConverter( fsm );
-            conv->convert( ).toXML( out );
-            delete conv;
-        }
+    default:
+        conv = new RightToLeftRegularGrammar( rrg );
+        break;
     }
+
+    conv->convert( ).toXML( m_out );
+    delete conv;
 }
 
+// ----------------------------------------------------------------------------
+
 ConversionHandler::TFormalism ConversionHandler::parseFormalismFromString( const std::string & _target ) const
 {
     string target;
@@ -223,94 +357,100 @@ ConversionHandler::TFormalism ConversionHandler::parseFormalismFromString( const
 
     if( target == "fa" || target == "automaton" || target == "fsm" )
         return FINITE_AUTOMATA;
-    if( target == "re" || target == "regexp" )
+
+    if( target == "re" || target == "regexp" || target == "regex" )
         return REGULAR_EXPRESSION;
+
     if( target == "rg" || target == "grammar" )
         return REGULAR_GRAMMAR;
 
-    throw AlibException( "Unknown target type" );
+    if( target == "rrg" )
+        return RIGHT_REGULAR_GRAMMAR;
+
+    if( target == "lrg" )
+        return LEFT_REGULAR_GRAMMAR;
+
+    throw AlibException( "ConversionHandler::Unknown target type" );
 }
 
-ConversionHandler::TAlgorithm ConversionHandler::parseAlgorithmFromString( const std::string & _algorithm ) const
+ConversionHandler::TFormalism ConversionHandler::parseFormalismFromTokens( void ) const
 {
-    string algorithm;
-    for( const auto & c : _algorithm )
-        algorithm.append( 1, tolower( c ) );
+    string xmlMark = m_tokens.front( ).getData( );
 
-    if( algorithm == "" ) return DEFAULT;
+    if( xmlMark == "automaton" )
+        return FINITE_AUTOMATA;
 
-    /* FA to RE */
-    /* RG to RE */
-    if( algorithm == "elimination" ) return STATE_ELIMINATION;
-    if( algorithm == "algebraic" ) return BRZOZOWSKI_ALGEBRAIC;
+    if( xmlMark == "regexp" )
+        return REGULAR_EXPRESSION;
 
-    /* FA to RG */
-    if( algorithm == "left" ) return FA_LRG;
-    if( algorithm == "right" ) return FA_RRG;
+    if( xmlMark == "grammar" )
+    {
+        bool ll, rl, lr, rr;
+        ll = rl = lr = rr = true;
 
-    /* RE to FA */
-    if( algorithm == "brzozowski" ) return BRZOZOWSKI_DERIVATION;
-    if( algorithm == "glushkov" ) return GLUSHKOV;
-    if( algorithm == "thompson" ) return THOMPSON;
+        UnknownGrammar grammar = GrammarParser::parse( m_tokens );
 
-    /* RE to RG */
-    if( algorithm == "brzozowskirrg") return BRZOZOWSKI_RRG;
-    if( algorithm == "glushkovrrg") return GLUSHKOV_RRG;
+        try
+        {
+            GrammarFactory::buildRightRegularGrammar( grammar );
+        }
+        catch( AlibException & e )
+        {
+            rr = false;
+        }
+
+        try
+        {
+            GrammarFactory::buildLeftRegularGrammar( grammar );
+        }
+        catch( AlibException & e )
+        {
+            lr = false;
+        }
+
+        try
+        {
+            GrammarFactory::buildRightLinearGrammar( grammar );
+        }
+        catch( AlibException & e )
+        {
+            rl = false;
+        }
 
-    /* RG to FA */
-    if( algorithm == "rg" ) return RG_FA;
+        try
+        {
+            GrammarFactory::buildLeftLinearGrammar( grammar );
+        }
+        catch( AlibException & e )
+        {
+            ll = false;
+        }
 
-    /* RG to RG */
-    if( algorithm == "rg" ) return LRG_RRG;
+        if( ll ) return LEFT_LINEAR_GRAMMAR;
+        if( rl ) return RIGHT_LINEAR_GRAMMAR;
+        if( lr ) return LEFT_REGULAR_GRAMMAR;
+        if( rr ) return RIGHT_REGULAR_GRAMMAR;
+    }
 
-    throw AlibException( "Invalid conversion. See help." );
+    throw AlibException( "ConversionHandler: Invalid input formalism." );
+    // return UNKNOWN;
 }
 
-ConversionHandler::TAlgorithm ConversionHandler::getDefaultAlgorithm( void ) const
+ConversionHandler::TAlgorithm ConversionHandler::parseAlgorithmFromString( const std::string & _algorithm ) const
 {
-    if( m_source == FINITE_AUTOMATA && m_target == REGULAR_EXPRESSION ) return STATE_ELIMINATION;
-    if( m_source == FINITE_AUTOMATA && m_target == REGULAR_GRAMMAR )    return FA_RRG;
-    if( m_source == REGULAR_EXPRESSION && m_target == FINITE_AUTOMATA ) return GLUSHKOV;
-    if( m_source == REGULAR_EXPRESSION && m_target == REGULAR_GRAMMAR ) return GLUSHKOV_RRG;
-    if( m_source == REGULAR_GRAMMAR && m_target == FINITE_AUTOMATA )    return RG_FA;
-    if( m_source == REGULAR_GRAMMAR && m_target == REGULAR_EXPRESSION ) return BRZOZOWSKI_ALGEBRAIC;
-    if( m_source == REGULAR_GRAMMAR && m_target == REGULAR_GRAMMAR )    return LRG_RRG;
-
-    throw AlibException( "ConversionHandler::getDefaultAlgorithm - unreachable code" );
-}
+    string algorithm;
+    for( const auto & c : _algorithm )
+        algorithm.append( 1, tolower( c ) );
 
-bool ConversionHandler::checkAlgorithm( void ) const
-{
-    if( m_algorithm == DEFAULT ) return true;
+    if( algorithm == "elimination" ) return STATE_ELIMINATION;
+    if( algorithm == "algebraic" ) return BRZOZOWSKI_ALGEBRAIC;
+    if( algorithm == "brzozowski" ) return BRZOZOWSKI_DERIVATION;
+    if( algorithm == "glushkov" ) return GLUSHKOV_NFA;
+    if( algorithm == "thompson" ) return THOMPSON_NFA;
 
-    /* FA to RE */
-    /* FA to RG */
-    if( m_source == FINITE_AUTOMATA )
-        return ( m_target == REGULAR_EXPRESSION &&
-                    ( m_algorithm == BRZOZOWSKI_ALGEBRAIC || m_algorithm == STATE_ELIMINATION ) ) ||
-               ( m_target == REGULAR_GRAMMAR &&
-                    ( m_algorithm == FA_LRG || m_algorithm == FA_RRG ) );
-
-    /* RE to FA */
-    /* RE to RG */
-    if( m_source == REGULAR_EXPRESSION )
-        return ( m_target == FINITE_AUTOMATA &&
-                    ( m_algorithm == BRZOZOWSKI_DERIVATION || m_algorithm == GLUSHKOV || m_algorithm == THOMPSON ) ) ||
-               ( m_target == REGULAR_GRAMMAR &&
-                    ( m_algorithm == BRZOZOWSKI_RRG || m_algorithm == GLUSHKOV_RRG ) );
-
-    /* RG to FA */
-    /* RG to RE */
-    /* RG to RG */
-    if( m_source == REGULAR_GRAMMAR )
-        return ( m_target == FINITE_AUTOMATA &&
-                    ( m_algorithm == RG_FA ) ) ||
-               ( m_target == REGULAR_EXPRESSION &&
-                    ( m_algorithm == BRZOZOWSKI_ALGEBRAIC ) ) ||
-               ( m_target == REGULAR_GRAMMAR &&
-                    ( m_algorithm == LRG_RRG ) );
-
-    return false;
+    if( algorithm == "" ) return DEFAULT;
+
+    throw AlibException( "ConversionHandler:: Invalid algorithm. See help." );
 }
 
 } /* namespace conversions */
diff --git a/aconversions/src/aconversion/ConversionHandler.h b/aconversions/src/aconversion/ConversionHandler.h
index 28f911930a..1bb2856732 100644
--- a/aconversions/src/aconversion/ConversionHandler.h
+++ b/aconversions/src/aconversion/ConversionHandler.h
@@ -19,19 +19,26 @@
 
 #include "../fa2re/StateElimination.h"
 #include "../fa2re/BrzozowskiAlgebraic.h"
+
 #include "../re2fa/Glushkov.h"
 #include "../re2fa/Thompson.h"
 #include "../re2fa/Brzozowski.h"
+
 #include "../fa2rg/fa2lrg/FAtoLRGConverter.h"
 #include "../fa2rg/fa2rrg/FAtoRRGConverter.h"
-#include "../rg2fa/LRGtoFAConverter.h"
-#include "../rg2fa/RRGtoFAConverter.h"
-#include "../rg2re/RRGAlgebraic.h"
-#include "../rg2re/LRGAlgebraic.h"
+
+#include "../rg2fa/lrg2fa/LRGtoFAConverter.h"
+#include "../rg2fa/rrg2fa/RRGtoFAConverter.h"
+
+#include "../rg2re/rrg2re/RRGAlgebraic.h"
+#include "../rg2re/lrg2re/LRGAlgebraic.h"
+
+#include "../re2rg/re2rrg/GlushkovRRG.h"
 #include "../re2rg/re2rrg/BrzozowskiDerivationRRG.h"
+
 #include "../lrg2rrg/LeftToRightRegularGrammar.h"
 #include "../rrg2lrg/RightToLeftRegularGrammar.h"
-#include "../re2rg/re2rrg/GlushkovRRG.h"
+
 
 namespace conversions
 {
@@ -48,54 +55,86 @@ public:
         STATE_ELIMINATION,
 
         /* FA to RG */
-        FA_LRG,
-        FA_RRG,
+        // FA to LRG,
+        // FA to RRG
 
         /* RE to FA */
         BRZOZOWSKI_DERIVATION,
-        THOMPSON,
-        GLUSHKOV,
+        THOMPSON_NFA,
+        GLUSHKOV_NFA,
 
         /* RE to RG */
-        BRZOZOWSKI_RRG,
-        GLUSHKOV_RRG,
+
 
         /* RG to FA */
-        RG_FA,
+        // LRG to FSM
+        // RRG to FSM
 
         /* RG to RE */
-        // BRZOZOWSKI_ALGEBRAIC,
-        // STATE_ELIMINATION,
+        // BRZOZOWSKI_ALGEBRAIC
 
         /* RG to RG */
-        LRG_RRG,
+        // RRG to LRG
+        // LRG to RRG
+
     };
 
     enum TFormalism
     {
         FINITE_AUTOMATA,
+
         REGULAR_GRAMMAR,
+        LEFT_REGULAR_GRAMMAR,
+        RIGHT_REGULAR_GRAMMAR,
+
+        LINEAR_GRAMMAR,
+        LEFT_LINEAR_GRAMMAR,
+        RIGHT_LINEAR_GRAMMAR,
+
         REGULAR_EXPRESSION,
+
         UNKNOWN,
     };
+    #define isGrammar(x) ( (x) == REGULAR_GRAMMAR || (x) == LEFT_REGULAR_GRAMMAR || (x) == RIGHT_REGULAR_GRAMMAR \
+                        || (x) == LINEAR_GRAMMAR  || (x) == LEFT_LINEAR_GRAMMAR  || (x) == RIGHT_LINEAR_GRAMMAR )
 
-    ConversionHandler( std::list<sax::Token> & tokens, const std::string & target, const std::string & algorithm );
-    void convert( std::ostream & out );
+    ConversionHandler( std::list<sax::Token> & tokens, const std::string & target, const std::string & algorithm, std::ostream & out );
+    void convert( void );
 
 private:
-    TFormalism m_source, m_target;
-    TAlgorithm m_algorithm;
-    std::list<sax::Token> & m_tokens;
-
     TFormalism parseFormalismFromString( const std::string & _target ) const;
+    TFormalism parseFormalismFromTokens( void ) const;
     TAlgorithm parseAlgorithmFromString( const std::string & _algorithm ) const;
-    TAlgorithm getDefaultAlgorithm( void ) const;
-    void convertAutomata( std::ostream & out );
-    void convertGrammar( std::ostream & out );
-    void convertRegExp( std::ostream & out );
-    bool checkAlgorithm( void ) const;
 
+    void convertFSM( void );
+    void convertFSMtoRE( void );
+    void convertFSMtoRG( void );
+    void convertFSMtoLRG( void );
+    void convertFSMtoRRG( void );
+
+    void convertRE( void );
+    void convertREtoFSM( void );
+    void convertREtoRG( void );
+    void convertREtoRRG( void );
+
+    void convertRG( void );
 
+    void convertRGtoFSM( void );
+    void convertLRGtoFSM( void );
+    void convertRRGtoFSM( void );
+
+    void convertRGtoRE( void );
+    void convertLRGtoRE( void );
+    void convertRRGtoRE( void );
+
+    void convertRGtoRG( void );
+    void convertLRGtoRRG( void );
+    void convertRRGtoLRG( void );
+
+    std::list<sax::Token> & m_tokens;
+    TFormalism m_source, m_target;
+    TAlgorithm m_algorithm;
+    std::ostream & m_out;
 };
 
 } /* namespace conversions */
diff --git a/aconversions/src/aconversion/aconversion.cpp b/aconversions/src/aconversion/aconversion.cpp
index 6bcd97c276..efc38b7991 100644
--- a/aconversions/src/aconversion/aconversion.cpp
+++ b/aconversions/src/aconversion/aconversion.cpp
@@ -25,43 +25,61 @@ void help( void )
     cout << "aconversion 0.01" << endl;
     cout << "Converts between regular expressions, regular grammars and finite automata." << endl;
     cout << "Usage: aconversion -t FORMALISM [SWITCH...]" << endl << endl;
-    cout << "  -t, --target=FORMALISM \t Specifies target formalism, valid values are 'FA', 'FSM' or 'automaton' for finite automata, 'RE' or 'regexp' for regular expression and 'RG' or 'grammar' for regular grammar." << endl;
+    cout << "  -t, --target=FORMALISM \t Specifies target formalism. See --list-algorithms for available formalisms." << endl;
     cout << "  -a, --algorithm=ALGORITHM \t Specifies algorithm to use. See --list-algorithms." << endl;
-    cout << "  -l, --list-algorithms \t Lists algorithms to use." << endl;
+    cout << "  -l, --list-algorithms \t Lists available algorithms." << endl;
 
     cout << endl;
 }
 
 void list_algorithms( void )
 {
+    cout << "List of formalisms:" << endl;
+    cout << "\t For finite automata use 'automata', 'fsm' or 'fa'." << endl;
+    cout << "\t For regular expression use 'regexp', 're' or 'regex'." << endl;
+    cout << "\t For right regular grammar use 'rg', 'rrg' or 'grammar'." << endl;
+    cout << "\t For left regular grammar use 'lrg'." << endl;
+    cout << "This list is case-insensitive." << endl;
+
+    cout << endl;
+
     cout << "List of available algorithms:" << endl;
 
-    cout << " |" << endl;
-    cout << " +- FA to RE:" << endl;
-    cout << " | +- 'algebraic' - Converts to RE using Brzozowski algebraic method." << endl;
-    cout << " | +- 'elimination' [Default] - Performs state elimination algorithm on NFA." << endl;
+    cout << endl;
+    cout << "FA to RE:" << endl;
+    cout << "\t" << "'algebraic' - Uses Brzozowski algebraic method (regular equations)." << endl;
+    cout << "\t" << "'elimination' [Default] - Performs state elimination algorithm on NFA." << endl;
+
+    cout << endl;
+    cout << "FA to RRG:" << endl;
+    cout << "\t" << "[Default] - Converts to right regular grammar." << endl;
 
-    cout << " +- FA to RG:" << endl;
-    cout << " | +- 'left' - Converts to left regular grammar." << endl;
-    cout << " | +- 'right' [Default] - Converts to right regular grammar." << endl;
+    cout << endl;
+    cout << "FA to LRG:" << endl;
+    cout << "\t" << "[Default] - Converts to left regular grammar." << endl;
 
-    cout << " +- RE to FA:" << endl;
-    cout << " | +- 'brzozowski' - Converts to finite automata using Brzozowski's Derivation method." << endl;
-    cout << " | +- 'thompson' - Converts to finite automata using Thompson's NFA Construction algorithm." << endl;
-    cout << " | +- 'glushkov' [Default] - Converts to finite automata using Gluskov's NFA algorithm." << endl;
+    cout << endl;
+    cout << "RE to FA:" << endl;
+    cout << "\t" << "'brzozowski' - Uses Brzozowski's derivation method (WARNING: May get stuck in infinite loop)." << endl;
+    cout << "\t" << "'thompson' - Converts to finite automata using Thompson's NFA Construction algorithm." << endl;
+    cout << "\t" << "'glushkov' [Default] - Converts to finite automata using Gluskov's NFA algorithm." << endl;
 
-    cout << " +- RE to RG:" << endl;
-    cout << " | +- 'brzozowskirrg' - Converts to right regular grammar using Brzozowski's Derivation Method." << endl;
-    cout << " | +- 'glushkovrrg' [Default] - Converts to right regular grammar using Glushkov's algorithm." << endl;
+    cout << endl;
+    cout << "RE to RRG:" << endl;
+    cout << "\t" << "'brzozowski' - Uses Brzozowski's derivation method (WARNING: May get stuck in infinite loop)." << endl;
+    cout << "\t" << "'glushkov' [Default] - Converts to finite automata using Gluskov's NFA algorithm." << endl;
 
-    cout << " +- RG to FA:" << endl;
-    cout << " | +- 'rg' [Default] - Converts right or left regular grammar to finite automata." << endl;
+    cout << endl;
+    cout << "RG to FA:" << endl;
+    cout << "\t" << "[Default] - Converts right or left regular grammar to finite automata." << endl;
 
-    cout << " +- RG to RE:" << endl;
-    cout << " | +- 'algebraic' [Default] - Converts left or right regular grammar to regexp using Brzozowski's Algebraic method." << endl;
+    cout << endl;
+    cout << "RG to RE:" << endl;
+    cout << "\t" << "'algebraic' [Default] - Uses Brzozowski algebraic method (regular equations)." << endl;
 
-    cout << " +- (L/R)RG to (R/L)RG:" << endl;
-    cout << " | +- 'rg' [Default] - Converts right to left regular grammar or vice versa." << endl;
+    cout << endl;
+    cout << "RG to RG:" << endl;
+    cout << "\t" << "[Default] - Converts right to left regular grammar or vice versa." << endl;
 }
 
 int main(int argc, char* argv[])
@@ -105,8 +123,8 @@ int main(int argc, char* argv[])
 
   try
   {
-      ConversionHandler conv( tokens, target, algorithm );
-      conv.convert( cout );
+      ConversionHandler conv( tokens, target, algorithm, cout );
+      conv.convert( );
   }
   catch( AlibException & e )
   {
-- 
GitLab