Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ConversionHandler.cpp 11.55 KiB
/*
 * ConversionHandler.cpp
 *
 *  Created on: 23. 2. 2014
 *	  Author: tomas
 */

#include "ConversionHandler.h"

//#include "conversions/fa2re/StateElimination.h"
#include "conversions/fa2re/BrzozowskiAlgebraic.h"

#include "conversions/re2fa/Glushkov.h"
#include "conversions/re2fa/Thompson.h"
#include "conversions/re2fa/Brzozowski.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/rg2re/rrg2re/RRGAlgebraic.h"
//#include "conversions/rg2re/lrg2re/LRGAlgebraic.h"

//#include "conversions/re2rg/re2rrg/GlushkovRRG.h"
//#include "conversions/re2rg/re2rrg/BrzozowskiDerivationRRG.h"

#include "conversions/rg2rg/lrg2rrg/LeftToRightRegularGrammar.h"
#include "conversions/rg2rg/rrg2lrg/RightToLeftRegularGrammar.h"


using namespace alib;
using namespace automaton;
using namespace grammar;
using namespace regexp;
using namespace sax;
using namespace std;

namespace conversions
{

ConversionHandler::ConversionHandler( list<Token> & tokens, const std::string & target, const std::string & algorithm, std::ostream & out ) :
	m_tokens( tokens ),
	m_source( parseFormalismFromTokens( ) ),
	m_target( parseFormalismFromString( target ) ),
	m_algorithm( parseAlgorithmFromString( algorithm ) ),
	m_out( out )
{

}

void ConversionHandler::convert( void )
{
	if( m_source == FINITE_AUTOMATON )
		convertFSM( );
	else if( m_source == REGULAR_EXPRESSION )
		convertRE( );
	else if( isGrammar( m_source ) )
		convertRG( );
	else
		throw exception::AlibException( "ConversionHandler: Unknown source formalism." );
}

// ----------------------------------------------------------------------------

void ConversionHandler::convertFSM( void )
{
	if( m_target == FINITE_AUTOMATON )
		throw exception::AlibException( "ConversionHandler: No valid conversion from FSM to FSM." );
	else if( m_target == REGULAR_EXPRESSION )
		convertFSMtoRE( );
	else if( isGrammar( m_target ) )
		convertFSMtoRG( );
	else
		throw exception::AlibException( "ConversionHandler: Unknown target formalism." );
}

void ConversionHandler::convertRE( void )
{
	if( m_target == FINITE_AUTOMATON )
		convertREtoFSM( );
	else if( m_target == REGULAR_EXPRESSION )
		throw exception::AlibException( "ConversionHandler: No valid conversion from RE to RE." );
	else if( isGrammar( m_target ) )
		convertREtoRG( );
	else
		throw exception::AlibException( "ConversionHandler: Unknown target formalism." );
}

void ConversionHandler::convertRG( void )
{
	if( m_target == FINITE_AUTOMATON )
		convertRGtoFSM( );
	else if( m_target == REGULAR_EXPRESSION )
		convertRGtoRE( );
	else if( isGrammar( m_target ) )
		convertRGtoRG( );
	else
		throw exception::AlibException( "ConversionHandler: Unknown target formalism." );
}

// ----------------------------------------------------------------------------

void ConversionHandler::convertFSMtoRE( void )
{
	switch( m_algorithm )
	{
	case BRZOZOWSKI_ALGEBRAIC: {
			std::string xmlMark = m_tokens.front( ).getData( );
			if( xmlMark == "NFA") {
				const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );
				regexp::UnboundedRegExp re = fa2re::BrzozowskiAlgebraic::convert( fsm );
				alib::DataFactory::toStdout(re);
			} else if( xmlMark == "DFA") {
				const automaton::DFA fsm = alib::DataFactory::fromTokens<automaton::DFA>( m_tokens );
				regexp::UnboundedRegExp re = fa2re::BrzozowskiAlgebraic::convert( fsm );
				alib::DataFactory::toStdout(re);
			} else {
				throw exception::AlibException("Unrecognised formalism");
			}
			break;
		}
	case STATE_ELIMINATION:
	default: {
			/*fa2re::StateElimination conv( fsm );
			regexp::UnboundedRegExp re = conv.convert();
			alib::DataFactory::toStdout(re);*/
			break;
		}
	}
}

