diff --git a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp index 784901e81964ac319e49f4dcdb2d685b668cca4a..a25a07cea609d18b773a3902a520d818a12f7da2 100644 --- a/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp +++ b/alib2algo/src/regexp/convert/ToAutomatonGlushkov.cpp @@ -14,8 +14,10 @@ #include "object/Object.h" -#include "../glushkov/GlushkovTraversal.h" +#include "../glushkov/GlushkovFollow.h" #include "../glushkov/GlushkovIndexate.h" +#include "../glushkov/GlushkovFirst.h" +#include "../glushkov/GlushkovLast.h" #include "../properties/RegExpEpsilon.h" #include <exception/CommonException.h> @@ -38,8 +40,8 @@ automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovIndexate::index ( regexp ); // steps 2, 3, 4 - const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp ); - const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp ); + const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovFirst::first ( indexedRegExp ); + const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovLast::last ( indexedRegExp ); // \e in q0 check is in step 7 @@ -49,14 +51,14 @@ automaton::NFA < > ToAutomatonGlushkov::convert ( const regexp::UnboundedRegExp // step 6 for ( auto const & symbol : first ) - automaton.addTransition ( q0, regexp::GlushkovTraversal::getSymbolFromGlushkovPair ( symbol.getSymbol ( ) ), label::Label ( label::ObjectLabel ( alib::Object ( symbol.getSymbol ( ).getData ( ) ) ) ) ); + automaton.addTransition ( q0, regexp::GlushkovIndexate::getSymbolFromGlushkovPair ( symbol.getSymbol ( ) ), label::Label ( label::ObjectLabel ( alib::Object ( symbol.getSymbol ( ).getData ( ) ) ) ) ); for ( const auto & x : indexedRegExp.getAlphabet ( ) ) - for ( const auto & f : regexp::GlushkovTraversal::follow ( indexedRegExp, UnboundedRegExpSymbol < alphabet::Symbol > ( x ) ) ) { + for ( const auto & f : regexp::GlushkovFollow::follow ( indexedRegExp, UnboundedRegExpSymbol < alphabet::Symbol > ( x ) ) ) { const alphabet::Symbol & p = x; const alphabet::Symbol & q = f.getSymbol ( ); - automaton.addTransition ( label::Label ( label::ObjectLabel ( alib::Object ( p.getData ( ) ) ) ), regexp::GlushkovTraversal::getSymbolFromGlushkovPair ( q ), label::Label ( label::ObjectLabel ( alib::Object ( q.getData ( ) ) ) ) ); + automaton.addTransition ( label::Label ( label::ObjectLabel ( alib::Object ( p.getData ( ) ) ) ), regexp::GlushkovIndexate::getSymbolFromGlushkovPair ( q ), label::Label ( label::ObjectLabel ( alib::Object ( q.getData ( ) ) ) ) ); } // step 7 diff --git a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp index 9d95ce23b81c26dc5652dec6a4676be4e50e56c9..8b8f2a655d29cc4ac992b603dafa923807072cda 100644 --- a/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp +++ b/alib2algo/src/regexp/convert/ToGrammarRightRGGlushkov.cpp @@ -16,8 +16,10 @@ #include <object/Object.h> -#include "../glushkov/GlushkovTraversal.h" +#include "../glushkov/GlushkovFollow.h" #include "../glushkov/GlushkovIndexate.h" +#include "../glushkov/GlushkovFirst.h" +#include "../glushkov/GlushkovLast.h" #include "../properties/RegExpEpsilon.h" #include <exception/CommonException.h> @@ -40,8 +42,8 @@ grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::Unbounded regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovIndexate::index ( regexp ); // steps 2, 3, 4 - const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp ); - const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp ); + const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovFirst::first ( indexedRegExp ); + const std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovLast::last ( indexedRegExp ); // \e in q0 check is in step 7 @@ -51,14 +53,14 @@ grammar::RightRG < > ToGrammarRightRGGlushkov::convert ( const regexp::Unbounded // step 6 for ( const auto & symbol : first ) - grammar.addRule ( S, std::make_pair ( regexp::GlushkovTraversal::getSymbolFromGlushkovPair ( symbol.getSymbol ( ) ), symbol.getSymbol ( ) ) ); + grammar.addRule ( S, std::make_pair ( regexp::GlushkovIndexate::getSymbolFromGlushkovPair ( symbol.getSymbol ( ) ), symbol.getSymbol ( ) ) ); for ( const auto & x : indexedRegExp.getAlphabet ( ) ) - for ( const auto & f : regexp::GlushkovTraversal::follow ( indexedRegExp, UnboundedRegExpSymbol < alphabet::Symbol > ( x ) ) ) { + for ( const auto & f : regexp::GlushkovFollow::follow ( indexedRegExp, UnboundedRegExpSymbol < alphabet::Symbol > ( x ) ) ) { const alphabet::Symbol & a = x; const alphabet::Symbol & b = f.getSymbol ( ); - grammar.addRule ( a, std::make_pair ( regexp::GlushkovTraversal::getSymbolFromGlushkovPair ( b ), b ) ); + grammar.addRule ( a, std::make_pair ( regexp::GlushkovIndexate::getSymbolFromGlushkovPair ( b ), b ) ); } // step 7 diff --git a/alib2algo/src/regexp/glushkov/GlushkovFirst.cpp b/alib2algo/src/regexp/glushkov/GlushkovFirst.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f40441b671d29f94f571ff85e6c5808679c9041d --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovFirst.cpp @@ -0,0 +1,66 @@ +/* + * GlushkovFirst.cpp + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#include "GlushkovFirst.h" +#include <regexp/unbounded/UnboundedRegExpAlternation.h> +#include <regexp/unbounded/UnboundedRegExpConcatenation.h> +#include <regexp/unbounded/UnboundedRegExpElement.h> +#include <regexp/unbounded/UnboundedRegExpEmpty.h> +#include <regexp/unbounded/UnboundedRegExpEpsilon.h> +#include <regexp/unbounded/UnboundedRegExpIteration.h> +#include <regexp/unbounded/UnboundedRegExpSymbol.h> + +#include "../properties/RegExpEpsilon.h" + +namespace regexp { + +std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::first ( const regexp::UnboundedRegExp < > & re ) { + return re.getRegExp ( ).getStructure ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFirst::Unbounded > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::Unbounded::visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp; + + for ( auto const & element : node.getElements ( ) ) { + tmp = element->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFirst::Unbounded > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + } + + return ret; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::Unbounded::visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp; + + for ( auto const & element : node.getElements ( ) ) { + tmp = element->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFirst::Unbounded > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * element ) ) // If regexp of this subtree can match epsilon, then we need to add next subtree + break; + } + + return ret; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::Unbounded::visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ) { + return node.getElement ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFirst::Unbounded > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::Unbounded::visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > { node }; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::Unbounded::visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFirst::Unbounded::visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovFirst.h b/alib2algo/src/regexp/glushkov/GlushkovFirst.h new file mode 100644 index 0000000000000000000000000000000000000000..80f699088d9b58f20f00995147b3689225031d49 --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovFirst.h @@ -0,0 +1,44 @@ +/* + * GlushkovFirst.h + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef GLUSHKOV_FIRST_H_ +#define GLUSHKOV_FIRST_H_ + +#include <set> + +#include <regexp/unbounded/UnboundedRegExp.h> +#include <regexp/RegExpFeatures.h> + +namespace regexp { + +/** + * RegExp tree traversal utils for Glushkov algorithm. + * + * Thanks to http://www.sciencedirect.com/science/article/pii/S030439759700296X for better follow() solution. + */ +class GlushkovFirst { +public: + /** + * @param re RegExp to probe + * @return all RegExpSymbols whichcan start the word. + */ + static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExp < > & re ); + + class Unbounded { + public: + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node ); + }; +}; + +} /* namespace regexp */ + +#endif /* GLUSHKOV_FIRST_H_ */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovFollow.cpp b/alib2algo/src/regexp/glushkov/GlushkovFollow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a97e1513c5802f148352c4950d6ada74b05c6a4 --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovFollow.cpp @@ -0,0 +1,91 @@ +/* + * GlushkovFollow.cpp + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#include "GlushkovFollow.h" +#include <regexp/unbounded/UnboundedRegExpAlternation.h> +#include <regexp/unbounded/UnboundedRegExpConcatenation.h> +#include <regexp/unbounded/UnboundedRegExpElement.h> +#include <regexp/unbounded/UnboundedRegExpEmpty.h> +#include <regexp/unbounded/UnboundedRegExpEpsilon.h> +#include <regexp/unbounded/UnboundedRegExpIteration.h> +#include <regexp/unbounded/UnboundedRegExpSymbol.h> + +#include "GlushkovFirst.h" +#include "GlushkovLast.h" +#include "GlushkovPos.h" + +#include "../properties/RegExpEpsilon.h" + +#include <iterator> + +namespace regexp { + +std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::follow ( const regexp::UnboundedRegExp < > & re, const UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { + return re.getRegExp ( ).getStructure ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFollow::Unbounded > ( symbol ); +} + +// ---------------------------------------------------------------------------- + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::Unbounded::visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { + for ( auto const & element : node.getElements ( ) ) + if ( element->accept < bool, GlushkovPos::Unbounded > ( symbolptr ) ) + return element->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFollow::Unbounded > ( symbolptr ); + + throw exception::CommonException ( "GlushkovFollow::Unbounded::visit(Alt)" ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::Unbounded::visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp, lastSet; + + for ( auto e = node.getElements ( ).begin ( ); e != node.getElements ( ).end ( ); e++ ) { + if ( ! ( * e )->accept < bool, GlushkovPos::Unbounded > ( symbolptr ) ) + continue; + + tmp = ( * e )->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFollow::Unbounded > ( symbolptr ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + lastSet = ( * e )->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovLast::Unbounded > ( ); + + if ( lastSet.find ( symbolptr ) != lastSet.end ( ) ) + for ( auto f = next ( e ); f != node.getElements ( ).end ( ); f++ ) { + tmp = ( * f )->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFirst::Unbounded > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * * f ) ) + break; + } + + } + + return ret; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::Unbounded::visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret = node.getElement ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFollow::Unbounded > ( symbolptr ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > lastSet = node.getElement ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovLast::Unbounded > ( ); + + if ( lastSet.find ( symbolptr ) != lastSet.end ( ) ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > firstSet = node.getElement ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovFirst::Unbounded > ( ); + ret.insert ( firstSet.begin ( ), firstSet.end ( ) ); + } + + return ret; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::Unbounded::visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::Unbounded::visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovFollow::Unbounded::visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovFollow.h b/alib2algo/src/regexp/glushkov/GlushkovFollow.h new file mode 100644 index 0000000000000000000000000000000000000000..547e6b081c403a5bc51e5764701e824c9c3801e1 --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovFollow.h @@ -0,0 +1,45 @@ +/* + * GlushkovFollow.h + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef GLUSHKOV_FOLLOW_H_ +#define GLUSHKOV_FOLLOW_H_ + +#include <set> + +#include <regexp/unbounded/UnboundedRegExp.h> +#include <regexp/RegExpFeatures.h> + +namespace regexp { + +/** + * RegExp tree traversal utils for Glushkov algorithm. + * + * Thanks to http://www.sciencedirect.com/science/article/pii/S030439759700296X for better follow() solution. + */ +class GlushkovFollow { +public: + /** + * @param re RegExp to probe + * @param symbol GlushkovSymbol for which we need the follow() + * @return all symbols that can follow specific symbol in word + */ + static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExp < > & re, const UnboundedRegExpSymbol < alphabet::Symbol > & symbol ); + + class Unbounded { + public: + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); + }; +}; + +} /* namespace regexp */ + +#endif /* GLUSHKOV_FOLLOW_H_ */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovIndexate.cpp b/alib2algo/src/regexp/glushkov/GlushkovIndexate.cpp index 2b2242bc2172a6055ba51c8e2c1a0c4fcfcf5500..9ee7de078c3acef3c17dfc162be97b2c5f687629 100644 --- a/alib2algo/src/regexp/glushkov/GlushkovIndexate.cpp +++ b/alib2algo/src/regexp/glushkov/GlushkovIndexate.cpp @@ -15,14 +15,18 @@ #include <regexp/unbounded/UnboundedRegExpIteration.h> #include <regexp/unbounded/UnboundedRegExpSymbol.h> -#include "../properties/RegExpEpsilon.h" #include <alphabet/SymbolPairSymbol.h> -#include <exception/CommonException.h> -#include <iterator> - namespace regexp { +alphabet::Symbol GlushkovIndexate::getSymbolFromGlushkovPair ( const alphabet::Symbol & symbol ) { + const alphabet::SymbolPairSymbol & symbolPair = ( const alphabet::SymbolPairSymbol & ) symbol.getData ( ); + + return symbolPair.getData ( ).first; +} + +// ----------------------------------------------------------------------------- + UnboundedRegExp < > GlushkovIndexate::index ( const regexp::UnboundedRegExp < > & re ) { int i = 1; @@ -63,4 +67,4 @@ std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > Glushkov return std::rvalue_ref < UnboundedRegExpElement < alphabet::Symbol > > ( new UnboundedRegExpEmpty < alphabet::Symbol > ( ) ); } -} /* namespace conversions */ +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovIndexate.h b/alib2algo/src/regexp/glushkov/GlushkovIndexate.h index 10240ace4125b8c655d137c9a21d78076197f830..8baed009cd99e660136e5ec95d6fb6c5a75dbb0d 100644 --- a/alib2algo/src/regexp/glushkov/GlushkovIndexate.h +++ b/alib2algo/src/regexp/glushkov/GlushkovIndexate.h @@ -8,10 +8,6 @@ #ifndef GLUSHKOV_INDEXATE_H_ #define GLUSHKOV_INDEXATE_H_ -#include <algorithm> -#include <list> -#include <set> - #include <regexp/unbounded/UnboundedRegExp.h> #include <regexp/RegExpFeatures.h> @@ -23,13 +19,14 @@ namespace regexp { */ class GlushkovIndexate { public: + static alphabet::Symbol getSymbolFromGlushkovPair ( const alphabet::Symbol & symbol ); + /** * @param re RegExp to index * @return UnboundedRegExp with indexed elements */ static regexp::UnboundedRegExp < > index ( const regexp::UnboundedRegExp < > & re ); -private: class Unbounded { public: static std::rvalue_ref < regexp::UnboundedRegExpElement < alphabet::Symbol > > visit(const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & alternation, int & i); @@ -41,6 +38,6 @@ private: }; }; -} /* namespace conversions */ +} /* namespace regexp */ #endif /* GLUSHKOV_INDEXATE_H_ */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovLast.cpp b/alib2algo/src/regexp/glushkov/GlushkovLast.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e8e52bbf0b381de9e129c37ff795f2b8020b9ac7 --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovLast.cpp @@ -0,0 +1,66 @@ +/* + * GlushkovLast::Unbounded.cpp + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#include "GlushkovLast.h" +#include <regexp/unbounded/UnboundedRegExpAlternation.h> +#include <regexp/unbounded/UnboundedRegExpConcatenation.h> +#include <regexp/unbounded/UnboundedRegExpElement.h> +#include <regexp/unbounded/UnboundedRegExpEmpty.h> +#include <regexp/unbounded/UnboundedRegExpEpsilon.h> +#include <regexp/unbounded/UnboundedRegExpIteration.h> +#include <regexp/unbounded/UnboundedRegExpSymbol.h> + +#include "../properties/RegExpEpsilon.h" + +namespace regexp { + +std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::last ( const regexp::UnboundedRegExp < > & re ) { + return re.getRegExp ( ).getStructure ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovLast::Unbounded > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::Unbounded::visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret; + + for ( const auto & element : node.getElements ( ) ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > tmp = element->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovLast::Unbounded > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + } + + return ret; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::Unbounded::visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret; + + for ( const auto & element : std::make_reverse ( node.getElements ( ) ) ) { + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > tmp = element->accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovLast::Unbounded > ( ); + ret.insert ( tmp.begin ( ), tmp.end ( ) ); + + if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * element ) ) + break; + } + + return ret; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::Unbounded::visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ) { + return node.getElement ( ).accept < std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > >, GlushkovLast::Unbounded > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::Unbounded::visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > { node }; +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::Unbounded::visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovLast::Unbounded::visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */ ) { + return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); +} + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovLast.h b/alib2algo/src/regexp/glushkov/GlushkovLast.h new file mode 100644 index 0000000000000000000000000000000000000000..acb9c651c77a717693e8191d8e601e7ff5cec373 --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovLast.h @@ -0,0 +1,44 @@ +/* + * GlushkovLast.h + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef GLUSHKOV_LAST_H_ +#define GLUSHKOV_LAST_H_ + +#include <set> + +#include <regexp/unbounded/UnboundedRegExp.h> +#include <regexp/RegExpFeatures.h> + +namespace regexp { + +/** + * RegExp tree traversal utils for Glushkov algorithm. + * + * Thanks to http://www.sciencedirect.com/science/article/pii/S030439759700296X for better follow() solution. + */ +class GlushkovLast { +public: + /** + * @param re RegExp to probe + * @return all RegExpSymbols that can terminate the word. + */ + static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExp < > & re ); + + class Unbounded { + public: + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node ); + static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node ); + }; +}; + +} /* namespace regexp */ + +#endif /* GLUSHKOV_LAST_H_ */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovPos.cpp b/alib2algo/src/regexp/glushkov/GlushkovPos.cpp new file mode 100644 index 0000000000000000000000000000000000000000..682b312d4c06c425f9b6e35dfd6b45cf33aa7c21 --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovPos.cpp @@ -0,0 +1,55 @@ +/* + * GlushkovTraversal.cpp + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#include "GlushkovPos.h" +#include <regexp/unbounded/UnboundedRegExpAlternation.h> +#include <regexp/unbounded/UnboundedRegExpConcatenation.h> +#include <regexp/unbounded/UnboundedRegExpElement.h> +#include <regexp/unbounded/UnboundedRegExpEmpty.h> +#include <regexp/unbounded/UnboundedRegExpEpsilon.h> +#include <regexp/unbounded/UnboundedRegExpIteration.h> +#include <regexp/unbounded/UnboundedRegExpSymbol.h> + +namespace regexp { + +bool GlushkovPos::pos ( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const regexp::UnboundedRegExp < > & node ) { + return node.getRegExp ( ).getStructure ( ).accept < bool, GlushkovPos::Unbounded > ( symbol ); +} + +bool GlushkovPos::Unbounded::visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { + for ( const auto & element : node.getElements ( ) ) + if ( element->accept < bool, GlushkovPos::Unbounded > ( symbol ) ) + return true; + + return false; +} + +bool GlushkovPos::Unbounded::visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { + for ( const auto & element : node.getElements ( ) ) + if ( element->accept < bool, GlushkovPos::Unbounded > ( symbol ) ) + return true; + + return false; +} + +bool GlushkovPos::Unbounded::visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { + return node.getElement ( ).accept < bool, GlushkovPos::Unbounded > ( symbol ); +} + +bool GlushkovPos::Unbounded::visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { + return symbol == node; +} + +bool GlushkovPos::Unbounded::visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbol */ ) { + return false; +} + +bool GlushkovPos::Unbounded::visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbol */ ) { + return false; +} + +} /* namespace regexp */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovPos.h b/alib2algo/src/regexp/glushkov/GlushkovPos.h new file mode 100644 index 0000000000000000000000000000000000000000..cffeafcbb04d1598491c8a0f8673297ad0816f3d --- /dev/null +++ b/alib2algo/src/regexp/glushkov/GlushkovPos.h @@ -0,0 +1,41 @@ +/* + * GlushkovPos.h + * + * Created on: 13. 3. 2014 + * Author: Tomas Pecka + */ + +#ifndef GLUSHKOV_POS_H_ +#define GLUSHKOV_POS_H_ + +#include <regexp/unbounded/UnboundedRegExp.h> +#include <regexp/RegExpFeatures.h> + +namespace regexp { + +/** + * RegExp tree traversal utils for Glushkov algorithm. + * + * Thanks to http://www.sciencedirect.com/science/article/pii/S030439759700296X for better follow() solution. + */ +class GlushkovPos { +public: + /** + * @return bool true if symbol is in this regexp + */ + static bool pos ( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const regexp::UnboundedRegExp < > & node ); + + class Unbounded { + public: + static bool visit ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); + static bool visit ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); + static bool visit ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); + static bool visit ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); + static bool visit ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); + static bool visit ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); + }; +}; + +} /* namespace regexp */ + +#endif /* GLUSHKOV_POS_H_ */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp b/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp deleted file mode 100644 index f2326ae106e83fd84807796e2dba82ddc620e0f2..0000000000000000000000000000000000000000 --- a/alib2algo/src/regexp/glushkov/GlushkovTraversal.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * GlushkovTraversal.cpp - * - * Created on: 13. 3. 2014 - * Author: Tomas Pecka - */ - -#include "GlushkovTraversal.h" - -#include "../properties/RegExpEpsilon.h" -#include <alphabet/SymbolPairSymbol.h> - -#include <exception/CommonException.h> -#include <iterator> - -namespace regexp { - -alphabet::Symbol GlushkovTraversal::getSymbolFromGlushkovPair ( const alphabet::Symbol & symbol ) { - const alphabet::SymbolPairSymbol & symbolPair = ( const alphabet::SymbolPairSymbol & ) symbol.getData ( ); - - return symbolPair.getData ( ).first; -} - -// ----------------------------------------------------------------------------- - -bool GlushkovTraversal::pos ( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const regexp::UnboundedRegExp < > & node ) { - return pos ( node.getRegExp ( ).getStructure ( ), symbol ); -} - -std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExp < > & re ) { - return first ( re.getRegExp ( ).getStructure ( ) ); -} - -std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExp < > & re ) { - return last ( re.getRegExp ( ).getStructure ( ) ); -} - -std::set < UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExp < > & re, const UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { - return follow ( re.getRegExp ( ).getStructure ( ), symbol ); -} - -// ----------------------------------------------------------------------------- - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node ) { - const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node ); - - if ( alternation ) - return first ( * alternation ); - else if ( concatenation ) - return first ( * concatenation ); - else if ( iteration ) - return first ( * iteration ); - else if ( eps ) - return first ( * eps ); - else if ( empty ) - return first ( * empty ); - else if ( symbol ) - return first ( * symbol ); - - throw exception::CommonException ( "GlushkovTraversal::first - invalid RegExpElement node" ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp; - - for ( auto const & element : node.getElements ( ) ) { - tmp = first ( * element ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - } - - return ret; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp; - - for ( auto const & element : node.getElements ( ) ) { - tmp = first ( * element ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * element ) ) // If regexp of this subtree can match epsilon, then we need to add next subtree - break; - } - - return ret; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ) { - return first ( node.getElement ( ) ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > { node }; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::first ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -// ---------------------------------------------------------------------------- - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node ) { - const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node ); - - if ( symbol ) - return last ( * symbol ); - else if ( alternation ) - return last ( * alternation ); - else if ( concatenation ) - return last ( * concatenation ); - else if ( iteration ) - return last ( * iteration ); - else if ( eps ) - return last ( * eps ); - else if ( empty ) - return last ( * empty ); - - throw exception::CommonException ( "GlushkovTraversal::last - invalid RegExpElement node" ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret; - - for ( const auto & element : node.getElements ( ) ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > tmp = last ( * element ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - } - - return ret; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret; - - for ( const auto & element : std::make_reverse ( node.getElements ( ) ) ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > tmp = last ( * element ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * element ) ) - break; - } - - return ret; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ) { - return last ( node.getElement ( ) ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > { node }; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::last ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -// ---------------------------------------------------------------------------- - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { - const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node ); - - if ( alternation ) - return follow ( * alternation, symbolptr ); - - else if ( concatenation ) - return follow ( * concatenation, symbolptr ); - - else if ( iteration ) - return follow ( * iteration, symbolptr ); - - else if ( symbol ) - return follow ( * symbol, symbolptr ); - - else if ( empty ) - return follow ( * empty, symbolptr ); - - else if ( eps ) - return follow ( * eps, symbolptr ); - - throw exception::CommonException ( "GlushkovTraversal::follow() - unknown RegExpElement node" ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { - for ( auto const & element : node.getElements ( ) ) - if ( pos ( * element, symbolptr ) ) - return follow ( * element, symbolptr ); - - throw exception::CommonException ( "GlushkovTraversal::follow(Alt)" ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret, tmp, lastSet; - - for ( auto e = node.getElements ( ).begin ( ); e != node.getElements ( ).end ( ); e++ ) { - if ( !pos ( * * e, symbolptr ) ) - continue; - - tmp = follow ( * * e, symbolptr ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - lastSet = last ( * * e ); - - if ( lastSet.find ( symbolptr ) != lastSet.end ( ) ) - for ( auto f = next ( e ); f != node.getElements ( ).end ( ); f++ ) { - tmp = first ( * * f ); - ret.insert ( tmp.begin ( ), tmp.end ( ) ); - - if ( !regexp::properties::RegExpEpsilon::languageContainsEpsilon ( * * f ) ) - break; - } - - } - - return ret; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ret = follow ( node.getElement ( ), symbolptr ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > lastSet = last ( node.getElement ( ) ); - - if ( lastSet.find ( symbolptr ) != lastSet.end ( ) ) { - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > firstSet = first ( node.getElement ( ) ); - ret.insert ( firstSet.begin ( ), firstSet.end ( ) ); - } - - return ret; -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > GlushkovTraversal::follow ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbolptr */ ) { - return std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > ( ); -} - -// ---------------------------------------------------------------------------- - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbolptr ) { - const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * alternation = dynamic_cast < const regexp::UnboundedRegExpAlternation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * concatenation = dynamic_cast < const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpIteration < alphabet::Symbol > * iteration = dynamic_cast < const regexp::UnboundedRegExpIteration < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * symbol = dynamic_cast < const regexp::UnboundedRegExpSymbol < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * empty = dynamic_cast < const regexp::UnboundedRegExpEmpty < alphabet::Symbol > * > ( & node ); - const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * eps = dynamic_cast < const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > * > ( & node ); - - if ( alternation ) - return pos ( * alternation, symbolptr ); - - else if ( concatenation ) - return pos ( * concatenation, symbolptr ); - - else if ( iteration ) - return pos ( * iteration, symbolptr ); - - else if ( symbol ) - return pos ( * symbol, symbolptr ); - - else if ( empty ) - return pos ( * empty, symbolptr ); - - else if ( eps ) - return pos ( * eps, symbolptr ); - - throw exception::CommonException ( "GlushkovTraversal::pos() - unknown RegExpElement node" ); -} - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { - for ( const auto & element : node.getElements ( ) ) - if ( pos ( * element, symbol ) ) - return true; - - return false; -} - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { - for ( const auto & element : node.getElements ( ) ) - if ( pos ( * element, symbol ) ) - return true; - - return false; -} - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { - return pos ( node.getElement ( ), symbol ); -} - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbol ) { - return symbol == node; -} - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbol */ ) { - return false; -} - -bool GlushkovTraversal::pos ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & /* node */, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & /* symbol */ ) { - return false; -} - -} /* namespace conversions */ diff --git a/alib2algo/src/regexp/glushkov/GlushkovTraversal.h b/alib2algo/src/regexp/glushkov/GlushkovTraversal.h deleted file mode 100644 index fac2d1004d81bff79a4e25c72680e08002ea6501..0000000000000000000000000000000000000000 --- a/alib2algo/src/regexp/glushkov/GlushkovTraversal.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * GlushkovTraversal.h - * - * Created on: 13. 3. 2014 - * Author: Tomas Pecka - */ - -#ifndef GLUSHKOVTRAVERSAL_H_ -#define GLUSHKOVTRAVERSAL_H_ - -#include <algorithm> -#include <list> -#include <set> - -#include <regexp/unbounded/UnboundedRegExp.h> -#include <regexp/unbounded/UnboundedRegExpAlternation.h> -#include <regexp/unbounded/UnboundedRegExpConcatenation.h> -#include <regexp/unbounded/UnboundedRegExpElement.h> -#include <regexp/unbounded/UnboundedRegExpEmpty.h> -#include <regexp/unbounded/UnboundedRegExpEpsilon.h> -#include <regexp/unbounded/UnboundedRegExpIteration.h> -#include <regexp/unbounded/UnboundedRegExpSymbol.h> - -namespace regexp { - -/** - * RegExp tree traversal utils for Glushkov algorithm. - * - * Thanks to http://www.sciencedirect.com/science/article/pii/S030439759700296X for better follow() solution. - */ -class GlushkovTraversal { -public: - static alphabet::Symbol getSymbolFromGlushkovPair ( const alphabet::Symbol & symbol ); - - /** - * @param re RegExp to probe - * @return all RegExpSymbols whichcan start the word. - */ - static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExp < > & re ); - - /** - * @param re RegExp to probe - * @return all RegExpSymbols that can terminate the word. - */ - static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExp < > & re ); - - /** - * @param re RegExp to probe - * @param symbol GlushkovSymbol for which we need the follow() - * @return all symbols that can follow specific symbol in word - */ - static std::set < UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExp < > & re, const UnboundedRegExpSymbol < alphabet::Symbol > & symbol ); - -private: - /** - * @return bool true if symbol pointer is in this subtree - */ - static bool pos ( const UnboundedRegExpSymbol < alphabet::Symbol > & symbol, const regexp::UnboundedRegExp < > & node ); - - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node ); - - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node ); - - static bool pos ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - static bool pos ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - static bool pos ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - static bool pos ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - static bool pos ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - static bool pos ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - static bool pos ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbSearch ); - - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpElement < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpAlternation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpConcatenation < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpIteration < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpEmpty < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); - static std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow ( const regexp::UnboundedRegExpEpsilon < alphabet::Symbol > & node, const regexp::UnboundedRegExpSymbol < alphabet::Symbol > & symbFollow ); -}; - -} /* namespace conversions */ - -#endif /* GLUSHKOVTRAVERSAL_H_ */ diff --git a/alib2algo/test-src/regexp/RegExpTest.cpp b/alib2algo/test-src/regexp/RegExpTest.cpp index 318e5aa4dcbf0adf0263e074008b619937ff3dfb..202114da9a0bf40a53d7980cc6c6160441c606b2 100644 --- a/alib2algo/test-src/regexp/RegExpTest.cpp +++ b/alib2algo/test-src/regexp/RegExpTest.cpp @@ -8,8 +8,10 @@ #include "regexp/unbounded/UnboundedRegExp.h" #include <regexp/RegExp.h> -#include "regexp/glushkov/GlushkovTraversal.h" +#include "regexp/glushkov/GlushkovFollow.h" #include "regexp/glushkov/GlushkovIndexate.h" +#include "regexp/glushkov/GlushkovFirst.h" +#include "regexp/glushkov/GlushkovLast.h" #include <factory/StringDataFactory.hpp> @@ -31,7 +33,7 @@ void RegExpTest::testFirst ( ) { regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) ); regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovIndexate::index ( regexp ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovFirst::first ( indexedRegExp ); CPPUNIT_ASSERT ( first.size ( ) == 0 ); } @@ -40,7 +42,7 @@ void RegExpTest::testFirst ( ) { regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) ); regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovIndexate::index ( regexp ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovTraversal::first ( indexedRegExp ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > first = regexp::GlushkovFirst::first ( indexedRegExp ); CPPUNIT_ASSERT ( first.size ( ) == 1 ); } @@ -52,7 +54,7 @@ void RegExpTest::testLast ( ) { regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) ); regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovIndexate::index ( regexp ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovLast::last ( indexedRegExp ); CPPUNIT_ASSERT ( last.size ( ) == 2 ); } @@ -61,7 +63,7 @@ void RegExpTest::testLast ( ) { regexp::UnboundedRegExp < > regexp ( static_cast < const regexp::UnboundedRegExp < > & > ( alib::StringDataFactory::fromString < regexp::RegExp > ( input ).getData ( ) ) ); regexp::UnboundedRegExp < > indexedRegExp = regexp::GlushkovIndexate::index ( regexp ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovTraversal::last ( indexedRegExp ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > last = regexp::GlushkovLast::last ( indexedRegExp ); std::cout << last << std::endl; CPPUNIT_ASSERT ( last.size ( ) == 1 ); @@ -76,17 +78,17 @@ void RegExpTest::testFollow ( ) { auto symbolsIter = indexedRegExp.getAlphabet ( ).begin ( ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow1 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow1 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow1.size ( ) == 1 ); symbolsIter++; - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow2 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow2 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow2.size ( ) == 1 ); symbolsIter++; - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow3 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow3 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow3.size ( ) == 0 ); } @@ -97,27 +99,27 @@ void RegExpTest::testFollow ( ) { auto symbolsIter = indexedRegExp.getAlphabet ( ).begin ( ); - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow1 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow1 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow1.size ( ) == 0 ); symbolsIter++; - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow2 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow2 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow2.size ( ) == 4 ); symbolsIter++; - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow3 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow3 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow3.size ( ) == 3 ); symbolsIter++; - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow4 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow4 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow4.size ( ) == 3 ); symbolsIter++; - std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow5 = regexp::GlushkovTraversal::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); + std::set < regexp::UnboundedRegExpSymbol < alphabet::Symbol > > follow5 = regexp::GlushkovFollow::follow ( indexedRegExp, regexp::UnboundedRegExpSymbol < alphabet::Symbol > ( * symbolsIter ) ); CPPUNIT_ASSERT ( follow5.size ( ) == 0 ); }