From 5e1b37737741ee2aa9555ed4ee449e2963594bbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz>
Date: Sat, 6 Sep 2014 22:09:59 +0200
Subject: [PATCH] algo: conv: fa2rg, rg2fa

---
 .../src/fa2rg/fa2lrg/FAtoLRGConverter.cpp     |  92 ----------------
 .../src/fa2rg/fa2lrg/FAtoLRGConverter.h       |  45 --------
 .../src/fa2rg/fa2rrg/FAtoRRGConverter.cpp     | 100 ------------------
 .../src/fa2rg/fa2rrg/FAtoRRGConverter.h       |  45 --------
 .../src/rg2fa/lrg2fa/LRGtoFAConverter.cpp     |  68 ------------
 .../src/rg2fa/lrg2fa/LRGtoFAConverter.h       |  41 -------
 .../src/rg2fa/rrg2fa/RRGtoFAConverter.cpp     |  66 ------------
 .../src/rg2fa/rrg2fa/RRGtoFAConverter.h       |  41 -------
 aconversions2/src/ConversionHandler.cpp       |  35 +++---
 .../fa2rg/fa2lrg/FAtoLRGConverter.cpp         |  58 ++++++++++
 .../fa2rg/fa2lrg/FAtoLRGConverter.h           |  28 +++++
 .../fa2rg/fa2rrg/FAtoRRGConverter.cpp         |  91 ++++++++++++++++
 .../fa2rg/fa2rrg/FAtoRRGConverter.h           |  29 +++++
 .../rg2fa/lrg2fa/LRGtoFAConverter.cpp         |  56 ++++++++++
 .../rg2fa/lrg2fa/LRGtoFAConverter.h           |  26 +++++
 .../rg2fa/rrg2fa/RRGtoFAConverter.cpp         |  57 ++++++++++
 .../rg2fa/rrg2fa/RRGtoFAConverter.h           |  26 +++++
 17 files changed, 387 insertions(+), 517 deletions(-)
 delete mode 100644 aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp
 delete mode 100644 aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.h
 delete mode 100644 aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp
 delete mode 100644 aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.h
 delete mode 100644 aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.cpp
 delete mode 100644 aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.h
 delete mode 100644 aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.cpp
 delete mode 100644 aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.h
 create mode 100644 alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
 create mode 100644 alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
 create mode 100644 alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
 create mode 100644 alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
 create mode 100644 alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.cpp
 create mode 100644 alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.h
 create mode 100644 alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.cpp
 create mode 100644 alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.h

