Skip to content
Snippets Groups Projects
Commit 472ae8cf authored by Tomáš Pecka's avatar Tomáš Pecka
Browse files

Closes #14: mapping automata state to nonterminal.

parent a303ab32
No related branches found
No related tags found
No related merge requests found
...@@ -20,16 +20,9 @@ AbstractFAtoRGConverter::AbstractFAtoRGConverter( const FSM & fsm ) : m_fsm( fsm ...@@ -20,16 +20,9 @@ AbstractFAtoRGConverter::AbstractFAtoRGConverter( const FSM & fsm ) : m_fsm( fsm
throw AlibException( "FSM has epsilon transitions" ); 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 */ } /* namespace conversions */
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <AlibException.h> #include <AlibException.h>
   
#include "../abstract/Conversion.h" #include "../abstract/Conversion.h"
#include "StateNonterminalMap.h"
   
namespace conversions namespace conversions
{ {
...@@ -21,12 +22,10 @@ class AbstractFAtoRGConverter : public Conversion ...@@ -21,12 +22,10 @@ class AbstractFAtoRGConverter : public Conversion
{ {
public: public:
AbstractFAtoRGConverter( const automaton::FSM & fsm ); AbstractFAtoRGConverter( const automaton::FSM & fsm );
~AbstractFAtoRGConverter( void );
   
protected: protected:
const automaton::FSM & m_fsm; const automaton::FSM & m_fsm;
void createNonTerminalSymbols( grammar::RegularGrammar & grammar ) const;
void createTerminalSymbols( grammar::RegularGrammar & grammar ) const;
}; };
   
} /* namespace conversions */ } /* namespace conversions */
......
/*
* 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 */
/*
* 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_ */
...@@ -19,25 +19,27 @@ FAtoLRGConverter::~FAtoLRGConverter( void ) ...@@ -19,25 +19,27 @@ FAtoLRGConverter::~FAtoLRGConverter( void )
   
LeftRegularGrammar FAtoLRGConverter::convert( void ) LeftRegularGrammar FAtoLRGConverter::convert( void )
{ {
createTerminalSymbols( m_grammar ); for( const auto & symbol : m_fsm.getInputAlphabet( ) )
createNonTerminalSymbols( m_grammar ); m_grammar.addTerminalSymbol( symbol );
StateNonterminalMap symbolMap( m_fsm, m_grammar );
   
// step 2 - create set of P in G // step 2 - create set of P in G
for( const auto & transition : m_fsm.getTransitions( ) ) for( const auto & transition : m_fsm.getTransitions( ) )
{ {
// 2a // 2a
list<Symbol> leftSide, rightSide; list<Symbol> leftSide, rightSide;
leftSide.push_back( Symbol( transition.getTo( ).getName( ) ) ); leftSide.push_back( symbolMap.getNonTerminal( transition.getTo( ) ) );
rightSide.push_back( Symbol( transition.getFrom( ).getName( ) ) ); rightSide.push_back( symbolMap.getNonTerminal( transition.getFrom( ) ) );
rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); rightSide.push_back( transition.getInput( ) );
m_grammar.addRule( Rule( leftSide, rightSide ) ); m_grammar.addRule( Rule( leftSide, rightSide ) );
   
// 2b // 2b
if( isInSet( transition.getFrom( ), m_fsm.getInitialStates( ) ) ) if( isInSet( transition.getFrom( ), m_fsm.getInitialStates( ) ) )
{ {
list<Symbol> leftSide, rightSide; list<Symbol> leftSide, rightSide;
leftSide.push_back( Symbol( transition.getTo( ).getName( ) ) ); leftSide.push_back( symbolMap.getNonTerminal( transition.getTo( ) ) );
rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); rightSide.push_back( transition.getInput( ) );
m_grammar.addRule( Rule( leftSide, rightSide ) ); m_grammar.addRule( Rule( leftSide, rightSide ) );
} }
} }
......
...@@ -19,31 +19,33 @@ FAtoRRGConverter::~FAtoRRGConverter( void ) ...@@ -19,31 +19,33 @@ FAtoRRGConverter::~FAtoRRGConverter( void )
   
RightRegularGrammar FAtoRRGConverter::convert( void ) RightRegularGrammar FAtoRRGConverter::convert( void )
{ {
createTerminalSymbols( m_grammar ); for( const auto & symbol : m_fsm.getInputAlphabet( ) )
createNonTerminalSymbols( m_grammar ); m_grammar.addTerminalSymbol( symbol );
StateNonterminalMap symbolMap( m_fsm, m_grammar );
   
// step 2 - create set of P in G // step 2 - create set of P in G
for( const auto & transition : m_fsm.getTransitions( ) ) for( const auto & transition : m_fsm.getTransitions( ) )
{ {
// 2a // 2a
list<Symbol> leftSide, rightSide; list<Symbol> leftSide, rightSide;
leftSide.push_back( Symbol( transition.getFrom( ).getName( ) ) ); leftSide.push_back( symbolMap.getNonTerminal( transition.getFrom( ) ) );
rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); rightSide.push_back( transition.getInput( ) );
rightSide.push_back( Symbol( transition.getTo( ).getName( ) ) ); rightSide.push_back( symbolMap.getNonTerminal( transition.getTo( ) ) );
m_grammar.addRule( Rule( leftSide, rightSide ) ); m_grammar.addRule( Rule( leftSide, rightSide ) );
   
// 2b // 2b
if( isInSet( transition.getTo( ), m_fsm.getFinalStates( ) ) ) if( isInSet( transition.getTo( ), m_fsm.getFinalStates( ) ) )
{ {
list<Symbol> leftSide, rightSide; list<Symbol> leftSide, rightSide;
leftSide.push_back( Symbol( transition.getFrom( ).getName( ) ) ); leftSide.push_back( symbolMap.getNonTerminal( transition.getFrom( ) ) );
rightSide.push_back( Symbol( transition.getInput( ).getSymbol( ) ) ); rightSide.push_back( transition.getInput( ) );
m_grammar.addRule( Rule( leftSide, rightSide ) ); m_grammar.addRule( Rule( leftSide, rightSide ) );
} }
} }
   
// step 3 - set start symbol of G // 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 // step 4
if( isInSet( State( m_grammar.getStartSymbol( ).getSymbol( ) ), m_fsm.getFinalStates( ) ) ) if( isInSet( State( m_grammar.getStartSymbol( ).getSymbol( ) ), m_fsm.getFinalStates( ) ) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment