From 472ae8cf376e7b6cf13f92480772cb419e0cdd36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Sat, 15 Mar 2014 23:20:12 +0100 Subject: [PATCH] Closes #14: mapping automata state to nonterminal. --- .../src/fa2rg/AbstractFAtoRGConverter.cpp | 9 +-- .../src/fa2rg/AbstractFAtoRGConverter.h | 5 +- .../src/fa2rg/StateNonterminalMap.cpp | 56 +++++++++++++++++++ aconversions/src/fa2rg/StateNonterminalMap.h | 43 ++++++++++++++ .../src/fa2rg/fa2lrg/FAtoLRGConverter.cpp | 16 +++--- .../src/fa2rg/fa2rrg/FAtoRRGConverter.cpp | 18 +++--- 6 files changed, 121 insertions(+), 26 deletions(-) create mode 100644 aconversions/src/fa2rg/StateNonterminalMap.cpp create mode 100644 aconversions/src/fa2rg/StateNonterminalMap.h diff --git a/aconversions/src/fa2rg/AbstractFAtoRGConverter.cpp b/aconversions/src/fa2rg/AbstractFAtoRGConverter.cpp index 0f457e2fb8..dedff158fe 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 495c1b5081..796e1fa84c 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 0000000000..0926708092 --- /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 0000000000..799491e757 --- /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 b99349a96f..7512a2c52f 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 59ecc0d1d6..30fc37d17d 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( ) ) ) -- GitLab