diff --git a/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp
deleted file mode 100644
index 253fcf940a..0000000000
--- a/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "FAtoLRGConverter.h"
-
-using namespace std;
-using namespace automaton;
-using namespace grammar;
-using namespace alib;
-
-namespace conversions
-{
-
-FAtoLRGConverter::FAtoLRGConverter( const FSM & automaton ) : m_automaton( automaton )
-{
-    if( ! automaton.isEpsilonFree( ) )
-        throw AlibException( "FSM has epsilon transitions." );
-}
-
-FAtoLRGConverter::~FAtoLRGConverter( void )
-{
-
-}
-
-LeftRegularGrammar FAtoLRGConverter::convert( void )
-{
-    LeftRegularGrammar grammar;
-    map<State, Symbol> nonterminalMap;
-
-    for( const auto & symbol : m_automaton.getInputAlphabet( ) )
-        grammar.addTerminalSymbol( symbol );
-
-    for( const auto & state : m_automaton.getStates( ) )
-    {
-        Symbol nt = grammar.createUniqueNonTerminalSymbol( state.getName( ) );
-        nonterminalMap.insert( pair<State,Symbol>( state, nt ) );
-    }
-
-    // step 2
-    Symbol newStart = grammar.createUniqueNonTerminalSymbol( "S", false );
-    grammar.setStartSymbol( newStart );
-
-    // step 3 - create set of P in G
-    for( const auto & transition : m_automaton.getTransitions( ) )
-    {
-        // 3a
-        list<Symbol> leftSide, rightSide;
-        leftSide.push_back( nonterminalMap.find( transition.getTo( ) )->second );
-        rightSide.push_back( nonterminalMap.find( transition.getFrom( ) )->second );
-        rightSide.push_back( transition.getInput( ) );
-        grammar.addRule( Rule( leftSide, rightSide ) );
-
-        if( isInSet( transition.getTo( ), m_automaton.getFinalStates( ) ) )
-        {
-            list<Symbol> leftSide, rightSide;
-            leftSide.push_back( grammar.getStartSymbol( ) );
-            rightSide.push_back( nonterminalMap.find( transition.getFrom( ) )->second );
-            rightSide.push_back( transition.getInput( ) );
-
-            Rule r( leftSide, rightSide );
-            if( ! isInSet( r, grammar.getRules( ) ) )
-                grammar.addRule( Rule( leftSide, rightSide ) );
-        }
-
-
-        if( isInSet( transition.getFrom( ), m_automaton.getInitialStates( ) ) )
-        {
-            list<Symbol> leftSide, rightSide;
-            leftSide.push_back( nonterminalMap.find( transition.getTo( ) )->second );
-            rightSide.push_back( transition.getInput( ) );
-            grammar.addRule( Rule( leftSide, rightSide ) );
-
-            if( isInSet( transition.getTo( ), m_automaton.getFinalStates( ) ) )
-            {
-                list<Symbol> leftSide, rightSide;
-                leftSide.push_back( grammar.getStartSymbol( ) );
-                rightSide.push_back( transition.getInput( ) );
-
-                Rule r( leftSide, rightSide );
-                if( ! isInSet( r, grammar.getRules( ) ) )
-                    grammar.addRule( Rule( leftSide, rightSide ) );
-            }
-        }
-    }
-
-    if( isInSet( * m_automaton.getInitialStates( ).begin( ), m_automaton.getFinalStates( ) ) )
-    {
-        list<Symbol> leftSide = { newStart }, rightSide;
-        grammar.addRule( Rule( leftSide, rightSide ) );
-    }
-
-    return grammar;
-}
-
-} /* namespace conversions */
diff --git a/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.h b/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.h
deleted file mode 100644
index 8d47a792c0..0000000000
--- a/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __FATOLRGCONVERTER_H__
-#define __FATOLRGCONVERTER_H__
-
-#include <map>
-
-#include <grammar/Regular/LeftRegularGrammar.h>
-#include <automaton/FSM/FSM.h>
-#include <AlibException.h>
-
-#include "../../interface/IConversionLRG.h"
-#include "../../include/macros.h"
-
-namespace conversions
-{
-
-/**
- * Finite automaton to right regular grammar converter.
- * Source: My own :)
- */
-class FAtoLRGConverter: public IConversionLRG
-{
-public:
-    /**
-     * @param automaton Original automaton.
-     */
-    FAtoLRGConverter( const automaton::FSM & automaton );
-
-    ~FAtoLRGConverter( void );
-
-    /**
-     * Performs conversion.
-     * @return left regular grammar equivalent to source automaton.
-     */
-    grammar::LeftRegularGrammar convert( void );
-
-protected:
-    /**
-     * input automaton
-     */
-    const automaton::FSM & m_automaton;
-};
-
-} /* namespace conversions */
-
-#endif /* __FATOLRGCONVERTER_H__ */
diff --git a/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp
deleted file mode 100644
index 4a87c0a6d2..0000000000
--- a/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-#include "FAtoRRGConverter.h"
-
-using namespace std;
-using namespace automaton;
-using namespace grammar;
-using namespace alib;
-
-namespace conversions
-{
-
-FAtoRRGConverter::FAtoRRGConverter( const FSM & automaton ) : m_automaton( automaton )
-{
-    if( ! automaton.isEpsilonFree( ) )
-        throw AlibException( "FSM has epsilon transitions." );
-}
-
-FAtoRRGConverter::~FAtoRRGConverter( void )
-{
-
-}
-
-RightRegularGrammar FAtoRRGConverter::convert( void )
-{
-    RightRegularGrammar grammar;
-    map<State, Symbol> nonterminalMap;
-
-    for( const auto & symbol : m_automaton.getInputAlphabet( ) )
-        grammar.addTerminalSymbol( symbol );
-
-    for( const auto & state : m_automaton.getStates( ) )
-    {
-        Symbol nt = grammar.createUniqueNonTerminalSymbol( state.getName( ) );
-        nonterminalMap.insert( pair<State,Symbol>( state, nt ) );
-    }
-
-    // step 2 - create set of P in G
-    for( const auto & transition : m_automaton.getTransitions( ) )
-    {
-        // 2a
-        list<Symbol> leftSide, rightSide;
-        leftSide.push_back( nonterminalMap.find( transition.getFrom( ) )->second );
-        rightSide.push_back( transition.getInput( ) );
-        rightSide.push_back( nonterminalMap.find( transition.getTo( ) )->second );
-        grammar.addRule( Rule( leftSide, rightSide ) );
-
-        // 2b
-        if( isInSet( transition.getTo( ), m_automaton.getFinalStates( ) ) )
-        {
-            list<Symbol> leftSide, rightSide;
-            leftSide.push_back( nonterminalMap.find( transition.getFrom( ) )->second );
-            rightSide.push_back( transition.getInput( ) );
-
-            /*
-             *  Rule might already in - consider case:
-             *  \delta(A,a) = { F, G }, where both F and G are final states
-             */
-            if( ! isInSet( Rule( leftSide, rightSide), grammar.getRules( ) ) )
-                grammar.addRule( Rule( leftSide, rightSide ) );
-        }
-    }
-
-    // step 3 - set start symbol of G
-    grammar.setStartSymbol( nonterminalMap.find( * m_automaton.getInitialStates( ).begin( ) )->second );
-
-    // step 4
-    if( isInSet( * m_automaton.getInitialStates( ).begin( ), m_automaton.getFinalStates( ) ) )
-    {
-        // 4a
-        if( ! grammar.isNonTerminalOnRightSideOfAnyRule( grammar.getStartSymbol( ) ) )
-        {
-            list<Symbol> leftSide, rightSide;
-            leftSide.push_back( grammar.getStartSymbol( ) );
-            grammar.addRule( Rule( leftSide, rightSide ) );
-        }
-        else // 4b
-        {
-            Symbol newStart = grammar.createUniqueNonTerminalSymbol( grammar.getStartSymbol( ).getSymbol( ), false );
-
-            for( const auto & rule : grammar.getRules( ) )
-            {
-                if( rule.getLeftSide( ).front( ) == grammar.getStartSymbol( ) )
-                {
-                    list<Symbol> leftSide, rightSide( rule.getRightSide( ) );
-                    leftSide.push_back( newStart );
-                    grammar.addRule( Rule( leftSide, rightSide ) );
-                }
-            }
-            grammar.setStartSymbol( newStart );
-
-            list<Symbol> leftSide, rightSide;
-            leftSide.push_back( newStart );
-            Rule rr( leftSide, rightSide );
-            grammar.addRule( Rule( leftSide, rightSide ) );
-        }
-    }
-
-    return grammar;
-}
-
-} /* namespace conversions */
diff --git a/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.h b/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.h
deleted file mode 100644
index cf0b442f64..0000000000
--- a/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __FATORRGCONVERTER_H__
-#define __FATORRGCONVERTER_H__
-
-#include <map>
-
-#include <grammar/Regular/RightRegularGrammar.h>
-#include <automaton/FSM/FSM.h>
-#include <AlibException.h>
-
-#include "../../interface/IConversionRRG.h"
-#include "../../include/macros.h"
-
-namespace conversions
-{
-
-/**
- * Finite automaton to right regular grammar converter.
- * Source: Melichar 2.104
- */
-class FAtoRRGConverter : public IConversionRRG
-{
-public:
-    /**
-     * @param automaton Source automaton.
-     */
-    FAtoRRGConverter( const automaton::FSM & automaton );
-
-    ~FAtoRRGConverter( void );
-
-    /**
-     * Performs conversion.
-     * @return left regular grammar equivalent to source automaton.
-     */
-    grammar::RightRegularGrammar convert ( void );
-
-protected:
-    /**
-     * input automaton
-     */
-    const automaton::FSM & m_automaton;
-};
-
-} /* namespace conversions */
-
-#endif /* __FATORRGCONVERTER_H__ */
diff --git a/aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.cpp b/aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.cpp
deleted file mode 100644
index dd06004fcb..0000000000
--- a/aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-#include "LRGtoFAConverter.h"
-
-using namespace alphabet;
-using namespace automaton;
-using namespace grammar;
-
-namespace conversions
-{
-
-LRGtoFAConverter::LRGtoFAConverter( const LeftRegularGrammar & grammar ) : m_grammar( grammar )
-{
-
-}
-
-LRGtoFAConverter::~LRGtoFAConverter( void )
-{
-
-}
-
-FSM LRGtoFAConverter::convert( void )
-{
-    FSM automaton;
-
-    for( const auto & symbol : m_grammar.getTerminalSymbols( ) )
-        automaton.addInputSymbol( symbol );
-
-    for( const auto & symbol : m_grammar.getNonTerminalSymbols( ) )
-        automaton.addState( State( symbol.getSymbol( ) ) );
-
-    const State & startState = automaton.createUniqueState( "q0", true );
-
-    // step 3, constructing \delta
-    for( const auto & rule : m_grammar.getRules( ) )
-    {
-        if( m_grammar.isEpsilonRule( rule ) )
-            continue;
-
-        State current( rule.getLeftSide( ).front( ).getSymbol( ) );
-
-        // if B->a => \delta(StartState,a)=B
-        if( rule.getRightSide( ).size( ) == 1 )
-        {
-            const Symbol & input( rule.getRightSide( ).front( ).getSymbol( ) );
-            automaton.addTransition( startState, input, current );
-        }
-        // if B->Ca => \delta(C,a)=B
-        else if( rule.getRightSide( ).size( ) == 2 )
-        {
-            State next( rule.getRightSide( ).front( ).getSymbol( ) );
-            const Symbol & input = rule.getRightSide( ).back( );
-
-            automaton.addTransition( next, input, current );
-        }
-    }
-
-    // step 4
-    automaton.addInitialState( startState );
-
-    // step 5
-    automaton.addFinalState( State( m_grammar.getStartSymbol().getSymbol() ) );
-    for( const auto & rule : m_grammar.getRules( ) )
-        if( m_grammar.isEpsilonRule( rule ) )
-            automaton.addFinalState( startState );
-
-    return automaton;
-}
-
-} /* namespace conversions */
diff --git a/aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.h b/aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.h
deleted file mode 100644
index 6fc54f6e13..0000000000
--- a/aconversions/src/rg2fa/lrg2fa/LRGtoFAConverter.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __LRGTOFACONVERTER_H__
-#define __LRGTOFACONVERTER_H__
-
-#include <grammar/Regular/LeftRegularGrammar.h>
-#include <automaton/FSM/FSM.h>
-
-#include "../../interface/IConversionFSM.h"
-
-namespace conversions
-{
-
-/**
- * Converts left regular grammar to finite automaton.
- * Source: Melichar 2.102.
- */
-class LRGtoFAConverter : public IConversionFSM
-{
-public:
-    /**
-     * @param grammar Source left regular grammar.
-     */
-    LRGtoFAConverter( const grammar::LeftRegularGrammar & grammar );
-
-    ~LRGtoFAConverter( void );
-
-    /**
-     * Performs conversion.
-     * @return FSM equivalent to source grammar.
-     */
-    automaton::FSM convert( void );
-
-private:
-    /**
-     * input grammar
-     */
-    const grammar::LeftRegularGrammar & m_grammar;
-};
-
-} /* namespace conversions */
-
-#endif /* __LRGTOFACONVERTER_H__ */
diff --git a/aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.cpp b/aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.cpp
deleted file mode 100644
index 8c81927b11..0000000000
--- a/aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#include "RRGtoFAConverter.h"
-
-using namespace alphabet;
-using namespace automaton;
-using namespace grammar;
-
-namespace conversions
-{
-
-RRGtoFAConverter::RRGtoFAConverter( const RightRegularGrammar & grammar ) : m_grammar( grammar )
-{
-
-}
-
-RRGtoFAConverter::~RRGtoFAConverter( void )
-{
-
-}
-
-
-FSM RRGtoFAConverter::convert( void )
-{
-    FSM automaton;
-
-    for( const auto & symbol : m_grammar.getTerminalSymbols( ) )
-        automaton.addInputSymbol( symbol );
-
-    for( const auto & symbol : m_grammar.getNonTerminalSymbols( ) )
-        automaton.addState( State( symbol.getSymbol( ) ) );
-
-    const State & AState = automaton.createUniqueState( "A", false );
-
-    for( const auto & rule : m_grammar.getRules( ) )
-    {
-        if( m_grammar.isEpsilonRule( rule ) )
-            continue;
-
-        State current( rule.getLeftSide( ).front( ).getSymbol( ) );
-
-        if( rule.getRightSide( ).size( ) == 1 ) // if B->a => \delta(B,a)=AState
-        {
-            const Symbol & input( rule.getRightSide( ).front( ).getSymbol( ) );
-            automaton.addTransition( current, input, AState );
-        }
-        else if( rule.getRightSide( ).size( ) == 2 ) // if B->aC => \delta(B,a)=C
-        {
-            const Symbol & input = rule.getRightSide( ).front( );
-            State next( rule.getRightSide( ).back( ).getSymbol( ) );
-
-            automaton.addTransition( current, input, next );
-        }
-    }
-
-    // step 4
-    automaton.addInitialState( m_grammar.getStartSymbol().getSymbol() );
-
-    // step 5
-    automaton.addFinalState( AState );
-    for( const auto & rule : m_grammar.getRules( ) )
-        if( m_grammar.isEpsilonRule( rule ) )
-            automaton.addFinalState( State( m_grammar.getStartSymbol( ).getSymbol( ) ) );
-
-    return automaton;
-}
-
-} /* namespace conversions */
diff --git a/aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.h b/aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.h
deleted file mode 100644
index edb23c86d5..0000000000
--- a/aconversions/src/rg2fa/rrg2fa/RRGtoFAConverter.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef __RRGTOFACONVERTER_H__
-#define __RRGTOFACONVERTER_H__
-
-#include <grammar/Regular/RightRegularGrammar.h>
-#include <automaton/FSM/FSM.h>
-
-#include "../../interface/IConversionFSM.h"
-
-namespace conversions
-{
-
-/**
- * Converts left regular grammar to finite automaton.
- * Source: Melichar 2.98
- */
-class RRGtoFAConverter : public IConversionFSM
-{
-public:
-    /**
-     * @param grammar Source right regular grammar.
-     */
-    RRGtoFAConverter( const grammar::RightRegularGrammar & grammar );
-
-    ~RRGtoFAConverter( void );
-
-    /**
-     * Performs conversion.
-     * @return FSM equivalent to source grammar.
-     */
-    automaton::FSM convert( void );
-
-private:
-    /**
-     * input grammar
-     */
-    const grammar::RightRegularGrammar & m_grammar;
-};
-
-} /* namespace conversions */
-
-#endif /* __RRGTOFACONVERTER_H__ */
diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp
index 9f40da9e86..814185c436 100644
--- a/aconversions2/src/ConversionHandler.cpp
+++ b/aconversions2/src/ConversionHandler.cpp
@@ -14,11 +14,11 @@
 //#include "conversions/re2fa/Thompson.h"
 //#include "conversions/re2fa/Brzozowski.h"
 
