diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp index b458ad7842459dba96b0960e7d865ef083cf9e24..6d56b8ed25947d738ef9a467a69a5484d9778713 100644 --- a/aconversions2/src/ConversionHandler.cpp +++ b/aconversions2/src/ConversionHandler.cpp @@ -213,8 +213,7 @@ void ConversionHandler::convertREtoFSM( void ) } case GLUSHKOV_NFA: default: { - conversions::re2fa::GlushkovNFA conv; - alib::DataFactory::toStdout(conv.convert(regexp)); + alib::DataFactory::toStdout(conversions::re2fa::GlushkovNFA::convert(regexp)); break; } } diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp b/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp index ad614b9a75cb07dfc7fd57db87f1901140c45f9d..471db6e083a777db341ea28cfd7e77cc7e450f02 100644 --- a/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp +++ b/alib2algo/src/conversions/re2fa/GlushkovNFA.cpp @@ -6,12 +6,17 @@ */ #include "GlushkovNFA.h" + #include "label/Label.h" #include "label/StringLabel.h" #include "label/CharacterLabel.h" #include "label/IntegerLabel.h" #include "label/LabelPairLabel.h" +#include "../../regexp/GlushkovTraversal.h" +#include "../../regexp/GlushkovPair.h" +#include "../../regexp/GlushkovSymbol.h" + #include "../../regexp/RegExpEpsilon.h" namespace conversions{ @@ -19,79 +24,87 @@ namespace conversions{ namespace re2fa { automaton::NFA GlushkovNFA::convert(const regexp::RegExp& regexp) { - automaton::NFA out; - regexp.getData().Accept((void*) &out, *this); - return out; -} -void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) { - automaton::NFA& out = *(automaton::NFA*) userData; - out = this->convert(regexp); -} - -void GlushkovNFA::Visit(void* userData, const regexp::UnboundedRegExp& regexp) { - automaton::NFA& out = *(automaton::NFA*) userData; - out = this->convert(regexp); + automaton::NFA* out = nullptr; + regexp.getData().Accept((void*) &out, GlushkovNFA::GLUSHKOV_NFA); + automaton::NFA res = std::move(*out); + delete out; + return res; } -automaton::NFA GlushkovNFA::convert( const regexp::UnboundedRegExp & re ) { +automaton::NFA GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) +{ automaton::NFA automaton; // step 1 - for( auto const& symbol : re.getAlphabet( ) ) + for( auto const& symbol : regexp.getAlphabet( ) ) automaton.addInputSymbol( symbol ); // steps 2, 3, 4 - m_first = regexp::GlushkovTraversal::first( re ); - m_last = regexp::GlushkovTraversal::last( re ); - for( auto const& x : regexp::GlushkovTraversal::getSymbols( re ) ) - for( auto const& f : regexp::GlushkovTraversal::follow( re, x ) ) { - m_pairs.insert( regexp::GlushkovPair( x, f ) ); - //std::cout << x.getSymbolPtr() << "|" << x.getSymbol() << "|" << x.getId() << " + "; - //std::cout << f.getSymbolPtr() << "|" << f.getSymbol() << "|" << f.getId() << std::endl; + std::set<regexp::GlushkovPair> pairs; + const std::set<regexp::GlushkovSymbol> first = regexp::GlushkovTraversal::first(regexp); + const std::set<regexp::GlushkovSymbol> last = regexp::GlushkovTraversal::last(regexp); + for( auto const& x : regexp::GlushkovTraversal::getSymbols( regexp ) ) + for( auto const& f : regexp::GlushkovTraversal::follow( regexp, x ) ) { + pairs.insert( regexp::GlushkovPair( x, f ) ); } // \e in q0 check is in step 7 // step 5 + std::map<regexp::GlushkovSymbol, automaton::State> stateMap; + automaton::State q0( label::Label( label::LabelPairLabel( std::make_pair( label::Label( label::CharacterLabel( 'q' ) ), label::Label( label::IntegerLabel ( 0 ) ) ) ) ) ); automaton.addState( q0 ); automaton.addInitialState( q0 ); - for( auto const& symbol : regexp::GlushkovTraversal::getSymbols( re ) ) { + for( auto const& symbol : regexp::GlushkovTraversal::getSymbols( regexp ) ) { automaton::State q( label::Label( label::LabelPairLabel( std::make_pair( label::Label( label::StringLabel( symbol.getInputSymbol( ) ) ), label::Label( label::IntegerLabel ( symbol.getId( ) ) ) ) ) ) ); - m_stateMap.insert( std::make_pair( symbol, q ) ); + stateMap.insert( std::make_pair( symbol, q ) ); automaton.addState( q ); } // step 6 - for( auto const& symbol : m_first ) { - const automaton::State & q = m_stateMap.find( symbol )->second; + for( auto const& symbol : first ) { + const automaton::State & q = stateMap.find( symbol )->second; automaton.addTransition( q0, symbol.getInputSymbol( ), q ); } - for( auto const& pair : m_pairs ) { - const automaton::State & p = m_stateMap.find( pair.getFirst( ) )->second; - const automaton::State & q = m_stateMap.find( pair.getSecond( ) )->second; + for( auto const& pair : pairs ) { + const automaton::State & p = stateMap.find( pair.getFirst( ) )->second; + const automaton::State & q = stateMap.find( pair.getSecond( ) )->second; automaton.addTransition( p, pair.getSecond( ).getInputSymbol( ), q ); } // step 7 - for( auto const& symbol : m_last ) { - const automaton::State & q = m_stateMap.find( symbol )->second; + for( auto const& symbol : last ) { + const automaton::State & q = stateMap.find( symbol )->second; automaton.addFinalState( q ); } - if(regexp::RegExpEpsilon::languageContainsEpsilon(re)) + if(regexp::RegExpEpsilon::languageContainsEpsilon(regexp)) automaton.addFinalState( q0 ); return automaton; } -automaton::NFA GlushkovNFA::convert( const regexp::FormalRegExp & re ) { - throw exception::AlibException("Unimplemented"); +void GlushkovNFA::Visit(void* userData, const regexp::FormalRegExp& regexp) const +{ + /* + automaton::NFA* & out = *((automaton::NFA**) userData); + out = new automaton::NFA(this->convert(regexp)); + */ + throw exception::AlibException("Glushkov: Converting FormalRegExp NYI"); // TODO +} + +void GlushkovNFA::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + automaton::NFA* & out = *((automaton::NFA**) userData); + out = new automaton::NFA(this->convert(regexp)); } +const GlushkovNFA GlushkovNFA::GLUSHKOV_NFA; + } /* namespace fa2re */ } /* namespace conversions */ diff --git a/alib2algo/src/conversions/re2fa/GlushkovNFA.h b/alib2algo/src/conversions/re2fa/GlushkovNFA.h index fa42209388e245a19ac2f8c2825b80c133d95cc5..1cb1c806b7aa9859135c1a9841ee8b22664fb6fe 100644 --- a/alib2algo/src/conversions/re2fa/GlushkovNFA.h +++ b/alib2algo/src/conversions/re2fa/GlushkovNFA.h @@ -10,18 +10,10 @@ #include <map> -#include <alphabet/Symbol.h> -#include <automaton/common/State.h> -#include <regexp/unbounded/UnboundedRegExp.h> -#include <regexp/unbounded/UnboundedRegExpElements.h> -#include <regexp/formal/FormalRegExp.h> -#include <regexp/formal/FormalRegExpElements.h> -#include <regexp/RegExp.h> - -#include "../../regexp/GlushkovTraversal.h" -#include "std/hexavigesimal.h" - #include <automaton/FSM/NFA.h> +#include <regexp/RegExp.h> +#include <regexp/formal/FormalRegExp.h> +#include <regexp/unbounded/UnboundedRegExp.h> namespace conversions { @@ -31,28 +23,24 @@ namespace re2fa { * Converts regular expression to finite automaton using Glushkov's NFA construction algorithm. * Source: Melichar 2.107 */ -class GlushkovNFA : public regexp::VisitableRegExpBase::visitor_type { +class GlushkovNFA : public regexp::VisitableRegExpBase::const_visitor_type +{ public: /** * Performs conversion. * @param re Original regular expression. - * @return FSM equivalent to original regular expression. - * + * @return NFA equivalent to original regular expression. */ - automaton::NFA convert( const regexp::UnboundedRegExp & re ); - automaton::NFA convert( const regexp::FormalRegExp & re ); + static automaton::NFA convert(const regexp::RegExp& re); - automaton::NFA convert( const regexp::RegExp & re ); + static automaton::NFA convert(const regexp::UnboundedRegExp& re); + static automaton::NFA convert(const regexp::FormalRegExp& re); private: - std::map<regexp::GlushkovSymbol, automaton::State> m_stateMap; - std::set<regexp::GlushkovSymbol> m_first; - std::set<regexp::GlushkovSymbol> m_last; - std::set<regexp::GlushkovPair> m_pairs; - - void Visit(void* , const regexp::FormalRegExp& regexp); - void Visit(void* , const regexp::UnboundedRegExp& regexp); + void Visit(void*, const regexp::FormalRegExp& regexp) const; + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + static const GlushkovNFA GLUSHKOV_NFA; }; } /* namespace re2fa */ diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp b/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp index c8dad374dd5dcbf78b6438a384e7fce5deffe3f2..7206e72e153c0882fa23f8093f6c88eb2ae4b3d9 100644 --- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp +++ b/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.cpp @@ -56,6 +56,7 @@ grammar::RightRG GlushkovNFA::convert(const regexp::UnboundedRegExp& regexp) // step 5 std::map<regexp::GlushkovSymbol, alphabet::Symbol> symbolMap; + for(const auto& symbol : regexp::GlushkovTraversal::getSymbols(regexp)) { alphabet::Symbol nt(alphabet::LabeledSymbol(label::Label(label::LabelPairLabel(std::make_pair(label::Label(label::StringLabel(symbol.getInputSymbol())), label::Label(label::IntegerLabel(symbol.getId()))))))); diff --git a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h b/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h index 9d75324ebdcb930dbea7f4c66ef7591f66d486b0..32de94e8b020907573114155fb9c1c8b33bea075 100644 --- a/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h +++ b/alib2algo/src/conversions/re2rg/re2rrg/GlushkovNFA.h @@ -30,6 +30,7 @@ class GlushkovNFA : public regexp::VisitableRegExpBase::const_visitor_type public: /** * Performs conversion. + * @param regexp original regular expression * @return right regular grammar equivalent to source regexp. */ static grammar::Grammar convert(const regexp::RegExp& regexp);