diff --git a/aconversions/src/fa2rg/AbstractFAtoRGConverter.cpp b/aconversions/src/fa2rg/AbstractFAtoRGConverter.cpp index 0f457e2fb8a0ab22bab2e888eea16d6c080b177c..dedff158feb0bb136988c4c03619ae3478fb2dc0 100644 --- a/aconversions/src/fa2rg/AbstractFAtoRGConverter.cpp +++ b/aconversions/src/fa2rg/AbstractFAtoRGConverter.cpp @@ -20,16 +20,9 @@ AbstractFAtoRGConverter::AbstractFAtoRGConverter( const FSM & fsm ) : m_fsm( fsm throw AlibException( "FSM has epsilon transitions" ); } -void AbstractFAtoRGConverter::createNonTerminalSymbols( RegularGrammar & rg ) const +AbstractFAtoRGConverter::~AbstractFAtoRGConverter( void ) { - for( const auto & state : m_fsm.getStates( ) ) - rg.addNonTerminalSymbol( Symbol( state.getName( ) ) ); -} -void AbstractFAtoRGConverter::createTerminalSymbols( RegularGrammar & rg ) const -{ - for( const auto & symbol : m_fsm.getInputAlphabet( ) ) - rg.addTerminalSymbol( symbol ); } } /* namespace conversions */ diff --git a/aconversions/src/fa2rg/AbstractFAtoRGConverter.h b/aconversions/src/fa2rg/AbstractFAtoRGConverter.h index 495c1b50814a4a4820ecf04dfe790a29016a5e36..796e1fa84cfcc50a260fba08ceb52d6bc23d9fbd 100644 --- a/aconversions/src/fa2rg/AbstractFAtoRGConverter.h +++ b/aconversions/src/fa2rg/AbstractFAtoRGConverter.h @@ -13,6 +13,7 @@ #include <AlibException.h> #include "../abstract/Conversion.h" +#include "StateNonterminalMap.h" namespace conversions { @@ -21,12 +22,10 @@ class AbstractFAtoRGConverter : public Conversion { public: AbstractFAtoRGConverter( const automaton::FSM & fsm ); + ~AbstractFAtoRGConverter( void ); protected: const automaton::FSM & m_fsm; - - void createNonTerminalSymbols( grammar::RegularGrammar & grammar ) const; - void createTerminalSymbols( grammar::RegularGrammar & grammar ) const; }; } /* namespace conversions */ diff --git a/aconversions/src/fa2rg/StateNonterminalMap.cpp b/aconversions/src/fa2rg/StateNonterminalMap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..092670809232c289bd9a93892e5fa65e8abaa243 --- /dev/null +++ b/aconversions/src/fa2rg/StateNonterminalMap.cpp @@ -0,0 +1,56 @@ +/* + * StateNonterminalMap.cpp + * + * Created on: 15. 3. 2014 + * Author: tomas + */ + +#include "StateNonterminalMap.h" + +using namespace alib; +using namespace alphabet; +using namespace automaton; +using namespace grammar; + +namespace conversions +{ + +StateNonterminalMap::StateNonterminalMap( const FSM & fsm, RegularGrammar & grammar ) : + m_fsm( fsm ), + m_grammar( grammar ) +{ + initMap( ); +} + +const Symbol & StateNonterminalMap::getNonTerminal( const State & state ) +{ + auto it = m_map.find( state ); + + // probably harmless to return reference to object stored in map + if( it != m_map.end( ) ) + return it->second; + + + // oops automata might have changed + // who the hell edits automata in process of converting to grammar? + if( isInSet( state, m_fsm.getStates( ) ) ) + { + Symbol nonTerminal = m_grammar.createUniqueNonTerminalSymbol( state.getName( ), false ); + m_map.insert( make_pair( state, nonTerminal ) ); + return m_map.find( state )->second; + } + + + throw AlibException( "No nonterminal for this state! Should not happen unless you manipulated with automata after initialize mapper initialize." ); +} + +void StateNonterminalMap::initMap( void ) +{ + for( const auto & state : m_fsm.getStates( ) ) + { + Symbol nonTerminal = m_grammar.createUniqueNonTerminalSymbol( state.getName( ), false ); + m_map.insert( make_pair( state, nonTerminal ) ); + } +} + +} /* namespace conversions */ diff --git a/aconversions/src/fa2rg/StateNonterminalMap.h b/aconversions/src/fa2rg/StateNonterminalMap.h new file mode 100644 index 0000000000000000000000000000000000000000..799491e7576bff6134c237472c17f8ac85f2218c --- /dev/null +++ b/aconversions/src/fa2rg/StateNonterminalMap.h @@ -0,0 +1,43 @@ +/* + * StateNonterminalMap.h + * + * Created on: 15. 3. 2014 + * Author: tomas + */ + +#ifndef STATENONTERMINALMAP_H_ +#define STATENONTERMINALMAP_H_ + +#include <map> + +#include <automaton/FSM/FSM.h> +#include <grammar/Regular/RegularGrammar.h> +#include <AlibException.h> + +#include "../include/macros.h" + +namespace conversions +{ + +class StateNonterminalMap +{ +public: + StateNonterminalMap( const automaton::FSM & fsm, grammar::RegularGrammar & grammar ); + const alphabet::Symbol & getNonTerminal( const automaton::State & state ); + +private: + void initMap( void ); + + /** + * Maps automaton's state to grammar's Symbol + */ + std::map<const automaton::State, const alphabet::Symbol> m_map; + + const automaton::FSM & m_fsm; + grammar::RegularGrammar & m_grammar; + +}; + +} /* namespace conversions */ + +#endif /* STATENONTERMINALMAP_H_ */ diff --git a/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp b/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp index b99349a96fce72b8d960b16aa81643bbe296a298..7512a2c52f677b222784e4a6daeb112c1a827d46 100644 --- a/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp +++ b/aconversions/src/fa2rg/fa2lrg/FAtoLRGConverter.cpp @@ -19,25 +19,27 @@ FAtoLRGConverter::~FAtoLRGConverter( void ) LeftRegularGrammar FAtoLRGConverter::convert( void ) { - createTerminalSymbols( m_grammar ); - createNonTerminalSymbols( m_grammar ); + for( const auto & symbol : m_fsm.getInputAlphabet( ) ) + m_grammar.addTerminalSymbol( symbol ); + + StateNonterminalMap symbolMap( m_fsm, m_grammar ); // step 2 - create set of P in G for( const auto & transition : m_fsm.getTransitions( ) ) { // 2a list<Symbol> leftSide, rightSide; - leftSide.push_back( Symbol( transition.getTo( ).getName( ) ) ); - rightSide.push_back( Symbol( transition.getFrom( ).getName( ) ) ); - rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); + leftSide.push_back( symbolMap.getNonTerminal( transition.getTo( ) ) ); + rightSide.push_back( symbolMap.getNonTerminal( transition.getFrom( ) ) ); + rightSide.push_back( transition.getInput( ) ); m_grammar.addRule( Rule( leftSide, rightSide ) ); // 2b if( isInSet( transition.getFrom( ), m_fsm.getInitialStates( ) ) ) { list<Symbol> leftSide, rightSide; - leftSide.push_back( Symbol( transition.getTo( ).getName( ) ) ); - rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); + leftSide.push_back( symbolMap.getNonTerminal( transition.getTo( ) ) ); + rightSide.push_back( transition.getInput( ) ); m_grammar.addRule( Rule( leftSide, rightSide ) ); } } diff --git a/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp b/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp index 59ecc0d1d697a83b65b879196c3c3a4db3aa283a..30fc37d17d8b577cf803a22a18ef0217146303cf 100644 --- a/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp +++ b/aconversions/src/fa2rg/fa2rrg/FAtoRRGConverter.cpp @@ -19,31 +19,33 @@ FAtoRRGConverter::~FAtoRRGConverter( void ) RightRegularGrammar FAtoRRGConverter::convert( void ) { - createTerminalSymbols( m_grammar ); - createNonTerminalSymbols( m_grammar ); + for( const auto & symbol : m_fsm.getInputAlphabet( ) ) + m_grammar.addTerminalSymbol( symbol ); + + StateNonterminalMap symbolMap( m_fsm, m_grammar ); // step 2 - create set of P in G for( const auto & transition : m_fsm.getTransitions( ) ) { // 2a list<Symbol> leftSide, rightSide; - leftSide.push_back( Symbol( transition.getFrom( ).getName( ) ) ); - rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); - rightSide.push_back( Symbol( transition.getTo( ).getName( ) ) ); + leftSide.push_back( symbolMap.getNonTerminal( transition.getFrom( ) ) ); + rightSide.push_back( transition.getInput( ) ); + rightSide.push_back( symbolMap.getNonTerminal( transition.getTo( ) ) ); m_grammar.addRule( Rule( leftSide, rightSide ) ); // 2b if( isInSet( transition.getTo( ), m_fsm.getFinalStates( ) ) ) { list<Symbol> leftSide, rightSide; - leftSide.push_back( Symbol( transition.getFrom( ).getName( ) ) ); - rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); + leftSide.push_back( symbolMap.getNonTerminal( transition.getFrom( ) ) ); + rightSide.push_back( transition.getInput( ) ); m_grammar.addRule( Rule( leftSide, rightSide ) ); } } // step 3 - set start symbol of G - m_grammar.setStartSymbol( Symbol( m_fsm.getInitialStates( ).begin( )->getName( ) ) ); + m_grammar.setStartSymbol( symbolMap.getNonTerminal( * m_fsm.getInitialStates( ).begin( ) ) ); // step 4 if( isInSet( State( m_grammar.getStartSymbol( ).getSymbol( ) ), m_fsm.getFinalStates( ) ) )