diff --git a/aconversions/src/re2fa/Glushkov.cpp b/aconversions/src/re2fa/Glushkov.cpp index da982d3e97e52502f9da7ee53ab00f83b344fb19..b3c4e060c82a7b10bb621b18a6067c11a8a376b9 100644 --- a/aconversions/src/re2fa/Glushkov.cpp +++ b/aconversions/src/re2fa/Glushkov.cpp @@ -18,8 +18,7 @@ namespace conversions Glushkov::Glushkov( const RegExp & re ) : AbstractREtoFAConverter( re ) { - //FIXME in alib! - m_regexpRoot = const_cast<RegExp&>( m_re ).getRegExp( ); + } FSM Glushkov::convert( void ) @@ -40,41 +39,66 @@ FSM Glushkov::convert( void ) State q0( "q0" ); m_fsm.addState( q0 ); m_fsm.addInitialState( q0 ); - for( const auto & ns : m_numberedSymbols ) - m_fsm.addState( ns.m_state ); + for( const auto & kv : m_numberedSymbols ) + m_fsm.addState( kv.second.m_state ); // step 6 for( const auto & ns : m_beginSymbolSet ) - m_fsm.addTransition( TransitionFSM ( q0, ns->m_alphabetSymbol, ns->m_state ) ); + m_fsm.addTransition( q0, ns.m_alphabetSymbol, ns.m_state ); for( const auto & ns : m_neighbourSymbolSet ) - m_fsm.addTransition( TransitionFSM ( State( ns.first->m_state ), ns.second->m_alphabetSymbol, State( ns.second->m_state ) ) ); + { + const NumberedSymbol & first = m_numberedSymbols.find( ns.m_first )->second; + const NumberedSymbol & second = m_numberedSymbols.find( ns.m_second )->second; + + m_fsm.addTransition( first.m_state, second.m_alphabetSymbol, first.m_state ); + } // step 7 for( const auto & ns : m_endSymbolSet ) - m_fsm.addFinalState( State ( ns->m_state ) ); + m_fsm.addFinalState( State ( ns.m_state ) ); - if( m_regexpRoot->containsEmptyString( ) ) + if( m_re.containsEmptyString( ) ) m_fsm.addFinalState( q0 ); return m_fsm; } -// ---------------------------------------------------------------------------- +void Glushkov::initNumberSymbols( void ) +{ + int id = 1; + + for( const auto & symb : RegExpAlphabet::getSymbolsListInOrder( m_re ) ) + m_numberedSymbols.insert( pair<const RegExpSymbol*, NumberedSymbol>( symb, NumberedSymbol( symb, id ++ ) ) ); +} void Glushkov::constructBeginSymbolSet( void ) { - for( const auto & s : getLeftmostSymbolsInTree( m_regexpRoot ) ) - m_beginSymbolSet.insert( getNumberedSymbol( s ) ); + for( const auto & s : getLeftmostSymbolsInTree( m_re.getRegExp( ) ) ) + m_beginSymbolSet.insert( m_numberedSymbols.find( s )->second ); } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpElement * node ) const +void Glushkov::constructEndSymbolSet( void ) { - Alternation* alternation = dynamic_cast<Alternation*>( node ); - Concatenation* concatenation = dynamic_cast<Concatenation*>( node ); - Iteration* iteration = dynamic_cast<Iteration*>( node ); - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node ); - RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>( node ); - RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node ); + for( const auto & s : getRightmostSymbolsInTree( m_re.getRegExp( ) ) ) + m_endSymbolSet.insert( m_numberedSymbols.find( s )->second ); +} + +void Glushkov::constructNeighbourSymbolSet( void ) +{ + for( const auto & n : getNeighbours( m_re.getRegExp( ) ) ) + m_neighbourSymbolSet.insert( n ); +} + +// ---------------------------------------------------------------------------- + +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpElement * node ) const +{ + const Alternation* alternation = dynamic_cast<const Alternation*>( node ); + const Concatenation* concatenation = dynamic_cast<const Concatenation*>( node ); + const Iteration* iteration = dynamic_cast<const Iteration*>( node ); + const RegExpSymbol* symbol = dynamic_cast<const RegExpSymbol*>( node ); + const RegExpEmpty* empty = dynamic_cast<const RegExpEmpty*>( node ); + const RegExpEpsilon* eps = dynamic_cast<const RegExpEpsilon*>( node ); if( symbol ) return getLeftmostSymbolsInTree( symbol ); @@ -92,26 +116,26 @@ const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpElement * nod throw AlibException( "Glushkov::getLeftmostSymbolsInTree - invalid RegExpElement node" ); } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Alternation * node ) const +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const Alternation * node ) const { - set<RegExpSymbol*> ret; + set<const RegExpSymbol*> ret; for( const auto & e : node->getElements( ) ) { - const set<RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e ); + const set<const RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e ); ret.insert( tmp.begin( ), tmp.end( ) ); } return ret; } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Concatenation * node ) const +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const Concatenation * node ) const { - set<RegExpSymbol*> ret; + set<const RegExpSymbol*> ret; for( const auto & e : node->getElements( ) ) { - const set<RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e ); + set<const RegExpSymbol*> tmp = getLeftmostSymbolsInTree( e ); ret.insert( tmp.begin( ), tmp.end( ) ); if( ! e->containsEmptyString( ) ) // If this subtree can be epsilon, then we need to add next subtree also @@ -121,41 +145,35 @@ const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Concatenation * nod return ret; } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( Iteration * node ) const +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const Iteration * node ) const { return getLeftmostSymbolsInTree( node->getElement( ) ); } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpSymbol * node ) const +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpSymbol * node ) const { - return set<RegExpSymbol*> { node }; + return set<const RegExpSymbol*> { node }; } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpEpsilon * node ) const +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpEpsilon * node ) const { - return set<RegExpSymbol*>( ); + return set<const RegExpSymbol*>( ); } -const set<RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( RegExpEmpty * node ) const +set<const RegExpSymbol*> Glushkov::getLeftmostSymbolsInTree( const RegExpEmpty * node ) const { - return set<RegExpSymbol*>( ); + return set<const RegExpSymbol*>( ); } // ---------------------------------------------------------------------------- -void Glushkov::constructEndSymbolSet( void ) -{ - for( const auto & s : getRightmostSymbolsInTree( m_regexpRoot ) ) - m_endSymbolSet.insert( getNumberedSymbol( s ) ); -} - -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpElement * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpElement * node ) const { - Alternation* alternation = dynamic_cast<Alternation*>( node ); - Concatenation* concatenation = dynamic_cast<Concatenation*>( node ); - Iteration* iteration = dynamic_cast<Iteration*>( node ); - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node ); - RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>( node ); - RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node ); + const Alternation* alternation = dynamic_cast<const Alternation*>( node ); + const Concatenation* concatenation = dynamic_cast<const Concatenation*>( node ); + const Iteration* iteration = dynamic_cast<const Iteration*>( node ); + const RegExpSymbol* symbol = dynamic_cast<const RegExpSymbol*>( node ); + const RegExpEmpty* empty = dynamic_cast<const RegExpEmpty*>( node ); + const RegExpEpsilon* eps = dynamic_cast<const RegExpEpsilon*>( node ); if( symbol ) return getRightmostSymbolsInTree( symbol ); @@ -173,26 +191,26 @@ const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpElement * no throw AlibException( "Glushkov::getRightmostSymbolsInTree - invalid RegExpElement node" ); } -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Alternation * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const Alternation * node ) const { - set<RegExpSymbol*> ret; + set<const RegExpSymbol*> ret; for( const auto & e : node->getElements( ) ) { - const set<RegExpSymbol*> tmp = getRightmostSymbolsInTree( e ); + set<const RegExpSymbol*> tmp = getRightmostSymbolsInTree( e ); ret.insert( tmp.begin( ), tmp.end( ) ); } return ret; } -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Concatenation * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const Concatenation * node ) const { - set<RegExpSymbol*> ret; + set<const RegExpSymbol*> ret; for( auto it = node->getElements( ).rbegin( ); it != node->getElements( ).rend( ) ; it ++ ) { - const set<RegExpSymbol*> tmp = getRightmostSymbolsInTree( *it ); + set<const RegExpSymbol*> tmp = getRightmostSymbolsInTree( *it ); ret.insert( tmp.begin( ), tmp.end( ) ); if( ! ( * it )->containsEmptyString( ) ) @@ -202,45 +220,36 @@ const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Concatenation * no return ret; } -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( Iteration * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const Iteration * node ) const { return getRightmostSymbolsInTree( node->getElement( ) ); } -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpSymbol * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpSymbol * node ) const { - return set<RegExpSymbol*> { node }; + return set<const RegExpSymbol*> { node }; } -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpEpsilon * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpEpsilon * node ) const { - return set<RegExpSymbol*>( ); + return set<const RegExpSymbol*>( ); } -const set<RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( RegExpEmpty * node ) const +set<const RegExpSymbol*> Glushkov::getRightmostSymbolsInTree( const RegExpEmpty * node ) const { - return set<RegExpSymbol*>( ); + return set<const RegExpSymbol*>( ); } // ---------------------------------------------------------------------------- -void Glushkov::constructNeighbourSymbolSet( void ) +set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpElement * node ) const { - for( const auto & pair : getNeighbours( m_regexpRoot ) ) - { - std::pair<const NumberedSymbol*, const NumberedSymbol*> p( getNumberedSymbol( pair.first ), getNumberedSymbol( pair.second ) ); - m_neighbourSymbolSet.insert( p ); - } -} - -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpElement * node ) const -{ - Alternation* alternation = dynamic_cast<Alternation*>( node ); - Concatenation* concatenation = dynamic_cast<Concatenation*>( node ); - Iteration* iteration = dynamic_cast<Iteration*>( node ); - RegExpSymbol* symbol = dynamic_cast<RegExpSymbol*>( node ); - RegExpEmpty* empty = dynamic_cast<RegExpEmpty*>( node ); - RegExpEpsilon* eps = dynamic_cast<RegExpEpsilon*>( node ); + const Alternation* alternation = dynamic_cast<const Alternation*>( node ); + const Concatenation* concatenation = dynamic_cast<const Concatenation*>( node ); + const Iteration* iteration = dynamic_cast<const Iteration*>( node ); + const RegExpSymbol* symbol = dynamic_cast<const RegExpSymbol*>( node ); + const RegExpEmpty* empty = dynamic_cast<const RegExpEmpty*>( node ); + const RegExpEpsilon* eps = dynamic_cast<const RegExpEpsilon*>( node ); if( symbol ) return getNeighbours( symbol ); @@ -258,25 +267,25 @@ const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbour throw AlibException( "Glushkov::getNeighbours - unknown RegExpElement* " ); } -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( Alternation * node ) const +set<Glushkov::Neighbours> Glushkov::getNeighbours( const Alternation * node ) const { - set<pair<const RegExpSymbol*, const RegExpSymbol*>> pairs; + set<Neighbours> n; for( const auto & e : node->getElements( ) ) { - const set<pair<const RegExpSymbol*, const RegExpSymbol*>> tmp = getNeighbours( e ); - pairs.insert( tmp.begin( ), tmp.end( ) ); + set<Neighbours> tmp = getNeighbours( e ); + n.insert( tmp.begin( ), tmp.end( ) ); } - return pairs; + return n; } -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( Concatenation * node ) const +set<Glushkov::Neighbours> Glushkov::getNeighbours( const Concatenation * node ) const { - set<pair<const RegExpSymbol*, const RegExpSymbol*>> pairs; + set<Neighbours> n; for( const auto & e : node->getElements( ) ) { - const set<pair<const RegExpSymbol*, const RegExpSymbol*>> tmp = getNeighbours( e ); - pairs.insert( tmp.begin( ), tmp.end( ) ); + set<Neighbours> tmp = getNeighbours( e ); + n.insert( tmp.begin( ), tmp.end( ) ); } for( auto e = node->getElements( ).begin( ); e != node->getElements( ).end( ); e ++ ) @@ -285,70 +294,50 @@ const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbour if( f == node->getElements( ).end( ) ) continue; - const set<RegExpSymbol*> rightmost = getRightmostSymbolsInTree( * e ); - for( f++ ; f != node->getElements( ).end( ); f ++ ) { - const set<RegExpSymbol*> leftmost = getLeftmostSymbolsInTree( * f ); - for( const auto & x : rightmost ) - for( const auto & y : leftmost ) - pairs.insert( pair<const RegExpSymbol*, const RegExpSymbol*>( x, y ) ); + for( const auto & x : getRightmostSymbolsInTree( * e ) ) + for( const auto & y : getLeftmostSymbolsInTree( * f ) ) + n.insert( Neighbours( x, y ) ); if( ! ( * f )->containsEmptyString( ) ) break; } } - return pairs; + return n; } -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( Iteration * node ) const +set<Glushkov::Neighbours> Glushkov::getNeighbours( const Iteration * node ) const { - set<pair<const RegExpSymbol*, const RegExpSymbol*>> pairs; - const set<pair<const RegExpSymbol*, const RegExpSymbol*>> tmp = getNeighbours( node->getElement( ) ); - pairs.insert( tmp.begin( ), tmp.end( ) ); + set<Neighbours> n; + set<Neighbours> tmp = getNeighbours( node->getElement( ) ); + n.insert( tmp.begin( ), tmp.end( ) ); - const set<RegExpSymbol*> leftmost = getLeftmostSymbolsInTree( node->getElement( ) ); for( const auto & x : getRightmostSymbolsInTree( node->getElement( ) ) ) - for( const auto & y : leftmost ) - pairs.insert( pair<const RegExpSymbol*, const RegExpSymbol*>( x, y ) ); + for( const auto & y : getLeftmostSymbolsInTree( node->getElement( ) ) ) + n.insert( Neighbours( x, y ) ); - return pairs; + return n; } -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpSymbol * node ) const +set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpSymbol * node ) const { - return set<pair<const RegExpSymbol*, const RegExpSymbol*>>(); + return set<Neighbours>( ); } -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpEpsilon * node ) const +set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpEpsilon * node ) const { - return set<pair<const RegExpSymbol*, const RegExpSymbol*>>(); + return set<Neighbours>( ); } -const set<pair<const RegExpSymbol*, const RegExpSymbol*>> Glushkov::getNeighbours( RegExpEmpty * node ) const +set<Glushkov::Neighbours> Glushkov::getNeighbours( const RegExpEmpty * node ) const { - return set<pair<const RegExpSymbol*, const RegExpSymbol*>>(); + return set<Neighbours>( ); } // ---------------------------------------------------------------------------- -void Glushkov::initNumberSymbols( void ) -{ - int iter = 1; - - for( const auto & symb : RegExpAlphabet::getSymbolsListInOrder( m_re ) ) - m_numberedSymbols.insert( NumberedSymbol( symb, iter ++ ) ); -} -const Glushkov::NumberedSymbol * Glushkov::getNumberedSymbol( const RegExpSymbol * symbol ) const -{ - for( auto it = m_numberedSymbols.begin( ); it != m_numberedSymbols.end( ); it ++ ) - if( it->m_regexpSymbol == symbol ) - return & ( *it ); - - throw AlibException( "Glushkov::getNumberedSymbol - no symbol found!" ); -} - bool Glushkov::NumberedSymbol::operator<( const NumberedSymbol & x ) const { return m_i < x.m_i; @@ -356,11 +345,27 @@ bool Glushkov::NumberedSymbol::operator<( const NumberedSymbol & x ) const Glushkov::NumberedSymbol::NumberedSymbol( const RegExpSymbol * symbol, int i ) : m_i( i ), - m_regexpSymbol( symbol ), - m_alphabetSymbol( Symbol( m_regexpSymbol->getSymbol( ) ) ), + m_alphabetSymbol( symbol->getSymbol( ) ), m_state( State( "[" + m_alphabetSymbol.getSymbol( ) + "], id " + to_string( m_i ) ) ) { } +// ---------------------------------------------------------------------------- + +Glushkov::Neighbours::Neighbours( const RegExpSymbol * first, const RegExpSymbol * second ) : + m_first( first ), + m_second( second ) +{ + +} + +bool Glushkov::Neighbours::operator<( const Neighbours & x ) const +{ + if( m_first != x.m_first ) + return m_first < x.m_first; + else + return m_second < x.m_second; +} + } /* namespace conversions */ diff --git a/aconversions/src/re2fa/Glushkov.h b/aconversions/src/re2fa/Glushkov.h index 6fd433892c7249dd681181194ad57bbeb3cbeef9..525750b4b60fc37d93c927048c25285a5e0ae00e 100644 --- a/aconversions/src/re2fa/Glushkov.h +++ b/aconversions/src/re2fa/Glushkov.h @@ -37,7 +37,6 @@ private: struct NumberedSymbol { const int m_i; - const regexp::RegExpSymbol * m_regexpSymbol; const alphabet::Symbol m_alphabetSymbol; const automaton::State m_state; @@ -45,44 +44,47 @@ private: bool operator<( const NumberedSymbol & x ) const; }; - void initNumberSymbols( void ); - const NumberedSymbol * getNumberedSymbol( const regexp::RegExpSymbol * symbol ) const; + struct Neighbours + { + const regexp::RegExpSymbol * m_first, * m_second; + Neighbours( const regexp::RegExpSymbol * first, const regexp::RegExpSymbol * second ); + bool operator<( const Neighbours & x ) const; + }; + + void initNumberSymbols( void ); void constructBeginSymbolSet( void ); void constructEndSymbolSet( void ); void constructNeighbourSymbolSet( void ); // TODO: consider moving these to independent class or regexputils - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpElement * node ) const; - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::Alternation * node ) const; - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::Concatenation * node ) const; - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::Iteration * node ) const; - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpSymbol * node ) const; - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpEmpty * node ) const; - const std::set<regexp::RegExpSymbol*> getLeftmostSymbolsInTree( regexp::RegExpEpsilon * node ) const; - - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpElement * node ) const; - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::Alternation * node ) const; - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::Concatenation * node ) const; - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::Iteration * node ) const; - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpSymbol * node ) const; - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpEmpty * node ) const; - const std::set<regexp::RegExpSymbol*> getRightmostSymbolsInTree( regexp::RegExpEpsilon * node ) const; - - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpElement * node ) const; - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::Alternation * node ) const; - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::Concatenation * node ) const; - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::Iteration * node ) const; - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpSymbol * node ) const; - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpEmpty * node ) const; - const std::set<std::pair<const regexp::RegExpSymbol*, const regexp::RegExpSymbol*>> getNeighbours( regexp::RegExpEpsilon * node ) const; - - regexp::RegExpElement* m_regexpRoot; - - //TODO: Lists would be better here for complexity issues of set insert method - std::set<NumberedSymbol> m_numberedSymbols; - std::set<const NumberedSymbol*> m_beginSymbolSet, m_endSymbolSet; - std::set<std::pair<const NumberedSymbol*, const NumberedSymbol*>> m_neighbourSymbolSet; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpElement * node ) const; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::Alternation * node ) const; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::Concatenation * node ) const; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::Iteration * node ) const; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpSymbol * node ) const; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpEmpty * node ) const; + std::set<const regexp::RegExpSymbol*> getLeftmostSymbolsInTree( const regexp::RegExpEpsilon * node ) const; + + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpElement * node ) const; + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::Alternation * node ) const; + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::Concatenation * node ) const; + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::Iteration * node ) const; + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpSymbol * node ) const; + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpEmpty * node ) const; + std::set<const regexp::RegExpSymbol*> getRightmostSymbolsInTree( const regexp::RegExpEpsilon * node ) const; + + std::set<Neighbours> getNeighbours( const regexp::RegExpElement * node ) const; + std::set<Neighbours> getNeighbours( const regexp::Alternation * node ) const; + std::set<Neighbours> getNeighbours( const regexp::Concatenation * node ) const; + std::set<Neighbours> getNeighbours( const regexp::Iteration * node ) const; + std::set<Neighbours> getNeighbours( const regexp::RegExpSymbol * node ) const; + std::set<Neighbours> getNeighbours( const regexp::RegExpEmpty * node ) const; + std::set<Neighbours> getNeighbours( const regexp::RegExpEpsilon * node ) const; + + std::map<const regexp::RegExpElement*, NumberedSymbol> m_numberedSymbols; + std::set<NumberedSymbol> m_beginSymbolSet, m_endSymbolSet; + std::set<Neighbours> m_neighbourSymbolSet; };