-//#include "conversions/fa2rg/fa2lrg/FAtoLRGConverter.h"
-//#include "conversions/fa2rg/fa2rrg/FAtoRRGConverter.h"
+#include "conversions/fa2rg/fa2lrg/FAtoLRGConverter.h"
+#include "conversions/fa2rg/fa2rrg/FAtoRRGConverter.h"
 
-//#include "conversions/rg2fa/lrg2fa/LRGtoFAConverter.h"
-//#include "conversions/rg2fa/rrg2fa/RRGtoFAConverter.h"
+#include "conversions/rg2fa/lrg2fa/LRGtoFAConverter.h"
+#include "conversions/rg2fa/rrg2fa/RRGtoFAConverter.h"
 
 //#include "conversions/rg2re/rrg2re/RRGAlgebraic.h"
 //#include "conversions/rg2re/lrg2re/LRGAlgebraic.h"
@@ -148,9 +148,8 @@ void ConversionHandler::convertFSMtoRRG( void )
 	switch( m_algorithm )
 	{
 	default: {
-/*			fa2rg::FAtoRRGConverter conv( fsm );
-			regexp::UnboundedRegExp re = conv.convert();
-			alib::DataFactory::toStdout(re);*/
+			fa2rg::FAtoRRGConverter conv;
+			alib::DataFactory::toStdout(conv.convert(fsm));
 			break;
 		}
 	}
