Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
LRGtoFAConverter.cpp 1.84 KiB
#include "LRGtoFAConverter.h"

using namespace alphabet;
using namespace automaton;
using namespace grammar;

namespace conversions
{

LRGtoFAConverter::LRGtoFAConverter( const LeftRegularGrammar & grammar ) : AbstractLRGtoFAConverter( grammar )
{
    //TODO: if is not LRG throw Exception
}

LRGtoFAConverter::~LRGtoFAConverter( void )
{

}

FSM LRGtoFAConverter::convert( void )
{
    for( const auto & symbol : m_grammar.getTerminalSymbols( ) )
        m_automaton.addInputSymbol( symbol );

    for( const auto & symbol : m_grammar.getNonTerminalSymbols( ) )
        m_automaton.addState( State( symbol.getSymbol( ) ) );

    const State & startState = m_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( ) );
            m_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( );

            m_automaton.addTransition( next, input, current );
        }
    }

    // step 4
    m_automaton.addInitialState( startState );

    // step 5
    m_automaton.addFinalState( State( m_grammar.getStartSymbol().getSymbol() ) );
    for( const auto & rule : m_grammar.getRules( ) )
        if( m_grammar.isEpsilonRule( rule ) )
            m_automaton.addFinalState( startState );

    return m_automaton;
}

} /* namespace conversions */