From bbd90d39ba92f49271622e41b7dfd9aa52f51ced Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 19 Jul 2016 08:20:17 +0200 Subject: [PATCH] make optimisation functions static --- .../src/regexp/simplify/RegExpOptimize.h | 47 +++-- .../simplify/RegExpOptimizeUnboundedPart.cxx | 180 +++++++++--------- 2 files changed, 109 insertions(+), 118 deletions(-) diff --git a/alib2algo/src/regexp/simplify/RegExpOptimize.h b/alib2algo/src/regexp/simplify/RegExpOptimize.h index e8d24797f9..81dab1c699 100644 --- a/alib2algo/src/regexp/simplify/RegExpOptimize.h +++ b/alib2algo/src/regexp/simplify/RegExpOptimize.h @@ -61,8 +61,7 @@ namespace simplify { * * - X1 : -> : a* + \e = a* */ -class RegExpOptimize : public std::SingleDispatch<RegExpOptimize, regexp::RegExp, regexp::RegExpBase> -{ +class RegExpOptimize : public std::SingleDispatch<RegExpOptimize, regexp::RegExp, regexp::RegExpBase> { public: RegExpOptimize() {} @@ -85,28 +84,28 @@ private: regexp::UnboundedRegExpElement * optimize( regexp::UnboundedRegExpEmpty const * const & node ) const; private: - bool A1( regexp::UnboundedRegExpAlternation * const & node ) const; - bool A2( regexp::UnboundedRegExpAlternation * const & node ) const; - bool A3( regexp::UnboundedRegExpAlternation * const & node ) const; - bool A4( regexp::UnboundedRegExpAlternation * const & node ) const; - bool A5( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool A6( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool A7( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool A8( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool A9( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool A10( regexp::UnboundedRegExpAlternation * const & node ) const; - bool A11( regexp::UnboundedRegExpIteration * const & node ) const; - bool V1( regexp::UnboundedRegExpIteration * const & node ) const; - bool V2( regexp::UnboundedRegExpAlternation * const & node ) const; - bool V3( regexp::UnboundedRegExpIteration * const & node ) const; - bool V4( regexp::UnboundedRegExpIteration * const & node ) const; - bool V5( regexp::UnboundedRegExpAlternation * const & node ) const; - bool V6( regexp::UnboundedRegExpAlternation * const & node ) const; - bool V8( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool V9( regexp::UnboundedRegExpConcatenation * const & node ) const; - bool V10( regexp::UnboundedRegExpIteration * const & node ) const; - - bool X1( regexp::UnboundedRegExpAlternation * const & node ) const; + static bool A1( regexp::UnboundedRegExpAlternation & node ); + static bool A2( regexp::UnboundedRegExpAlternation & node ); + static bool A3( regexp::UnboundedRegExpAlternation & node ); + static bool A4( regexp::UnboundedRegExpAlternation & node ); + static bool A5( regexp::UnboundedRegExpConcatenation & node ); + static bool A6( regexp::UnboundedRegExpConcatenation & node ); + static bool A7( regexp::UnboundedRegExpConcatenation & node ); + static bool A8( regexp::UnboundedRegExpConcatenation & node ); + static bool A9( regexp::UnboundedRegExpConcatenation & node ); + static bool A10( regexp::UnboundedRegExpAlternation & node ); + static bool A11( regexp::UnboundedRegExpIteration & node ); + static bool V1( regexp::UnboundedRegExpIteration & node ); + static bool V2( regexp::UnboundedRegExpAlternation & node ); + static bool V3( regexp::UnboundedRegExpIteration & node ); + static bool V4( regexp::UnboundedRegExpIteration & node ); + static bool V5( regexp::UnboundedRegExpAlternation & node ); + static bool V6( regexp::UnboundedRegExpAlternation & node ); + static bool V8( regexp::UnboundedRegExpConcatenation & node ); + static bool V9( regexp::UnboundedRegExpConcatenation & node ); + static bool V10( regexp::UnboundedRegExpIteration & node ); + + static bool X1( regexp::UnboundedRegExpAlternation & node ); bool S( regexp::FormalRegExpElement * & node ) const; bool A1( regexp::FormalRegExpElement * & node ) const; diff --git a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx index 7a073174a4..1fb2421e80 100644 --- a/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx +++ b/alib2algo/src/regexp/simplify/RegExpOptimizeUnboundedPart.cxx @@ -89,7 +89,7 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpAlternation co alt->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( optimize( child.get() ) ) ); // optimize while you can - while( A1( alt ) || A2( alt ) || A3( alt ) || A4( alt ) || A10( alt ) || V2( alt ) || V5( alt ) || V6( alt ) || X1( alt ) ); + while( A1( * alt ) || A2( * alt ) || A3( * alt ) || A4( * alt ) || A10( * alt ) || V2( * alt ) || V5( * alt ) || V6( * alt ) || X1( * alt ) ); if( alt->getElements ( ).size( ) == 1 ) { UnboundedRegExpElement* ret = alt->getChildren ( ).front ( ).release ( ); @@ -111,7 +111,7 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpConcatenation for( const auto & child : node->getElements ( ) ) concat->pushBackChild ( std::smart_ptr < UnboundedRegExpElement > ( optimize( child.get() ) ) ); - while( A5( concat ) || A6( concat ) || A7( concat ) || A8( concat ) || A9( concat ) || V8( concat ) );//|| V9( concat ) ); + while( A5( * concat ) || A6( * concat ) || A7( * concat ) || A8( * concat ) || A9( * concat ) || V8( * concat ) );//|| V9( * concat ) ); if( concat->getElements ( ).size( ) == 1 ) { UnboundedRegExpElement* ret = concat->getChildren ( ).front( ).release(); @@ -142,7 +142,7 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpIteration cons delete iter; return new UnboundedRegExpEpsilon( ); } - } while( A11( iter ) || V1( iter ) || V3( iter ) || V4( iter ) || V10( iter ) ); + } while( A11( * iter ) || V1( * iter ) || V3( * iter ) || V4( * iter ) || V10( * iter ) ); return iter; } @@ -164,14 +164,15 @@ UnboundedRegExpElement * RegExpOptimize::optimize( UnboundedRegExpEpsilon const * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::A1( UnboundedRegExpAlternation & node ) { bool optimized = false; - for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) { + + for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) { if( dynamic_cast < UnboundedRegExpAlternation * > ( it->get ( ) ) ) { std::smart_ptr < UnboundedRegExpAlternation > childAlt ( static_cast < UnboundedRegExpAlternation * >( it->release() ) ); - it = node->getChildren ( ).erase( it ); + it = node.getChildren ( ).erase( it ); - it = node->insert( it, std::make_move_iterator(childAlt->getChildren ( ).begin ( ) ), std::make_move_iterator(childAlt->getChildren ( ).end ( ) ) ); + it = node.insert( it, std::make_move_iterator(childAlt->getChildren ( ).begin ( ) ), std::make_move_iterator(childAlt->getChildren ( ).end ( ) ) ); optimized = true; } else @@ -186,13 +187,13 @@ bool RegExpOptimize::A1( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::A2( UnboundedRegExpAlternation & node ) { auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a < *b; }; - if( std::is_sorted( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), cmp ) ) + if( std::is_sorted( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), cmp ) ) return false; - std::sort( node->getChildren ( ).begin(), node->getChildren ( ).end(), cmp ); + std::sort( node.getChildren ( ).begin(), node.getChildren ( ).end(), cmp ); return true; } @@ -201,14 +202,14 @@ bool RegExpOptimize::A2( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::A3( UnboundedRegExpAlternation & node ) { bool optimized = false; // alternation with no children is efectively \0 - for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) { + for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) { if( dynamic_cast < UnboundedRegExpEmpty * >( it->get ( ) ) ) { - it = node->getChildren ( ).erase( it ); + it = node.getChildren ( ).erase( it ); optimized = true; } else @@ -223,7 +224,7 @@ bool RegExpOptimize::A3( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::A4( UnboundedRegExpAlternation & node ) { /* * two ways of implementing this opitimization: * - sort and call std::unique ( O(n lg n) + O(n) ), but it also sorts... @@ -233,10 +234,10 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const { */ auto cmp = [ ]( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; }; - size_t size = node->getChildren ( ).size ( ); - std::unique ( node->getChildren ( ).begin ( ), node->getChildren ( ).end ( ), cmp); + size_t size = node.getChildren ( ).size ( ); + std::unique ( node.getChildren ( ).begin ( ), node.getChildren ( ).end ( ), cmp); - return size != node->getChildren ( ).size ( ); + return size != node.getChildren ( ).size ( ); } /** @@ -244,15 +245,15 @@ bool RegExpOptimize::A4( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node ) const { +bool RegExpOptimize::A5( UnboundedRegExpConcatenation & node ) { bool optimized = false; - for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) { + for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) { if( dynamic_cast<UnboundedRegExpConcatenation *>( it->get() ) ) { std::smart_ptr < UnboundedRegExpConcatenation > childConcat ( static_cast<UnboundedRegExpConcatenation *>( it->release() ) ); - it = node->getChildren ( ).erase( it ); + it = node.getChildren ( ).erase( it ); - it = node->insert( it, std::make_move_iterator(childConcat->getChildren ( ).begin( )), std::make_move_iterator(childConcat->getChildren ( ).end( ) )); + it = node.insert( it, std::make_move_iterator(childConcat->getChildren ( ).begin( )), std::make_move_iterator(childConcat->getChildren ( ).end( ) )); optimized = true; } else @@ -267,14 +268,14 @@ bool RegExpOptimize::A5( UnboundedRegExpConcatenation * const & node ) const { * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node ) const { +bool RegExpOptimize::A6( UnboundedRegExpConcatenation & node ) { bool optimized = false; // concatenation with no children is efectively \e - for( auto it = node->getChildren ( ).begin( ); it != node->getChildren ( ).end( ); ) { + for( auto it = node.getChildren ( ).begin( ); it != node.getChildren ( ).end( ); ) { if( dynamic_cast < UnboundedRegExpEpsilon * >( it->get ( ) ) ) { - it = node->getChildren ( ).erase( it ); + it = node.getChildren ( ).erase( it ); optimized = true; } else @@ -289,12 +290,12 @@ bool RegExpOptimize::A6( UnboundedRegExpConcatenation * const & node ) const { * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node ) const { - if( std::any_of( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), []( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast < UnboundedRegExpEmpty * >( a.get() ); } ) ) { - if(node->getChildren ( ).size() == 1) return false; +bool RegExpOptimize::A7( UnboundedRegExpConcatenation & node ) { + if(node.getChildren ( ).size() == 1) return false; - node->getChildren ( ).clear( ); - node->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEmpty( ) ) ); + if( std::any_of( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), []( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast < UnboundedRegExpEmpty * >( a.get() ); } ) ) { + node.getChildren ( ).clear( ); + node.pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( new UnboundedRegExpEmpty( ) ) ); return true; } @@ -307,8 +308,7 @@ bool RegExpOptimize::A7( UnboundedRegExpConcatenation * const & node ) const { * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A8( UnboundedRegExpConcatenation * const & /* node */) const -{ +bool RegExpOptimize::A8( UnboundedRegExpConcatenation & /* node */) { /* bool optimized = false; @@ -355,8 +355,7 @@ bool RegExpOptimize::A8( UnboundedRegExpConcatenation * const & /* node */) cons * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A9( UnboundedRegExpConcatenation * const & /* node */) const -{ +bool RegExpOptimize::A9( UnboundedRegExpConcatenation & /* node */) { /* bool optimized = false; @@ -406,7 +405,7 @@ bool RegExpOptimize::A9( UnboundedRegExpConcatenation * const & /* node */) cons * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::A10( UnboundedRegExpAlternation & node ) { bool optimized = false; /* @@ -416,15 +415,15 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const { */ // check if we have some epsilon or iteration left, else nothing to do - auto eps = find_if( node->getElements().begin( ), node->getElements().end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { + auto eps = find_if( node.getElements().begin( ), node.getElements().end( ), [ ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon const *>( a.get() ) || dynamic_cast<UnboundedRegExpIteration const*>( a.get() ); }); - if( eps == node->getElements().end( ) ) + if( eps == node.getElements().end( ) ) return false; - for( unsigned i = 0; i < node->getChildren ( ).size ( ); i++ ) { - UnboundedRegExpConcatenation * childConcat = dynamic_cast<UnboundedRegExpConcatenation *>( node->getChildren ( ) [ i ].get ( ) ); + for( unsigned i = 0; i < node.getChildren ( ).size ( ); i++ ) { + UnboundedRegExpConcatenation * childConcat = dynamic_cast<UnboundedRegExpConcatenation *>( node.getChildren ( ) [ i ].get ( ) ); if( ! childConcat ) continue; @@ -436,13 +435,13 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const { // concatenation without the iteration node UnboundedRegExpConcatenation tmpConcat ( * childConcat ); tmpConcat.getChildren ( ).erase( tmpConcat.getChildren ( ).begin( ) ); + UnboundedRegExpElement * tmpConcatOpt = RegExpOptimize::REG_EXP_OPTIMIZE.optimize ( & tmpConcat ); - UnboundedRegExpElement * tmpConcatOpt = optimize( & tmpConcat ); // check if the iteration element is the same as the rest of the concatenation if( iter->getElement() == * tmpConcatOpt ) { optimized = true; - node->setChild ( std::move ( childConcat->getElements().front() ), i ); + node.setChild ( std::move ( childConcat->getElements().front() ), i ); } delete tmpConcatOpt; @@ -456,10 +455,8 @@ bool RegExpOptimize::A10( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpIteration node * @return bool true if optimization applied else false */ -bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const { - bool optimized = false; - - UnboundedRegExpAlternation * const & childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node->getChild ( ).get() ); +bool RegExpOptimize::A11( UnboundedRegExpIteration & node ) { + UnboundedRegExpAlternation * childAlt = dynamic_cast<UnboundedRegExpAlternation *>( node.getChild ( ).get() ); if( childAlt ) { // check if eps inside iteration's alternation @@ -472,11 +469,11 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const { return false; // remove eps from alternation - optimized = true; childAlt->getChildren ( ).erase( eps ); + return true; } - return optimized; + return false; } /** @@ -484,8 +481,7 @@ bool RegExpOptimize::A11( UnboundedRegExpIteration * const & node ) const { * @param node UnboundedRegExpIteration node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V1( UnboundedRegExpIteration * const &) const -{ +bool RegExpOptimize::V1( UnboundedRegExpIteration &) { // implemented in optimize( UnboundedRegExpIteration ) return false; @@ -496,7 +492,7 @@ bool RegExpOptimize::V1( UnboundedRegExpIteration * const &) const * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::V2( UnboundedRegExpAlternation & node ) { bool optimized = false; /* @@ -506,7 +502,7 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const { std::vector < UnboundedRegExpElement * > iterElements; // cache iter elements because of operator invalidation after erase - for( const std::smart_ptr < UnboundedRegExpElement > & n : node->getElements ( ) ) { + for( const std::smart_ptr < UnboundedRegExpElement > & n : node.getElements ( ) ) { UnboundedRegExpIteration * iter = dynamic_cast < UnboundedRegExpIteration * > ( n.get ( ) ); if( iter ) { UnboundedRegExpAlternation * inner = dynamic_cast < UnboundedRegExpAlternation * > ( iter->getChild ( ).get ( ) ); @@ -520,16 +516,16 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const { } for( UnboundedRegExpElement * n : iterElements ) { - auto it = find_if( node->getChildren().begin( ), node->getChildren().end( ), [ n ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { + auto it = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ n ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *n; }); - if( it == node->getChildren().end() ) { + if( it == node.getChildren().end() ) { continue; } optimized = true; - node->getChildren().erase( it ); + node.getChildren().erase( it ); } return optimized; @@ -540,10 +536,10 @@ bool RegExpOptimize::V2( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpIteration node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node ) const { - UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node->getChild ( ).get() ); +bool RegExpOptimize::V3( UnboundedRegExpIteration & node ) { + UnboundedRegExpIteration* childIter = dynamic_cast<UnboundedRegExpIteration*>( node.getChild ( ).get() ); if( childIter ) { - node->setChild ( std::move ( childIter->getChild ( ) ) ); + node.setChild ( std::move ( childIter->getChild ( ) ) ); return true; } @@ -556,20 +552,18 @@ bool RegExpOptimize::V3( UnboundedRegExpIteration * const & node ) const { * @param node UnboundedRegExpIteration node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node ) const { +bool RegExpOptimize::V4( UnboundedRegExpIteration & node ) { // interpretation: if iteration's element is concat and every concat's element is iteration - UnboundedRegExpConcatenation* cont = dynamic_cast<UnboundedRegExpConcatenation*>( node->getChild ( ).get() ); + UnboundedRegExpConcatenation* cont = dynamic_cast<UnboundedRegExpConcatenation*>( node.getChild ( ).get() ); if( ! cont || ! all_of( cont->getChildren ( ).begin( ), cont->getChildren ( ).end( ), [] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration * >( a.get() ); } ) ) return false; - UnboundedRegExpAlternation * newAlt = new UnboundedRegExpAlternation( ); + UnboundedRegExpAlternation newAlt; - for( const auto & n : cont->getChildren ( ) ) { - newAlt->pushBackChild ( std::move ( static_cast < UnboundedRegExpIteration * > ( n.get ( ) )->getChild ( ) ) ); - } + for( const auto & n : cont->getChildren ( ) ) + newAlt.pushBackChild ( std::move ( static_cast < UnboundedRegExpIteration * > ( n.get ( ) )->getChild ( ) ) ); - node->setChild ( std::smart_ptr < UnboundedRegExpElement > ( optimize ( newAlt ) ) ); - delete newAlt; + node.setChild ( std::smart_ptr < UnboundedRegExpElement > ( RegExpOptimize::REG_EXP_OPTIMIZE.optimize ( & newAlt ) ) ); return true; } @@ -579,8 +573,7 @@ bool RegExpOptimize::V4( UnboundedRegExpIteration * const & node ) const { * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & /* node */ ) const -{ +bool RegExpOptimize::V5( UnboundedRegExpAlternation & /* node */ ) { /* bool optimized = false; */ // reinterpretation: ax*y = ay+ax*xy @@ -733,7 +726,7 @@ bool RegExpOptimize::V5( UnboundedRegExpAlternation * const & /* node */ ) const * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::V6( UnboundedRegExpAlternation & node ) { bool optimized = false; // reinterpretation: ax*y = ay+axx*y @@ -743,7 +736,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { // y = rest (suffix) // prefix.xx*.suffix + prefix.suffix = prefix.x*.suffix - for( auto itA = node->getChildren ( ).begin( ); itA != node->getChildren ( ).end( ); ) { + for( auto itA = node.getChildren ( ).begin( ); itA != node.getChildren ( ).end( ); ) { UnboundedRegExpConcatenation * concat = dynamic_cast<UnboundedRegExpConcatenation*>( itA->get() ); if( ! concat ) { ++ itA; @@ -792,7 +785,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { } else { UnboundedRegExpConcatenation* tmpA = new UnboundedRegExpConcatenation( ); tmpA->insert( tmpA->getChildren().end( ), concat->getChildren().begin( ), itStartX ); - regexpA = optimize( tmpA ); + regexpA = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpA ); delete tmpA; } @@ -803,7 +796,7 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { } else { UnboundedRegExpConcatenation* tmpY = new UnboundedRegExpConcatenation( ); tmpY->insert( tmpY->getChildren().end( ), std::next( itC ), concat->getChildren ( ).end( ) ); - regexpY = optimize( tmpY ); + regexpY = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpY ); delete tmpY; } @@ -811,14 +804,14 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { UnboundedRegExpConcatenation* tmpAY = new UnboundedRegExpConcatenation( ); tmpAY->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) ); tmpAY->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) ); - UnboundedRegExpElement * regexpAY = optimize( tmpAY ); + UnboundedRegExpElement * regexpAY = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpAY ); regexpA = tmpAY->getChildren()[0].release(); regexpY = tmpAY->getChildren()[1].release(); delete tmpAY; - auto iterAY = find_if( node->getChildren().begin( ), node->getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } ); + auto iterAY = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ regexpAY ] ( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return *a == *regexpAY; } ); delete regexpAY; - if( iterAY == node->getChildren().end( ) ) { + if( iterAY == node.getChildren().end( ) ) { ++ itC; delete regexpA; @@ -829,20 +822,20 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { // if AY exists, then we can simply do this: // iterator invalidated, need to backup concat node UnboundedRegExpElement * tmpItA = itA->get(); - node->getChildren().erase( iterAY ); + node.getChildren().erase( iterAY ); // iterator invalidated, need to recall before erase - itA = find_if( node->getChildren().begin( ), node->getChildren().end( ), [ tmpItA ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *tmpItA; } ); + itA = find_if( node.getChildren().begin( ), node.getChildren().end( ), [ tmpItA ]( const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return *a == *tmpItA; } ); UnboundedRegExpConcatenation * tmpAltered = new UnboundedRegExpConcatenation( ); tmpAltered->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpA ) ); tmpAltered->pushBackChild( * itC ); tmpAltered->pushBackChild( std::smart_ptr < UnboundedRegExpElement > ( regexpY ) ); - UnboundedRegExpElement * regexpAltered = optimize( tmpAltered ); + UnboundedRegExpElement * regexpAltered = RegExpOptimize::REG_EXP_OPTIMIZE.optimize( tmpAltered ); delete tmpAltered; - node->setChild( std::smart_ptr < UnboundedRegExpElement > ( regexpAltered ), itA ); + node.setChild( std::smart_ptr < UnboundedRegExpElement > ( regexpAltered ), itA ); optimized = true; break; } @@ -858,15 +851,15 @@ bool RegExpOptimize::V6( UnboundedRegExpAlternation * const & node ) const { * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const { +bool RegExpOptimize::V8( UnboundedRegExpConcatenation & node ) { bool optimized = false; // interpretation: if there is iteration in concatenation node, and element of iteration contains eps and is straight before this iteration, then this element can be omitted - if ( node->getChildren ( ).size ( ) == 0 ) + if ( node.getChildren ( ).size ( ) == 0 ) return false; - for( auto it = next ( node->getChildren ( ).begin( ) ); it != node->getChildren ( ).end( ); ) { + for( auto it = next ( node.getChildren ( ).begin( ) ); it != node.getChildren ( ).end( ); ) { UnboundedRegExpIteration* iter = dynamic_cast<UnboundedRegExpIteration*>( it->get() ); if( ! iter ) { @@ -879,7 +872,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const { if( concat ) { // check if not out of bounds - if( ( unsigned ) distance( node->getChildren ( ).begin( ), it ) < concat->getChildren ( ).size ( ) ) { + if( ( unsigned ) distance( node.getChildren ( ).begin( ), it ) < concat->getChildren ( ).size ( ) ) { it ++; continue; } @@ -889,22 +882,22 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const { advance( it2, - (int) concat->getChildren().size( ) ); if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(*concat) && - concat->getChildren().size ( ) == ( unsigned ) distance ( it2, node->getChildren ( ).end( ) ) && + concat->getChildren().size ( ) == ( unsigned ) distance ( it2, node.getChildren ( ).end( ) ) && equal( concat->getChildren ( ).begin( ), concat->getChildren ( ).end( ), it2, [] ( const std::smart_ptr < UnboundedRegExpElement > & a, const std::smart_ptr < UnboundedRegExpElement > & b ) -> bool { return *a == *b; } ) ) { optimized = true; - it = node->getChildren().erase( it2, it ); + it = node.getChildren().erase( it2, it ); } else ++ it; } else { auto prev = std::prev ( it ); if( regexp::properties::RegExpEpsilon::languageContainsEpsilon(iter->getElement()) && iter->getElement ( ) == **prev ) { - it = node->getChildren().erase( prev ); + it = node.getChildren().erase( prev ); optimized = true; // in case xxx*, we need to stay on the iter element, not to go behind it - if( it != node->getChildren().begin( ) ) + if( it != node.getChildren().begin( ) ) it = std::prev( it ); } else ++ it; @@ -919,8 +912,7 @@ bool RegExpOptimize::V8( UnboundedRegExpConcatenation * const & node ) const { * @param node UnboundedRegExpConcatenation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & /* node */ ) const -{ +bool RegExpOptimize::V9( UnboundedRegExpConcatenation & /* node */ ) { /* bool optimized = false; */ // interpretation: if concat (C1) with iter && iteration's element is concat (C2), then: @@ -986,9 +978,9 @@ bool RegExpOptimize::V9( UnboundedRegExpConcatenation * const & /* node */ ) con * @param node UnboundedRegExpIteration node * @return bool true if optimization applied else false */ -bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node ) const { +bool RegExpOptimize::V10( UnboundedRegExpIteration & node ) { // interpretation: if iter's child is alternation where some of its children are iteration, then they do not have to be iterations - UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node->getChild ( ).get() ); + UnboundedRegExpAlternation* alt = dynamic_cast<UnboundedRegExpAlternation*>( node.getChild ( ).get() ); if( ! alt || ! any_of( alt->getChildren ( ).begin( ), alt->getChildren ( ).end( ), [] ( std::smart_ptr < UnboundedRegExpElement > & a ) -> bool{ return dynamic_cast<UnboundedRegExpIteration * >( a.get() ); } ) ) return false; @@ -1005,15 +997,15 @@ bool RegExpOptimize::V10( UnboundedRegExpIteration * const & node ) const { * @param node UnboundedRegExpAlternation node * @return bool true if optimization applied else false */ -bool RegExpOptimize::X1( UnboundedRegExpAlternation * const & node ) const { +bool RegExpOptimize::X1( UnboundedRegExpAlternation & node ) { // theorem: In regexp like a* + \e, \e is described twice, first in a*, second in \e. // therefore we can delete the \e as it is redundant - auto iter = find_if( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration * >( a.get() );} ); - auto eps = find_if( node->getChildren ( ).begin( ), node->getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon * >( a.get() );} ); + auto iter = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpIteration * >( a.get() );} ); + auto eps = find_if( node.getChildren ( ).begin( ), node.getChildren ( ).end( ), [] (const std::smart_ptr < UnboundedRegExpElement > & a ) -> bool { return dynamic_cast<UnboundedRegExpEpsilon * >( a.get() );} ); - if( iter != node->getChildren ( ).end( ) && eps != node->getChildren ( ).end( ) ) { - node->getChildren ( ).erase( eps ); + if( iter != node.getChildren ( ).end( ) && eps != node.getChildren ( ).end( ) ) { + node.getChildren ( ).erase( eps ); return true; } -- GitLab