@@ -163,9 +162,8 @@ void ConversionHandler::convertFSMtoLRG( void )
 	switch( m_algorithm )
 	{
 	default: {
-/*			fa2rg::FAtoLRGConverter conv( fsm );
-			regexp::UnboundedRegExp re = conv.convert();
-			alib::DataFactory::toStdout(re);*/
+			fa2rg::FAtoLRGConverter conv;
+			alib::DataFactory::toStdout(conv.convert(fsm));
 			break;
 		}
 	}
@@ -283,9 +281,8 @@ void ConversionHandler::convertLRGtoFSM( void )
 	switch( m_algorithm )
 	{
 	default: {
-/*			rg2fa::LRGtoFAConverter conv( lrg );
-			automaton::NFA nfa = conv.convert();
-			alib::DataFactory::toStdout(nfa);*/
+			rg2fa::LRGtoFAConverter conv;
+			alib::DataFactory::toStdout(conv.convert(lrg));
 			break;
 		}
 	}
@@ -298,9 +295,8 @@ void ConversionHandler::convertRRGtoFSM( void )
 	switch( m_algorithm )
 	{
 	default: {
-/*			rg2fa::RRGtoFAConverter conv( lrg );
-			automaton::NFA nfa = conv.convert();
-			alib::DataFactory::toStdout(nfa);*/
+			rg2fa::RRGtoFAConverter conv;
+			alib::DataFactory::toStdout(conv.convert(rrg));
 			break;
 		}
 	}