void ConversionHandler::convertFSMtoRG( void )
{
	if( m_target == RIGHT_REGULAR_GRAMMAR )
		convertFSMtoRRG( );
	else if( m_target == LEFT_REGULAR_GRAMMAR )
		convertFSMtoLRG( );
	else
		throw exception::AlibException( "ConversionHandler::Unknown target formalism" );
}

void ConversionHandler::convertFSMtoRRG( void )
{
	const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );

	switch( m_algorithm )
	{
	default: {
			fa2rg::FAtoRRGConverter conv;
			alib::DataFactory::toStdout(conv.convert(fsm));
			break;
		}
	}
}

void ConversionHandler::convertFSMtoLRG( void )
{
	const automaton::NFA fsm = alib::DataFactory::fromTokens<automaton::NFA>( m_tokens );

	switch( m_algorithm )
	{
	default: {
			fa2rg::FAtoLRGConverter conv;
			alib::DataFactory::toStdout(conv.convert(fsm));
			break;
		}
	}
}

// ----------------------------------------------------------------------------

void ConversionHandler::convertREtoFSM( void )
{
    const regexp::RegExp regexp = alib::DataFactory::fromTokens<regexp::RegExp>(m_tokens);

	switch( m_algorithm )
	{
	case BRZOZOWSKI_DERIVATION: {
			re2fa::Brzozowski conv;
			alib::DataFactory::toStdout(conv.convert(regexp));
			break;
		}
	case THOMPSON_NFA: {
			re2fa::Thompson conv;
			alib::DataFactory::toStdout(conv.convert(regexp));
			break;
		}
	case GLUSHKOV_NFA:
	default: {
			//re2fa::Glushkov conv;
			//alib::DataFactory::toStdout(conv.convert(regexp));
			break;
		}
	}
}

void ConversionHandler::convertREtoRG( void )
{
	if( m_target == RIGHT_REGULAR_GRAMMAR )
		convertREtoRRG( );
	else if( m_target == LEFT_REGULAR_GRAMMAR )
		throw exception::AlibException( "ConversionHandler:: RE to LRG is not implemented. Please convert to RRG and then to LRG." );
	else
		throw exception::AlibException( "ConversionHandler::Unknown target formalism" );
}

void ConversionHandler::convertREtoRRG( void )
{
	const regexp::UnboundedRegExp regexp = alib::DataFactory::fromTokens<regexp::UnboundedRegExp>( m_tokens );

	switch( m_algorithm )
	{
	case BRZOZOWSKI_DERIVATION: {
/*			re2rg::BrzozowskiDerivationRRG conv( regexp );
			grammar::RightRG rrg = conv.convert();
			alib::DataFactory::toStdout(rrg);*/
			break;
		}
	default: {
/*			re2rg::GlushkoRRG conv( regexp );
			grammar::RightRG rrg = conv.convert();
			alib::DataFactory::toStdout(rrg);*/
			break;
		}
	}
}

// ----------------------------------------------------------------------------

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 exception::AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
	else if( m_source == RIGHT_LINEAR_GRAMMAR )
		throw exception::AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
	else
		throw exception::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 exception::AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
	else if( m_source == RIGHT_LINEAR_GRAMMAR )
		throw exception::AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
	else
		throw exception::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 exception::AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
	else if( m_source == RIGHT_LINEAR_GRAMMAR )
		throw exception::AlibException( "ConversionHandler: Conversions from linear grammars are not yet implemented." );
	else
		throw exception::AlibException( "ConversionHandler: Unknown target formalism." );
}

void ConversionHandler::convertLRGtoFSM( void )
{
	const grammar::LeftRG lrg = alib::DataFactory::fromTokens<grammar::LeftRG>( m_tokens );

	switch( m_algorithm )
	{
	default: {
			rg2fa::LRGtoFAConverter conv;
			alib::DataFactory::toStdout(conv.convert(lrg));
			break;
		}
	}
}

