/* * GlushkovRRG.cpp * * Created on: 11. 1. 2014 * Author: tomas */ #include "GlushkovRRG.h" using namespace alib; using namespace alphabet; using namespace grammar; using namespace regexp; using namespace std; namespace conversions { GlushkovRRG::GlushkovRRG( const RegExp & re ) : m_re( re ) { } GlushkovRRG::~GlushkovRRG( void ) { } RightRegularGrammar GlushkovRRG::convert( void ) { RightRegularGrammar grammar; // step 1 for( auto const& symbol : m_re.getAlphabet( ) ) grammar.addTerminalSymbol( symbol.getSymbol( ) ); // steps 2, 3, 4 m_first = GlushkovTraversal::first( m_re ); m_last = GlushkovTraversal::last( m_re ); for( auto const& x : GlushkovTraversal::getSymbols( m_re ) ) for( auto const& f : GlushkovTraversal::follow( m_re, x ) ) m_pairs.insert( GlushkovPair( x, f ) ); // \e in q0 check is in step 7 // step 5 Symbol S = grammar.createUniqueNonTerminalSymbol( "S" ); grammar.setStartSymbol( S ); int nonterminalId = 0; for( auto const& symbol : GlushkovTraversal::getSymbols( m_re ) ) { Symbol a = grammar.createUniqueNonTerminalSymbol( toBase26( nonterminalId ++ ) + to_string( symbol.getId( ) ) ); m_symbolMap.insert( std::pair<GlushkovSymbol, Symbol>( symbol, a ) ); } // step 6 for( auto const& symbol : m_first ) { Symbol const& a = m_symbolMap.find( symbol )->second; list<Symbol> leftSide = { S }; list<Symbol> rightSide = { symbol.getInputSymbol( ), a }; grammar.addRule( Rule( leftSide, rightSide ) ); } for( auto const& pair : m_pairs ) { Symbol const& a = m_symbolMap.find( pair.getFirst( ) )->second; Symbol const& b = m_symbolMap.find( pair.getSecond( ) )->second; list<Symbol> leftSide = { a }; list<Symbol> rightSide = { pair.getSecond( ).getInputSymbol( ), b }; grammar.addRule( Rule( leftSide, rightSide ) ); } // step 7 for( auto const& symbol : m_last ) { /* * for all rules where ns.m_nonTerminal is on rightSide: * add Rule: leftSide -> symbol.getSymbol( ) * unless it already exists */ Symbol const& a = m_symbolMap.find( symbol )->second; for( auto const & rule : grammar.getRules( ) ) { if( isInList( a, rule.getRightSide( ) ) ) { list<Symbol> leftSide = rule.getLeftSide( ); list<Symbol> rightSide = { symbol.getInputSymbol( ) }; Rule r( leftSide, rightSide ); if( ! isInSet( r, grammar.getRules( ) ) ) grammar.addRule( r ); } } } if( m_re.containsEmptyString( ) ) { list<Symbol> leftSide = { S }; list<Symbol> rightSide = { }; grammar.addRule( Rule( leftSide, rightSide ) ); } return grammar; } } /* namespace conversions */