@@ -399,10 +395,11 @@ ConversionHandler::TFormalism ConversionHandler::parseFormalismFromTokens( void
 	if( xmlMark == "regexp" || xmlMark == "unboundedRegexp" )
 		return REGULAR_EXPRESSION;
 
-	if( xmlMark == "grammar" )
-	{
+	if( xmlMark == "RightRG" )
 		return RIGHT_REGULAR_GRAMMAR;
-	}
+
+    if( xmlMark == "LeftRG" )
+        return LEFT_REGULAR_GRAMMAR;
 
 	throw exception::AlibException( "ConversionHandler: Invalid input formalism." );
 }
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
new file mode 100644
index 0000000000..aa02f30771
--- /dev/null
+++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.cpp
@@ -0,0 +1,58 @@
+#include "FAtoLRGConverter.h"
+#include <map>
+
+#include <label/StringLabel.h>
+#include <alphabet/LabeledSymbol.h>
+
+namespace fa2rg
+{
+
+grammar::LeftRG FAtoLRGConverter::convert(const automaton::NFA& automaton)
+{
+    std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+    // step 2
+    grammar::LeftRG grammar(alphabet::Symbol(alphabet::LabeledSymbol(label::Label(label::StringLabel("S")))));
+
+    // step 1
+    grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+    for(const auto& state : automaton.getStates())
+    {
+        alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+        grammar.addNonterminalSymbol(nt);
+        nonterminalMap.insert(std::pair<automaton::State, alphabet::Symbol>(state, nt));
+    }
+
+
+    // step 3 - create set of P in G
+    for(const auto& transition : automaton.getTransitions())
+    {
+        const automaton::State& from = transition.first.first;
+        const alphabet::Symbol& input = transition.first.second;
+
+        for(const auto& to : transition.second)
+        {
+            // 3a
+            grammar.addRule(nonterminalMap.find(to)->second, std::make_pair(nonterminalMap.find(from)->second, input));
+
+            if(automaton.getFinalStates().count(to) > 0)
+                grammar.addRule(grammar.getInitialSymbol(), std::make_pair(nonterminalMap.find(from)->second, input));
+
+
+            if(automaton.getInitialStates().count(from) > 0)
+            {
+                grammar.addRule(nonterminalMap.find(to)->second, input);
+
+                if(automaton.getFinalStates().count(to) > 0)
+                    grammar.addRule(grammar.getInitialSymbol(), input);
+            }
+        }
+    }
+
+    if(automaton.getFinalStates().count(*automaton.getInitialStates().begin()) > 0)
+        grammar.setGeneratesEpsilon(true);
+
+    return grammar;
+}
+
+} /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
new file mode 100644
index 0000000000..ef2f0a32ac
--- /dev/null
+++ b/alib2algo/src/conversions/fa2rg/fa2lrg/FAtoLRGConverter.h
@@ -0,0 +1,28 @@
+#ifndef __FATOLRGCONVERTER_H__
+#define __FATOLRGCONVERTER_H__
+
+#include <map>
+
+#include <grammar/Regular/LeftRG.h>
+#include <automaton/FSM/NFA.h>
+
+namespace fa2rg
+{
+
+/**
+ * Finite automaton to right regular grammar converter.
+ * Source: My own :)
+ */
+class FAtoLRGConverter
+{
+public:
+    /**
+     * Performs conversion.
+     * @return left regular grammar equivalent to source automaton.
+     */
+    grammar::LeftRG convert(const automaton::NFA& automaton);
+};
+
+} /* namespace fa2rg */
+
+#endif /* __FATOLRGCONVERTER_H__ */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
new file mode 100644
index 0000000000..6fc273e1a8
--- /dev/null
+++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.cpp
@@ -0,0 +1,91 @@
+#include "FAtoRRGConverter.h"
+
+#include <alphabet/LabeledSymbol.h>
+
+namespace fa2rg
+{
+
+grammar::RightRG FAtoRRGConverter::convert(const automaton::NFA& automaton)
+{
+    std::map<automaton::State, alphabet::Symbol> nonterminalMap;
+
+    const automaton::State& initState = *automaton.getInitialStates().begin();
+    const alphabet::Symbol initSymbol(alphabet::LabeledSymbol(initState.getName()));
+
+    grammar::RightRG grammar(initSymbol);
+    nonterminalMap.insert(std::make_pair(initState, initSymbol));
+
+    grammar.setTerminalAlphabet(automaton.getInputAlphabet());
+
+    for(const auto& state : automaton.getStates())
+    {
+        if(state == initState)
+            continue;
+
+        alphabet::Symbol nt = alphabet::createUniqueSymbol(alphabet::Symbol(alphabet::LabeledSymbol(state.getName())), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+        grammar.addNonterminalSymbol(nt);
+        nonterminalMap.insert(std::make_pair(state, nt));
+    }
+
+    // step 2 - create set of P in G
+    for(const auto& transition : automaton.getTransitions())
+    {
+        const automaton::State& from = transition.first.first;
+        const alphabet::Symbol& input = transition.first.second;
+        for(const auto& to : transition.second)
+        {
+            grammar.addRule(nonterminalMap.find(from)->second, std::make_pair(input, nonterminalMap.find(to)->second)); // 2a
+            if(automaton.getFinalStates().count(to)) // 2b
+                grammar.addRule(nonterminalMap.find(from)->second, input);
+        }
+    }
+
+    // step 3 - set start symbol of G
+    grammar.setInitialSymbol(nonterminalMap.find(*automaton.getInitialStates().begin())->second);
+
+    // step 4
+    if(automaton.getFinalStates().count(*automaton.getInitialStates().begin()))
+    {
+        if( ! this->isSymbolOnAnyRightHandSide(grammar.getInitialSymbol(), grammar)) // 4a
+        {
+            grammar.setGeneratesEpsilon(true);
+        }
+        else // 4b
+        {
+            alphabet::Symbol newStart = alphabet::createUniqueSymbol(grammar.getInitialSymbol(), grammar.getTerminalAlphabet(), grammar.getNonterminalAlphabet());
+            grammar.addNonterminalSymbol(newStart);
+
+            for(const auto& rule : grammar.getRules())
+                for(const auto& rightSide : rule.second)
+                    if(rule.first == grammar.getInitialSymbol())
+                        grammar.addRule(newStart, rightSide);
+
+            grammar.setInitialSymbol(newStart);
+            grammar.setGeneratesEpsilon(true);
+        }
+    }
+
+    return grammar;
+}
+
+bool FAtoRRGConverter::isSymbolOnAnyRightHandSide(const alphabet::Symbol& symbol, const grammar::RightRG& grammar) const
+{
+    for(const auto& rule : grammar.getRules())
+        for(const auto& rightSide : rule.second)
+            if(rightSide.is<std::pair<alphabet::Symbol, alphabet::Symbol>>( ))
+            {
+                const std::pair<alphabet::Symbol, alphabet::Symbol>& rhs = rightSide.get<std::pair<alphabet::Symbol, alphabet::Symbol>>();
+                if(rhs.first == symbol || rhs.second == symbol)
+                    return true;
+            }
+            else
+            {
+                const alphabet::Symbol& rhs = rightSide.get<alphabet::Symbol>();
+                if(rhs == symbol)
+                    return true;
+            }
+
+    return false;
+}
+
+} /* namespace fa2rg */
diff --git a/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
new file mode 100644
index 0000000000..79132db839
--- /dev/null
+++ b/alib2algo/src/conversions/fa2rg/fa2rrg/FAtoRRGConverter.h
@@ -0,0 +1,29 @@
+#ifndef __FATORRGCONVERTER_H__
+#define __FATORRGCONVERTER_H__
+
+#include <grammar/Regular/RightRG.h>
+#include <automaton/FSM/NFA.h>
+
+namespace fa2rg
+{
+
+/**
+ * Finite automaton to right regular grammar converter.
+ * Source: Melichar 2.104
+ */
+class FAtoRRGConverter
+{
+public:
+    /**
+     * Performs conversion.
+     * @return left regular grammar equivalent to source automaton.
+     */
+    grammar::RightRG convert(const automaton::NFA& automaton);
+
+private:
+    bool isSymbolOnAnyRightHandSide(const alphabet::Symbol& symbol, const grammar::RightRG& grammar) const;
+};
+
+} /* namespace fa2rg */
+
+#endif /* __FATORRGCONVERTER_H__ */
diff --git a/alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.cpp b/alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.cpp
new file mode 100644
index 0000000000..01d719f8e2
--- /dev/null
+++ b/alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.cpp
@@ -0,0 +1,56 @@
+#include "LRGtoFAConverter.h"
+
+#include <label/StringLabel.h>
+#include <automaton/Automaton.h>
+#include <alphabet/LabeledSymbol.h>
+
+namespace rg2fa
+{
+
+automaton::NFA LRGtoFAConverter::convert(const grammar::LeftRG& grammar)
+{
+    std::map<alphabet::Symbol, automaton::State> stateMap;
+
+    automaton::NFA automaton;
+    automaton.setInputSymbols(grammar.getTerminalAlphabet());
+    for(const auto& symbol : grammar.getNonterminalAlphabet())
+    {
+        automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
+        automaton.addState(state);
+        stateMap.insert(std::make_pair(symbol, state));
+    }
+
+    const automaton::State startState = automaton::createUniqueState(automaton::State(label::Label(label::StringLabel("q0"))), automaton.getStates());
+    automaton.addState(startState);
+
+    // step 3, constructing \delta
+    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(startState, rhs, stateMap.find(lhs)->second);
+            }
+        }
+    }
+
+    // step 4
+    automaton.addInitialState(startState);
+
+    // step 5
+    automaton.addFinalState(stateMap.find(grammar.getInitialSymbol())->second);
+    if(grammar.getGeneratesEpsilon())
+        automaton.addFinalState(startState);
+
+    return automaton;
+}
+
+} /* namespace rg2fa */
diff --git a/alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.h b/alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.h
new file mode 100644
index 0000000000..607f72d46d
--- /dev/null
+++ b/alib2algo/src/conversions/rg2fa/lrg2fa/LRGtoFAConverter.h
@@ -0,0 +1,26 @@
+#ifndef __LRGTOFACONVERTER_H__
+#define __LRGTOFACONVERTER_H__
+
+#include <grammar/Regular/LeftRG.h>
+#include <automaton/FSM/NFA.h>
+
+namespace rg2fa
+{
+
+/**
+ * Converts left regular grammar to finite automaton.
+ * Source: Melichar 2.102.
+ */
+class LRGtoFAConverter
+{
+public:
+    /**
+     * Performs conversion.
+     * @return FSM equivalent to source grammar.
+     */
+    automaton::NFA convert(const grammar::LeftRG& grammar);
+};
+
+} /* namespace rg2fa */
+
+#endif /* __LRGTOFACONVERTER_H__ */
diff --git a/alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.cpp b/alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.cpp
new file mode 100644
index 0000000000..62bdf29d57
--- /dev/null
+++ b/alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.cpp
@@ -0,0 +1,57 @@
+#include "RRGtoFAConverter.h"
+
+#include <label/StringLabel.h>
+#include <automaton/Automaton.h>
+#include <alphabet/LabeledSymbol.h>
+
+namespace rg2fa
+{
+
+automaton::NFA RRGtoFAConverter::convert(const grammar::RightRG& grammar)
+{
+    std::map<alphabet::Symbol, automaton::State> stateMap;
+
+    automaton::NFA automaton;
+    automaton.setInputSymbols(grammar.getTerminalAlphabet());
+    for(const auto& symbol : grammar.getNonterminalAlphabet())
+    {
+        automaton::State state(static_cast<const alphabet::LabeledSymbol&>(symbol.getData()).getLabel());
+        automaton.addState(state);
+        stateMap.insert(std::make_pair(symbol, state));
+    }
+
+    const automaton::State AState = automaton::createUniqueState(automaton::State(label::Label(label::StringLabel("A"))), automaton.getStates());
+    automaton.addState(AState);
+
+    // step 3, construct \delta
+    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 4
+    automaton.addInitialState(stateMap.find(grammar.getInitialSymbol())->second);
+
+    // step 5
+    automaton.addFinalState(AState);
+    if(grammar.getGeneratesEpsilon())
+        for(const auto& state : automaton.getInitialStates())
+            automaton.addFinalState(state);
+
+    return automaton;
+}
+
+} /* namespace conversions */
diff --git a/alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.h b/alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.h
new file mode 100644
index 0000000000..30666e4cfe
--- /dev/null
+++ b/alib2algo/src/conversions/rg2fa/rrg2fa/RRGtoFAConverter.h
@@ -0,0 +1,26 @@
+#ifndef __RRGTOFACONVERTER_H__
+#define __RRGTOFACONVERTER_H__
+
+#include <grammar/Regular/RightRG.h>
+#include <automaton/FSM/NFA.h>
+
+namespace rg2fa
+{
+
+/**
+ * Converts left regular grammar to finite automaton.
+ * Source: Melichar 2.98
+ */
+class RRGtoFAConverter
+{
+public:
+    /**
+     * Performs conversion.
+     * @return FSM equivalent to source grammar.
+     */
+    automaton::NFA convert(const grammar::RightRG& grammar);
+};
+
+} /* namespace rg2fa */
+
+#endif /* __RRGTOFACONVERTER_H__ */
-- 
GitLab