void ConversionHandler::convertRRGtoFSM( void )
{
	const grammar::RightRG rrg = alib::DataFactory::fromTokens<grammar::RightRG>( m_tokens );

	switch( m_algorithm )
	{
	default: {
			rg2fa::RRGtoFAConverter conv;
			alib::DataFactory::toStdout(conv.convert(rrg));
			break;
		}
	}
}

void ConversionHandler::convertLRGtoRE( void )
{
	const grammar::LeftRG lrg = alib::DataFactory::fromTokens<grammar::LeftRG>( m_tokens );

	switch( m_algorithm )
	{
	case BRZOZOWSKI_ALGEBRAIC:
	default: {
/*			lrg2re::LRGAlgebraic conv( lrg );
			regexp::UnboundedRegExp regexp = conv.convert();
			alib::DataFactory::toStdout(regexp);*/
			break;
		}
	}
}

void ConversionHandler::convertRRGtoRE( void )
{
	const grammar::RightRG rrg = alib::DataFactory::fromTokens<grammar::RightRG>( m_tokens );

	switch( m_algorithm )
	{
	case BRZOZOWSKI_ALGEBRAIC:
	default: {
/*			rrg2re::RRGAlgebraic conv( rrg );
			regexp::UnboundedRegExp regexp = conv.convert();
			alib::DataFactory::toStdout(regexp);*/
			break;
		}
	}
}

void ConversionHandler::convertLRGtoRRG( void )
{
	const grammar::LeftRG lrg = alib::DataFactory::fromTokens<grammar::LeftRG>( m_tokens );

	switch( m_algorithm )
	{
	default:
			rg2rg::LeftToRightRegularGrammar conv;
			alib::DataFactory::toStdout(conv.convert(lrg));
		break;
	}
}

void ConversionHandler::convertRRGtoLRG( void )
{
	const grammar::RightRG rrg = alib::DataFactory::fromTokens<grammar::RightRG>( m_tokens );
	switch( m_algorithm )
	{
	default:
		rg2rg::RightToLeftRegularGrammar conv;
		alib::DataFactory::toStdout(conv.convert(rrg));
		break;
	}
}

// ----------------------------------------------------------------------------

ConversionHandler::TFormalism ConversionHandler::parseFormalismFromString( const std::string & _target ) const
{
	std::string target;
	for( const auto & c : _target )
		target.append( 1, tolower( c ) );

	if( target == "fa" || target == "fsa" || target == "fsm" )
		return FINITE_AUTOMATON;

	if( target == "re" || target == "regexp" || target == "regex" )
		return REGULAR_EXPRESSION;

	if( target == "rrg" || target == "rg" || target == "grammar" )
		return RIGHT_REGULAR_GRAMMAR;

	if( target == "lrg" )
		return LEFT_REGULAR_GRAMMAR;

	throw exception::AlibException( "ConversionHandler::Unknown target type" );
}

ConversionHandler::TFormalism ConversionHandler::parseFormalismFromTokens( void ) const
{
	std::string xmlMark = m_tokens.front( ).getData( );

	if( xmlMark == "automaton" || xmlMark == "NFA" || xmlMark == "DFA" )
		return FINITE_AUTOMATON;

	if( xmlMark == "regexp" || xmlMark == "unboundedRegexp" )
		return REGULAR_EXPRESSION;

	if( xmlMark == "RightRG" )
		return RIGHT_REGULAR_GRAMMAR;

    if( xmlMark == "LeftRG" )
        return LEFT_REGULAR_GRAMMAR;

	throw exception::AlibException( "ConversionHandler: Invalid input formalism." );
}

ConversionHandler::TAlgorithm ConversionHandler::parseAlgorithmFromString( const std::string & _algorithm ) const
{
	std::string algorithm;
	for( const auto & c : _algorithm )
		algorithm.append( 1, tolower( c ) );

	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;

	if( algorithm == "" ) return DEFAULT;

	throw exception::AlibException( "ConversionHandler:: Invalid algorithm. See help." );
}

} /* namespace conversions */