From df42965d9cc5da5b8a34a6ce8565f628da4a4a2d Mon Sep 17 00:00:00 2001 From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz> Date: Tue, 25 Oct 2016 16:05:38 +0200 Subject: [PATCH] adapt regexps to new visitor technique --- .../regexp/convert/ToAutomatonThompson.cpp | 235 +++++++----------- .../src/regexp/convert/ToAutomatonThompson.h | 36 ++- .../src/regexp/properties/RegExpEmpty.cpp | 100 +++----- alib2algo/src/regexp/properties/RegExpEmpty.h | 38 ++- .../src/regexp/properties/RegExpEpsilon.cpp | 108 +++----- .../src/regexp/properties/RegExpEpsilon.h | 39 +-- .../src/regexp/transform/RegExpDerivation.cpp | 124 ++++----- .../src/regexp/transform/RegExpDerivation.h | 38 ++- .../src/regexp/transform/RegExpIntegral.cpp | 107 +++----- .../src/regexp/transform/RegExpIntegral.h | 38 ++- .../src/regexp/common/RegExpToXMLComposer.cpp | 69 ++--- .../src/regexp/common/RegExpToXMLComposer.h | 38 ++- .../regexp/formal/FormalRegExpAlternation.h | 4 +- .../regexp/formal/FormalRegExpConcatenation.h | 4 +- .../src/regexp/formal/FormalRegExpElement.h | 52 +++- .../src/regexp/formal/FormalRegExpEmpty.h | 4 +- .../src/regexp/formal/FormalRegExpEpsilon.h | 4 +- .../src/regexp/formal/FormalRegExpIteration.h | 4 +- .../regexp/formal/FormalRegExpStructure.cpp | 2 +- .../src/regexp/formal/FormalRegExpSymbol.h | 4 +- .../unbounded/UnboundedRegExpAlternation.h | 4 +- .../unbounded/UnboundedRegExpConcatenation.h | 4 +- .../regexp/unbounded/UnboundedRegExpElement.h | 52 +++- .../regexp/unbounded/UnboundedRegExpEmpty.h | 4 +- .../regexp/unbounded/UnboundedRegExpEpsilon.h | 4 +- .../unbounded/UnboundedRegExpIteration.h | 4 +- .../unbounded/UnboundedRegExpStructure.cpp | 2 +- .../regexp/unbounded/UnboundedRegExpSymbol.h | 4 +- .../src/regexp/RegExpToStringComposer.cpp | 70 ++---- alib2str/src/regexp/RegExpToStringComposer.h | 36 +-- 30 files changed, 508 insertions(+), 724 deletions(-) diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp index 150947b19d..d2af830fab 100644 --- a/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp +++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.cpp @@ -19,15 +19,17 @@ automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::RegExp& reg automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::FormalRegExp & regexp) { //FIXME use actual algorithms that implement product alternation and iteration of re over automata and remove terrible TERRIBLE hack with dummy initial state - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> out(automaton::EpsilonNFA < >(label::labelFrom(0)), 1, nullptr, nullptr); + int nextState = 1; + const label::Label * headArg = nullptr; + const label::Label * tailArg = nullptr; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); + automaton::EpsilonNFA < > automaton ( label::labelFrom ( 0 ) ); automaton.setInputAlphabet(regexp.getAlphabet()); - regexp.getRegExp().getStructure().Accept((void*) &out, ToAutomatonThompson::Formal::FORMAL); + regexp.getRegExp().getStructure().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); - automaton.setInitialState(*std::get<2>(out)); - automaton.setFinalStates(std::set<label::Label>{*std::get<3>(out)}); + automaton.setInitialState ( * headArg ); + automaton.setFinalStates ( std::set < label::Label > { * tailArg } ); automaton.removeState(label::labelFrom(0)); @@ -38,15 +40,17 @@ auto ToAutomatonThompsonFormalRegExp = ToAutomatonThompson::RegistratorWrapper<a automaton::EpsilonNFA < > ToAutomatonThompson::convert(const regexp::UnboundedRegExp & regexp) { //FIXME use actual algorithms that implement product alternation and iteration of re over automata and remove terrible TERRIBLE hack with dummy initial state - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> out(automaton::EpsilonNFA < >(label::labelFrom(0)), 1, nullptr, nullptr); + int nextState = 1; + const label::Label * headArg = nullptr; + const label::Label * tailArg = nullptr; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); + automaton::EpsilonNFA < > automaton ( label::labelFrom ( 0 ) ); automaton.setInputAlphabet(regexp.getAlphabet()); - regexp.getRegExp().getStructure().Accept((void*) &out, ToAutomatonThompson::Unbounded::UNBOUNDED); + regexp.getRegExp().getStructure().accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); - automaton.setInitialState(*std::get<2>(out)); - automaton.setFinalStates(std::set<label::Label>{*std::get<3>(out)}); + automaton.setInitialState ( * headArg ); + automaton.setFinalStates ( std::set < label::Label > { * tailArg } ); automaton.removeState(label::labelFrom(0)); @@ -57,211 +61,164 @@ auto ToAutomatonThompsonUnboundedRegExp = ToAutomatonThompson::RegistratorWrappe // ---------------------------------------------------------------------------- -void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); - static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(userData, *this); - automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out)); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail); + alternation.getLeftElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail); - static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(userData, *this); - automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out)); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail); + alternation.getRightElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(userData, *this); - const label::Label* leftHead = std::get<2>(out); - const label::Label* leftTail = std::get<3>(out); +void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + concatenation.getLeftElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + const label::Label* leftHead = headArg; + const label::Label* leftTail = tailArg; - static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this); - automaton.addTransition(*leftTail, string::Epsilon < >::EPSILON, *std::get<2>(out)); + concatenation.getRightElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + automaton.addTransition(*leftTail, string::Epsilon < >::EPSILON, *headArg); - std::get<2>(out) = &(*automaton.getStates().find(*leftHead)); - // std::get<3>(out) = std::get<3>(out); + headArg = &(*automaton.getStates().find(*leftHead)); + // tailArg = tailArg; } -void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); - static_cast<const regexp::FormalRegExpElement&>(iteration.getElement()).Accept(userData, *this); - automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out)); + iteration.getElement().accept < void, ToAutomatonThompson::Formal, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg); automaton.addTransition(head, string::Epsilon < >::EPSILON, tail); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, *std::get<2>(out)); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, *headArg); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); automaton.addTransition(head, symbol.getSymbol(), tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEpsilon&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); automaton.addTransition(head, string::Epsilon < >::EPSILON, tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Formal::Visit(void* userData, const regexp::FormalRegExpEmpty&) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Formal::visit(const regexp::FormalRegExpEmpty&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -const ToAutomatonThompson::Formal ToAutomatonThompson::Formal::FORMAL; - // ---------------------------------------------------------------------------- -void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); - for(const auto& element : alternation.getElements()) - { - static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this); - automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out)); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail); + for(const auto& element : alternation.getElements()) { + element->accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail); } - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - +void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { std::vector<std::pair<const label::Label*, const label::Label*>> tails; - for(const auto& element : concatenation.getElements()) - { - static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(userData, *this); - tails.push_back(std::make_pair(std::get<2>(out), std::get<3>(out))); + for(const auto& element : concatenation.getElements()) { + element->accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + tails.push_back(std::make_pair(headArg, tailArg)); } for(size_t i = 1; i < tails.size(); i++) automaton.addTransition(*tails[i-1].second, string::Epsilon < >::EPSILON, *tails[i].first); - std::get<2>(out) = tails[0].first; - std::get<3>(out) = tails[tails.size()-1].second; + headArg = tails[0].first; + tailArg = tails[tails.size()-1].second; } -void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); - static_cast<const regexp::UnboundedRegExpElement&>(iteration.getElement()).Accept(userData, *this); - automaton.addTransition(head, string::Epsilon < >::EPSILON, *std::get<2>(out)); + iteration.getElement().accept < void, ToAutomatonThompson::Unbounded, automaton::EpsilonNFA < > &, int &, const label::Label * &, const label::Label * & >(automaton, nextState, headArg, tailArg); + automaton.addTransition(head, string::Epsilon < >::EPSILON, *headArg); automaton.addTransition(head, string::Epsilon < >::EPSILON, tail); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, tail); - automaton.addTransition(*std::get<3>(out), string::Epsilon < >::EPSILON, *std::get<2>(out)); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, tail); + automaton.addTransition(*tailArg, string::Epsilon < >::EPSILON, *headArg); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); automaton.addTransition(head, symbol.getSymbol(), tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); automaton.addTransition(head, string::Epsilon < >::EPSILON, tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -void ToAutomatonThompson::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const { - std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*> &out = *(std::tuple<automaton::EpsilonNFA < >, int, const label::Label*, const label::Label*>*) userData; - automaton::EpsilonNFA < >& automaton = std::get<0>(out); - - label::Label head = label::labelFrom(std::get<1>(out)++); - label::Label tail = label::labelFrom(std::get<1>(out)++); +void ToAutomatonThompson::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg) { + label::Label head = label::labelFrom(nextState++); + label::Label tail = label::labelFrom(nextState++); automaton.addState(head); automaton.addState(tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + headArg = &(*automaton.getStates().find(head)); + tailArg = &(*automaton.getStates().find(tail)); } -const ToAutomatonThompson::Unbounded ToAutomatonThompson::Unbounded::UNBOUNDED; - } /* namespace convert */ } /* namespace regexp */ diff --git a/alib2algo/src/regexp/convert/ToAutomatonThompson.h b/alib2algo/src/regexp/convert/ToAutomatonThompson.h index 22329a8269..c5797afa03 100644 --- a/alib2algo/src/regexp/convert/ToAutomatonThompson.h +++ b/alib2algo/src/regexp/convert/ToAutomatonThompson.h @@ -41,32 +41,24 @@ public: static automaton::EpsilonNFA < > convert(const regexp::FormalRegExp& regexp); static automaton::EpsilonNFA < > convert(const regexp::UnboundedRegExp& regexp); - class Unbounded : public regexp::UnboundedRegExpElement::Visitor { + class Unbounded { public: - Unbounded ( ) { } - - static const Unbounded UNBOUNDED; - private: - void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const; - void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const; - void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const; - void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const; - void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const; - void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const; + static void visit(const regexp::UnboundedRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::UnboundedRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::UnboundedRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::UnboundedRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::UnboundedRegExpEpsilon& epsilon, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::UnboundedRegExpEmpty& empty, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); }; - class Formal : public regexp::FormalRegExpElement::Visitor { + class Formal { public: - Formal ( ) { } - - static const Formal FORMAL; - private: - void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const; - void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const; - void Visit(void*, const regexp::FormalRegExpIteration& iteration) const; - void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const; - void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const; - void Visit(void*, const regexp::FormalRegExpEmpty& empty) const; + static void visit(const regexp::FormalRegExpAlternation& alternation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::FormalRegExpConcatenation& concatenation, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::FormalRegExpIteration& iteration, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::FormalRegExpSymbol& symbol, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::FormalRegExpEpsilon& epsilon, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); + static void visit(const regexp::FormalRegExpEmpty& empty, automaton::EpsilonNFA < > & automaton , int & nextState, const label::Label * & headArg, const label::Label * & tailArg); }; }; diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.cpp b/alib2algo/src/regexp/properties/RegExpEmpty.cpp index e1da9e26d5..ebd2075478 100644 --- a/alib2algo/src/regexp/properties/RegExpEmpty.cpp +++ b/alib2algo/src/regexp/properties/RegExpEmpty.cpp @@ -18,9 +18,7 @@ bool RegExpEmpty::languageIsEmpty(const regexp::RegExp& regexp) { } bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpElement& regexp) { - bool out; - regexp.Accept((void*) &out, RegExpEmpty::Formal::FORMAL); - return out; + return regexp.accept < bool, RegExpEmpty::Formal > ( ); } bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExpStructure& regexp) { @@ -34,9 +32,7 @@ bool RegExpEmpty::languageIsEmpty(const regexp::FormalRegExp& regexp) { auto RegExpEmptyFormalRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp::FormalRegExp>( RegExpEmpty::languageIsEmpty); bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpElement& regexp) { - bool out; - regexp.Accept((void*) &out, RegExpEmpty::Unbounded::UNBOUNDED); - return out; + return regexp.accept < bool, RegExpEmpty::Unbounded > ( ); } bool RegExpEmpty::languageIsEmpty(const regexp::UnboundedRegExpStructure& regexp) { @@ -51,102 +47,66 @@ auto RegExpEmptyUnboundedRegExp = RegExpEmpty::RegistratorWrapper<bool, regexp:: // ---------------------------------------------------------------------------- -void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const { - bool &ret = *(bool*) data; - +bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation) { for(const auto& element : alternation.getElements()) { - static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, *this); - if(! ret) { - ret = false; - return; + if(! element->accept < bool, RegExpEmpty::Unbounded > ( ) ) { + return false; } } - ret = true; + return true; } -void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const { - bool &ret = *(bool*) data; - +bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation) { for(const auto& element : concatenation.getElements()) { - static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, *this); - if(ret) { - ret = true; - return; + if( element->accept < bool, RegExpEmpty::Unbounded > ( ) ) { + return true; } } - ret = false; + return false; } -void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpIteration&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpIteration&) { + return false; } -void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpSymbol&) { + return false; } -void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const { - bool &ret = *(bool*) data; - ret = true; +bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEmpty&) { + return true; } -void RegExpEmpty::Unbounded::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEmpty::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&) { + return false; } -const RegExpEmpty::Unbounded RegExpEmpty::Unbounded::UNBOUNDED; - // ---------------------------------------------------------------------------- -void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const { - bool &ret = *(bool*) data; - - static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(data, *this); - bool retLeft = ret; - - static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(data, *this); - bool retRight = ret; - - ret = retLeft && retRight; +bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpAlternation& alternation) { + return alternation.getLeftElement().accept < bool, RegExpEmpty::Formal > ( ) && alternation.getRightElement().accept < bool, RegExpEmpty::Formal > ( ); } -void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const { - bool &ret = *(bool*) data; - - static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(data, *this); - bool retLeft = ret; - - static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(data, *this); - bool retRight = ret; - - ret = retLeft || retRight; +bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation) { + return concatenation.getLeftElement().accept < bool, RegExpEmpty::Formal > ( ) || concatenation.getRightElement().accept < bool, RegExpEmpty::Formal > ( ); } -void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpIteration&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpIteration&) { + return false; } -void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpSymbol&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpSymbol&) { + return false; } -void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpEmpty&) const { - bool &ret = *(bool*) data; - ret = true; +bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEmpty&) { + return true; } -void RegExpEmpty::Formal::Visit(void* data, const regexp::FormalRegExpEpsilon&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEmpty::Formal::visit(const regexp::FormalRegExpEpsilon&) { + return false; } -const RegExpEmpty::Formal RegExpEmpty::Formal::FORMAL; - } /* namespace properties */ } /* namespace regexp */ diff --git a/alib2algo/src/regexp/properties/RegExpEmpty.h b/alib2algo/src/regexp/properties/RegExpEmpty.h index 2551bccad7..6fb4455a71 100644 --- a/alib2algo/src/regexp/properties/RegExpEmpty.h +++ b/alib2algo/src/regexp/properties/RegExpEmpty.h @@ -36,34 +36,24 @@ public: static bool languageIsEmpty(const regexp::UnboundedRegExpStructure& regexp); static bool languageIsEmpty(const regexp::UnboundedRegExp& regexp); - class Unbounded : public regexp::UnboundedRegExpElement::Visitor { + class Unbounded { public: - Unbounded ( ) { } - - static const Unbounded UNBOUNDED; - - private: - void Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const; - void Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const; - void Visit(void* data, const regexp::UnboundedRegExpIteration& iteration) const; - void Visit(void* data, const regexp::UnboundedRegExpSymbol& symbol) const; - void Visit(void* data, const regexp::UnboundedRegExpEmpty& empty) const; - void Visit(void* data, const regexp::UnboundedRegExpEpsilon& epsilon) const; + static bool visit(const regexp::UnboundedRegExpAlternation& alternation); + static bool visit(const regexp::UnboundedRegExpConcatenation& concatenation); + static bool visit(const regexp::UnboundedRegExpIteration& iteration); + static bool visit(const regexp::UnboundedRegExpSymbol& symbol); + static bool visit(const regexp::UnboundedRegExpEmpty& empty); + static bool visit(const regexp::UnboundedRegExpEpsilon& epsilon); }; - class Formal : public regexp::FormalRegExpElement::Visitor { + class Formal { public: - Formal ( ) { } - - static const Formal FORMAL; - - private: - void Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const; - void Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const; - void Visit(void* data, const regexp::FormalRegExpIteration& iteration) const; - void Visit(void* data, const regexp::FormalRegExpSymbol& symbol) const; - void Visit(void* data, const regexp::FormalRegExpEmpty& empty) const; - void Visit(void* data, const regexp::FormalRegExpEpsilon& epsilon) const; + static bool visit(const regexp::FormalRegExpAlternation& alternation); + static bool visit(const regexp::FormalRegExpConcatenation& concatenation); + static bool visit(const regexp::FormalRegExpIteration& iteration); + static bool visit(const regexp::FormalRegExpSymbol& symbol); + static bool visit(const regexp::FormalRegExpEmpty& empty); + static bool visit(const regexp::FormalRegExpEpsilon& epsilon); }; }; diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp index bf0714503b..a7e9910cd9 100644 --- a/alib2algo/src/regexp/properties/RegExpEpsilon.cpp +++ b/alib2algo/src/regexp/properties/RegExpEpsilon.cpp @@ -18,9 +18,7 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::RegExp& regexp) { } bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpElement& regexp) { - bool out; - regexp.Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON); - return out; + return regexp.accept<bool, RegExpEpsilon::Formal>(); } bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExpStructure& regexp) { @@ -34,9 +32,7 @@ bool RegExpEpsilon::languageContainsEpsilon(const regexp::FormalRegExp& regexp) auto RegExpEpsilonFormalRegExp = RegExpEpsilon::RegistratorWrapper<bool, regexp::FormalRegExp>( RegExpEpsilon::languageContainsEpsilon); bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpElement& regexp) { - bool out; - regexp.Accept((void*) &out, RegExpEpsilon::REG_EXP_EPSILON); - return out; + return regexp.accept<bool, RegExpEpsilon::Unbounded>(); } bool RegExpEpsilon::languageContainsEpsilon(const regexp::UnboundedRegExpStructure& regexp) { @@ -51,104 +47,64 @@ auto RegExpEpsilonUnboundedRegExp = RegExpEpsilon::RegistratorWrapper<bool, rege // --------------------------------------------------------------------------- -void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const { - bool &ret = *(bool*) data; +bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation) { + for ( const auto & element : alternation.getElements ( ) ) + if ( element->accept < bool, RegExpEpsilon::Unbounded > ( ) ) + return true; - for(const auto& element : alternation.getElements()) { - static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, RegExpEpsilon::REG_EXP_EPSILON); - if(ret) { - ret = true; - return; - } - } - - ret = false; + return false; } -void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const { - bool &ret = *(bool*) data; +bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation) { + for ( const auto & element : concatenation.getElements ( ) ) + if ( ! element->accept < bool, RegExpEpsilon::Unbounded > ( ) ) + return false; - for(const auto& element : concatenation.getElements()) { - static_cast<const regexp::UnboundedRegExpElement&>(*element).Accept(data, RegExpEpsilon::REG_EXP_EPSILON); - if(!ret) { - ret = false; - return; - } - } - - ret = true; + return true; } -void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpIteration&) const { - bool &ret = *(bool*) data; - ret = true; +bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpIteration&) { + return true; } -void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpSymbol&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpSymbol&) { + return false; } -void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpEpsilon&) const { - bool &ret = *(bool*) data; - ret = true; +bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&) { + return true; } -void RegExpEpsilon::Visit(void* data, const regexp::UnboundedRegExpEmpty&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEpsilon::Unbounded::visit(const regexp::UnboundedRegExpEmpty&) { + return false; } // ---------------------------------------------------------------------------- -void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const { - bool &ret = *(bool*) data; - - static_cast<const regexp::FormalRegExpElement&>(alternation.getLeftElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON); - bool retLeft = ret; - - static_cast<const regexp::FormalRegExpElement&>(alternation.getRightElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON); - bool retRight = ret; - - ret = retLeft || retRight; +bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpAlternation& alternation) { + return alternation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() || alternation.getRightElement().accept<bool, RegExpEpsilon::Formal>(); } -void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const { - bool &ret = *(bool*) data; - - static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON); - bool retLeft = ret; - - static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(data, RegExpEpsilon::REG_EXP_EPSILON); - bool retRight = ret; - - ret = retLeft && retRight; +bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation) { + return concatenation.getLeftElement().accept<bool, RegExpEpsilon::Formal>() && concatenation.getRightElement().accept<bool, RegExpEpsilon::Formal>(); } -void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpIteration&) const { - bool &ret = *(bool*) data; - ret = true; +bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpIteration&) { + return true; } -void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpSymbol&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpSymbol&) { + return false; } -void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpEmpty&) const { - bool &ret = *(bool*) data; - ret = false; +bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEmpty&) { + return false; } -void RegExpEpsilon::Visit(void* data, const regexp::FormalRegExpEpsilon&) const { - bool &ret = *(bool*) data; - ret = true; +bool RegExpEpsilon::Formal::visit(const regexp::FormalRegExpEpsilon&) { + return true; } -// --------------------------------------------------------------------------- - -const RegExpEpsilon RegExpEpsilon::REG_EXP_EPSILON; - } /* namespace properties */ } /* namespace regexp */ diff --git a/alib2algo/src/regexp/properties/RegExpEpsilon.h b/alib2algo/src/regexp/properties/RegExpEpsilon.h index 4ce6bb7349..e6002f7b1d 100644 --- a/alib2algo/src/regexp/properties/RegExpEpsilon.h +++ b/alib2algo/src/regexp/properties/RegExpEpsilon.h @@ -24,10 +24,8 @@ namespace properties { * Checks, whether regexp (or its subtree) describes epsilon (empty string). * */ -class RegExpEpsilon : public std::SingleDispatch<RegExpEpsilon, bool, const regexp::RegExpBase &>, regexp::FormalRegExpElement::Visitor, regexp::UnboundedRegExpElement::Visitor { +class RegExpEpsilon : public std::SingleDispatch<RegExpEpsilon, bool, const regexp::RegExpBase &> { public: - RegExpEpsilon() {} - static bool languageContainsEpsilon(const regexp::RegExp& regexp); static bool languageContainsEpsilon(const regexp::FormalRegExpElement& regexp); @@ -38,22 +36,25 @@ public: static bool languageContainsEpsilon(const regexp::UnboundedRegExpStructure& regexp); static bool languageContainsEpsilon(const regexp::UnboundedRegExp& regexp); -private: - void Visit(void* data, const regexp::UnboundedRegExpAlternation& alternation) const; - void Visit(void* data, const regexp::UnboundedRegExpConcatenation& concatenation) const; - void Visit(void* data, const regexp::UnboundedRegExpIteration& iteration) const; - void Visit(void* data, const regexp::UnboundedRegExpSymbol& symbol) const; - void Visit(void* data, const regexp::UnboundedRegExpEmpty& empty) const; - void Visit(void* data, const regexp::UnboundedRegExpEpsilon& epsilon) const; - - void Visit(void* data, const regexp::FormalRegExpAlternation& alternation) const; - void Visit(void* data, const regexp::FormalRegExpConcatenation& concatenation) const; - void Visit(void* data, const regexp::FormalRegExpIteration& iteration) const; - void Visit(void* data, const regexp::FormalRegExpSymbol& symbol) const; - void Visit(void* data, const regexp::FormalRegExpEmpty& empty) const; - void Visit(void* data, const regexp::FormalRegExpEpsilon& epsilon) const; - - static const RegExpEpsilon REG_EXP_EPSILON; + class Unbounded { + public: + static bool visit(const regexp::UnboundedRegExpAlternation& alternation); + static bool visit(const regexp::UnboundedRegExpConcatenation& concatenation); + static bool visit(const regexp::UnboundedRegExpIteration& iteration); + static bool visit(const regexp::UnboundedRegExpSymbol& symbol); + static bool visit(const regexp::UnboundedRegExpEmpty& empty); + static bool visit(const regexp::UnboundedRegExpEpsilon& epsilon); + }; + + class Formal { + public: + static bool visit(const regexp::FormalRegExpAlternation& alternation); + static bool visit(const regexp::FormalRegExpConcatenation& concatenation); + static bool visit(const regexp::FormalRegExpIteration& iteration); + static bool visit(const regexp::FormalRegExpSymbol& symbol); + static bool visit(const regexp::FormalRegExpEmpty& empty); + static bool visit(const regexp::FormalRegExpEpsilon& epsilon); + }; }; } /* namespace properties */ diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.cpp b/alib2algo/src/regexp/transform/RegExpDerivation.cpp index ca1287e112..afd330d1e7 100644 --- a/alib2algo/src/regexp/transform/RegExpDerivation.cpp +++ b/alib2algo/src/regexp/transform/RegExpDerivation.cpp @@ -20,11 +20,8 @@ regexp::RegExp RegExpDerivation::derivation(const regexp::RegExp& regexp, const regexp::FormalRegExp RegExpDerivation::derivation(const regexp::FormalRegExp& regexp, const string::LinearString < >& string) { std::unique_ptr < regexp::FormalRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() ); - for(const auto& symbol : string.getContent()) { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > > out(symbol, nullptr); - newRegExp->Accept((void*) &out, RegExpDerivation::Formal::FORMAL); - newRegExp = std::move ( out.second ); - } + for(const auto& symbol : string.getContent()) + newRegExp = newRegExp->accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(symbol); return regexp::FormalRegExp ( regexp::FormalRegExpStructure ( std::move ( * newRegExp ) ) ); } @@ -34,11 +31,8 @@ auto RegExpDerivationFormalRegExp = RegExpDerivation::RegistratorWrapper<regexp: regexp::UnboundedRegExp RegExpDerivation::derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string) { std::unique_ptr < regexp::UnboundedRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() ); - for(const auto& symbol : string.getContent()) { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > out(symbol, nullptr); - newRegExp->Accept((void*) &out, RegExpDerivation::Unbounded::UNBOUNDED); - newRegExp = std::move ( out.second ); - } + for(const auto& symbol : string.getContent()) + newRegExp = newRegExp->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( symbol ); return regexp::UnboundedRegExp ( regexp::UnboundedRegExpStructure ( std::move ( * newRegExp ) ) ); } @@ -47,85 +41,65 @@ auto RegExpDerivationUnboundedRegExp = RegExpDerivation::RegistratorWrapper<rege // ---------------------------------------------------------------------------- -void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - - alternation.getLeftElement().Accept(userData, *this); - std::unique_ptr < regexp::FormalRegExpElement > leftDerivative = std::move ( out.second ); - - alternation.getRightElement().Accept(userData, *this); +std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument) { + std::unique_ptr < regexp::FormalRegExpElement > leftDerivative = alternation.getLeftElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument); + std::unique_ptr < regexp::FormalRegExpElement > rightDerivative = alternation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument); - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftDerivative ), std::move ( * out.second ) ) ); + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftDerivative ), std::move ( * rightDerivative ) ) ); } -void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); +std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument) { + std::unique_ptr < regexp::FormalRegExpElement > leftDerivative = concatenation.getLeftElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument); - concatenation.getLeftElement().Accept(userData, *this); - - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( std::move ( * out.second ), std::move_copy ( concatenation.getRightElement ( ) ) ) ); + std::unique_ptr < regexp::FormalRegExpElement > res ( new regexp::FormalRegExpConcatenation( std::move ( * leftDerivative ), std::move_copy ( concatenation.getRightElement ( ) ) ) ); if(regexp::properties::RegExpEpsilon::languageContainsEpsilon(concatenation.getLeftElement())) { - std::unique_ptr < regexp::FormalRegExpElement > alternation = std::move ( out.second ); - concatenation.getRightElement().Accept(userData, *this); + std::unique_ptr < regexp::FormalRegExpElement > rightDerivative = concatenation.getRightElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal>(argument); - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation ( std::move ( * alternation ), std::move( * out.second ) ) ); + res = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation ( std::move ( * res ), std::move( * rightDerivative ) ) ); } -} - -void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - - iteration.getElement().Accept(userData, *this); - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( std::move ( * out.second ), iteration ) ); + return res; } -void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); +std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument) { + std::unique_ptr < regexp::FormalRegExpElement > elementDerivative = iteration.getElement().accept<std::unique_ptr < regexp::FormalRegExpElement >, regexp::RegExpDerivation::Formal > ( argument ); + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpConcatenation( * elementDerivative, iteration ) ); +} - if(out.first == symbol.getSymbol()) - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEpsilon() ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument) { + if(argument == symbol.getSymbol()) + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEpsilon() ); else - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() ); + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() ); } -void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEpsilon&, const alphabet::Symbol&) { + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() ); } -void RegExpDerivation::Formal::Visit(void* userData, const regexp::FormalRegExpEmpty&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpDerivation::Formal::visit(const regexp::FormalRegExpEmpty&, const alphabet::Symbol&) { + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpEmpty() ); } -const RegExpDerivation::Formal RegExpDerivation::Formal::FORMAL; - // ---------------------------------------------------------------------------- - -void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument) { std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() ); - for(const auto& child : alternation.getElements()) { - child->Accept(userData, *this); - ret->appendElement(std::move( * out.second ) ); - } + for(const auto& child : alternation.getElements()) + ret->appendElement( * ( child->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) ); - out.second = std::move ( ret ); + return ret; } -void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument) { std::unique_ptr < regexp::UnboundedRegExpAlternation > ret ( new regexp::UnboundedRegExpAlternation() ); for(auto child = concatenation.getElements().begin(); child != concatenation.getElements().end(); ++ child) { std::unique_ptr < regexp::UnboundedRegExpConcatenation > concat ( new regexp::UnboundedRegExpConcatenation() ); - (*child)->Accept(userData, *this); - concat->appendElement( std::move ( * out.second ) ); + concat->appendElement( * ( (*child)->accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) ); auto succeedingElement = child; while(++succeedingElement != concatenation.getElements().end()) @@ -137,39 +111,29 @@ void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedR break; } - out.second = std::move ( ret ); + return ret; } -void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData); - - iteration.getElement().Accept(userData, *this); - +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument) { UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( ); - con->appendElement ( std::move ( * out.second ) ); + con->appendElement ( * ( iteration.getElement().accept<std::unique_ptr < regexp::UnboundedRegExpElement >, regexp::RegExpDerivation::Unbounded > ( argument ) ) ); con->appendElement ( iteration ); - out.second = std::unique_ptr < UnboundedRegExpElement > ( con ); + return std::unique_ptr < UnboundedRegExpElement > ( con ); } -void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData); - - if(out.first == symbol.getSymbol()) - out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEpsilon() ); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument) { + if(argument == symbol.getSymbol()) + return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEpsilon() ); else - out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() ); + return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() ); } -void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData); - out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() ); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, const alphabet::Symbol&) { + return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() ); } -void RegExpDerivation::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>>*) userData); - out.second = std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() ); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpDerivation::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, const alphabet::Symbol&) { + return std::unique_ptr < UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty() ); } -const RegExpDerivation::Unbounded RegExpDerivation::Unbounded::UNBOUNDED; - } /* namespace regexp */ diff --git a/alib2algo/src/regexp/transform/RegExpDerivation.h b/alib2algo/src/regexp/transform/RegExpDerivation.h index 1c24962014..e145ebfbff 100644 --- a/alib2algo/src/regexp/transform/RegExpDerivation.h +++ b/alib2algo/src/regexp/transform/RegExpDerivation.h @@ -40,34 +40,24 @@ public: static regexp::UnboundedRegExp derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string); private: - class Formal : public regexp::FormalRegExpElement::Visitor { + class Formal { public: - Formal ( ) { } - - static const Formal FORMAL; - - private: - void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const; - void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const; - void Visit(void*, const regexp::FormalRegExpIteration& iteration) const; - void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const; - void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const; - void Visit(void*, const regexp::FormalRegExpEmpty& empty) const; + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEpsilon& epsilon, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEmpty& empty, const alphabet::Symbol& argument); }; - class Unbounded : public regexp::UnboundedRegExpElement::Visitor { + class Unbounded { public: - Unbounded ( ) { } - - static const Unbounded UNBOUNDED; - - private: - void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const; - void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const; - void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const; - void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const; - void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const; - void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const; + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEpsilon& epsilon, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEmpty& empty, const alphabet::Symbol& argument); }; }; diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.cpp b/alib2algo/src/regexp/transform/RegExpIntegral.cpp index 047b2c5db8..f3f598ef49 100644 --- a/alib2algo/src/regexp/transform/RegExpIntegral.cpp +++ b/alib2algo/src/regexp/transform/RegExpIntegral.cpp @@ -18,11 +18,8 @@ regexp::RegExp RegExpIntegral::integral(const regexp::RegExp& regexp, const stri regexp::FormalRegExp RegExpIntegral::integral(const regexp::FormalRegExp& regexp, const string::LinearString < >& string) { std::unique_ptr < regexp::FormalRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() ); - for(const auto& symbol : string.getContent()) { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > > out(symbol, nullptr); - newRegExp->Accept((void*) &out, RegExpIntegral::Formal::FORMAL); - newRegExp = std::move ( out.second ); - } + for(const auto& symbol : string.getContent()) + newRegExp = newRegExp->accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( symbol ); return regexp::FormalRegExp ( regexp::FormalRegExpStructure ( * newRegExp ) ); } @@ -32,11 +29,8 @@ auto RegExpIntegralFormalRegExp = RegExpIntegral::RegistratorWrapper<regexp::For regexp::UnboundedRegExp RegExpIntegral::integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string) { std::unique_ptr < regexp::UnboundedRegExpElement > newRegExp ( regexp.getRegExp().getStructure().clone() ); - for(const auto& symbol : string.getContent()) { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > > out(symbol, nullptr); - newRegExp->Accept((void*) &out, RegExpIntegral::Unbounded::UNBOUNDED); - newRegExp = std::move ( out.second ); - } + for(const auto& symbol : string.getContent()) + newRegExp = newRegExp->accept < std::unique_ptr < regexp::UnboundedRegExpElement >, RegExpIntegral::Unbounded > ( symbol ); return regexp::UnboundedRegExp ( regexp::UnboundedRegExpStructure( * newRegExp ) ); } @@ -45,108 +39,77 @@ auto RegExpIntegralUnboundedRegExp = RegExpIntegral::RegistratorWrapper<regexp:: // ---------------------------------------------------------------------------- -void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); +std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument) { + std::unique_ptr < regexp::FormalRegExpElement > leftIntegral = alternation.getLeftElement().accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( argument ); + std::unique_ptr < regexp::FormalRegExpElement > rightIntegral = alternation.getRightElement().accept < std::unique_ptr < regexp::FormalRegExpElement >, RegExpIntegral::Formal > ( argument ); - alternation.getLeftElement().Accept(userData, *this); - std::unique_ptr < regexp::FormalRegExpElement > leftIntegral = std::move ( out.second ); - - alternation.getRightElement().Accept(userData, *this); - - out.second = std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftIntegral ), std::move ( * out.second ) ) ); + return std::unique_ptr < FormalRegExpElement > ( new regexp::FormalRegExpAlternation( std::move ( * leftIntegral ), std::move ( * rightIntegral ) ) ); } -void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - - out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( out.first ), concatenation ) ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument) { + return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( argument ), concatenation ) ); } -void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - - out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( out.first ), iteration ) ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument) { + return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( argument ), iteration ) ); } -void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - - out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( out.first ), symbol ) ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument) { + return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpConcatenation ( regexp::FormalRegExpSymbol ( argument ), symbol ) ); } -void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpSymbol( out.first ) ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEpsilon&, const alphabet::Symbol& argument) { + return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpSymbol( argument ) ); } -void RegExpIntegral::Formal::Visit(void* userData, const regexp::FormalRegExpEmpty&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::FormalRegExpElement > >*) userData); - out.second = std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpEmpty( ) ); +std::unique_ptr < regexp::FormalRegExpElement > RegExpIntegral::Formal::visit(const regexp::FormalRegExpEmpty&, const alphabet::Symbol&) { + return std::unique_ptr < regexp::FormalRegExpElement > ( new regexp::FormalRegExpEmpty( ) ); } -const RegExpIntegral::Formal RegExpIntegral::Formal::FORMAL; - // ---------------------------------------------------------------------------- -void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const -{ - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData); - +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument) { regexp::UnboundedRegExpAlternation* alt = new regexp::UnboundedRegExpAlternation(); - for(const auto& child : alternation.getElements()) { - child->Accept(userData, *this); - alt->appendElement(std::move(*out.second)); - } + for(const auto& child : alternation.getElements()) + alt->appendElement(* ( child->accept < std::unique_ptr < regexp::UnboundedRegExpElement >, RegExpIntegral::Unbounded > (argument) ) ); - out.second = std::unique_ptr < UnboundedRegExpElement > ( alt ); + return std::unique_ptr < UnboundedRegExpElement > ( alt ); } -void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData); - +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument) { regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( ); - con->appendElement ( regexp::UnboundedRegExpSymbol ( out.first ) ); + con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) ); for ( const auto & element : concatenation.getElements() ) con->appendElement ( * element ); - out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con ); + return std::unique_ptr < regexp::UnboundedRegExpElement > ( con ); } -void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData); - +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument) { regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( ); - con->appendElement ( regexp::UnboundedRegExpSymbol ( out.first ) ); + con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) ); con->appendElement ( iteration ); - out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con ); + return std::unique_ptr < regexp::UnboundedRegExpElement > ( con ); } -void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData); - +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument) { regexp::UnboundedRegExpConcatenation * con = new regexp::UnboundedRegExpConcatenation( ); - con->appendElement ( regexp::UnboundedRegExpSymbol ( out.first ) ); + con->appendElement ( regexp::UnboundedRegExpSymbol ( argument ) ); con->appendElement ( symbol ); - out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( con ); + return std::unique_ptr < regexp::UnboundedRegExpElement > ( con ); } -void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData); - - out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpSymbol( out.first ) ); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEpsilon&, const alphabet::Symbol& argument) { + return std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpSymbol( argument ) ); } -void RegExpIntegral::Unbounded::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const { - std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement>> &out = *((std::pair<alphabet::Symbol, std::unique_ptr < regexp::UnboundedRegExpElement > >*) userData); - - out.second = std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty( ) ); +std::unique_ptr < regexp::UnboundedRegExpElement > RegExpIntegral::Unbounded::visit(const regexp::UnboundedRegExpEmpty&, const alphabet::Symbol&) { + return std::unique_ptr < regexp::UnboundedRegExpElement > ( new regexp::UnboundedRegExpEmpty( ) ); } -const RegExpIntegral::Unbounded RegExpIntegral::Unbounded::UNBOUNDED; - } /* namespace regexp */ diff --git a/alib2algo/src/regexp/transform/RegExpIntegral.h b/alib2algo/src/regexp/transform/RegExpIntegral.h index 3a9fa67313..ab84ebd42f 100644 --- a/alib2algo/src/regexp/transform/RegExpIntegral.h +++ b/alib2algo/src/regexp/transform/RegExpIntegral.h @@ -37,34 +37,24 @@ public: static regexp::UnboundedRegExp integral(const regexp::UnboundedRegExp& regexp, const string::LinearString < >& string); private: - class Formal : public regexp::FormalRegExpElement::Visitor { + class Formal { public: - Formal ( ) { } - - static const Formal FORMAL; - - private: - void Visit(void*, const regexp::FormalRegExpAlternation& alternation) const; - void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation) const; - void Visit(void*, const regexp::FormalRegExpIteration& iteration) const; - void Visit(void*, const regexp::FormalRegExpSymbol& symbol) const; - void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon) const; - void Visit(void*, const regexp::FormalRegExpEmpty& empty) const; + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpAlternation& alternation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpConcatenation& concatenation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpIteration& iteration, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpSymbol& symbol, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEpsilon& epsilon, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::FormalRegExpElement > visit(const regexp::FormalRegExpEmpty& empty, const alphabet::Symbol& argument); }; - class Unbounded : public regexp::UnboundedRegExpElement::Visitor { + class Unbounded { public: - Unbounded ( ) { } - - static const Unbounded UNBOUNDED; - - private: - void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation) const; - void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation) const; - void Visit(void*, const regexp::UnboundedRegExpIteration& iteration) const; - void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol) const; - void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon) const; - void Visit(void*, const regexp::UnboundedRegExpEmpty& empty) const; + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpAlternation& alternation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpConcatenation& concatenation, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpIteration& iteration, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpSymbol& symbol, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEpsilon& epsilon, const alphabet::Symbol& argument); + static std::unique_ptr < regexp::UnboundedRegExpElement > visit(const regexp::UnboundedRegExpEmpty& empty, const alphabet::Symbol& argument); }; }; diff --git a/alib2data/src/regexp/common/RegExpToXMLComposer.cpp b/alib2data/src/regexp/common/RegExpToXMLComposer.cpp index 0cc3a3372b..a985ff877e 100644 --- a/alib2data/src/regexp/common/RegExpToXMLComposer.cpp +++ b/alib2data/src/regexp/common/RegExpToXMLComposer.cpp @@ -16,98 +16,72 @@ namespace regexp { -void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpAlternation& alternation, std::deque<sax::Token>& out) { out.emplace_back("alternation", sax::Token::TokenType::START_ELEMENT); for (const auto& element : alternation.getElements()) { - element->Accept(userData, *this); + element->accept < void, RegExpToXMLComposer::Unbounded > ( out ); } out.emplace_back("alternation", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpConcatenation& concatenation, std::deque<sax::Token>& out) { out.emplace_back("concatenation", sax::Token::TokenType::START_ELEMENT); for (auto element : concatenation.getElements()) { - element->Accept(userData, *this); + element->accept < void, RegExpToXMLComposer::Unbounded > ( out ); } out.emplace_back("concatenation", sax::Token::TokenType::END_ELEMENT); - } -void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpIteration& iteration) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpIteration& iteration, std::deque<sax::Token>& out) { out.emplace_back("iteration", sax::Token::TokenType::START_ELEMENT); - iteration.getElement().Accept(userData, *this); + iteration.getElement().accept < void, RegExpToXMLComposer::Unbounded > ( out ); out.emplace_back("iteration", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpSymbol& symbol, std::deque<sax::Token>& out) { alib::xmlApi<alphabet::Symbol>::compose(out, symbol.getSymbol()); } -void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpEpsilon&) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpEpsilon&, std::deque<sax::Token>& out) { out.emplace_back("epsilon", sax::Token::TokenType::START_ELEMENT); out.emplace_back("epsilon", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Unbounded::Visit(void* userData, const UnboundedRegExpEmpty&) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Unbounded::visit(const UnboundedRegExpEmpty&, std::deque<sax::Token>& out) { out.emplace_back("empty", sax::Token::TokenType::START_ELEMENT); out.emplace_back("empty", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpAlternation& alternation) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Formal::visit(const FormalRegExpAlternation& alternation, std::deque<sax::Token>& out) { out.emplace_back("alternation", sax::Token::TokenType::START_ELEMENT); - alternation.getLeftElement().Accept(userData, *this); - alternation.getRightElement().Accept(userData, *this); + alternation.getLeftElement().accept < void, RegExpToXMLComposer::Formal > ( out ); + alternation.getRightElement().accept < void, RegExpToXMLComposer::Formal > ( out ); out.emplace_back("alternation", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Formal::visit(const FormalRegExpConcatenation& concatenation, std::deque<sax::Token>& out) { out.emplace_back("concatenation", sax::Token::TokenType::START_ELEMENT); - concatenation.getLeftElement().Accept(userData, *this); - concatenation.getRightElement().Accept(userData, *this); + concatenation.getLeftElement().accept < void, RegExpToXMLComposer::Formal > ( out ); + concatenation.getRightElement().accept < void, RegExpToXMLComposer::Formal > ( out ); out.emplace_back("concatenation", sax::Token::TokenType::END_ELEMENT); - } -void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpIteration& iteration) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Formal::visit(const FormalRegExpIteration& iteration, std::deque<sax::Token>& out) { out.emplace_back("iteration", sax::Token::TokenType::START_ELEMENT); - iteration.getElement().Accept(userData, *this); + iteration.getElement().accept < void, RegExpToXMLComposer::Formal > ( out ); out.emplace_back("iteration", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpSymbol& symbol) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Formal::visit(const FormalRegExpSymbol& symbol, std::deque<sax::Token>& out) { alib::xmlApi<alphabet::Symbol>::compose(out, symbol.getSymbol()); } -void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpEpsilon&) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Formal::visit(const FormalRegExpEpsilon&, std::deque<sax::Token>& out) { out.emplace_back("epsilon", sax::Token::TokenType::START_ELEMENT); out.emplace_back("epsilon", sax::Token::TokenType::END_ELEMENT); } -void RegExpToXMLComposer::Formal::Visit(void* userData, const FormalRegExpEmpty&) const { - std::deque<sax::Token> &out = *((std::deque<sax::Token>*) userData); - +void RegExpToXMLComposer::Formal::visit(const FormalRegExpEmpty&, std::deque<sax::Token>& out) { out.emplace_back("empty", sax::Token::TokenType::START_ELEMENT); out.emplace_back("empty", sax::Token::TokenType::END_ELEMENT); } @@ -120,7 +94,4 @@ void RegExpToXMLComposer::composeAlphabet(std::deque<sax::Token>& out, const std out.emplace_back("alphabet", sax::Token::TokenType::END_ELEMENT); } -RegExpToXMLComposer::Unbounded RegExpToXMLComposer::Unbounded::UNBOUNDED; -RegExpToXMLComposer::Formal RegExpToXMLComposer::Formal::FORMAL; - } /* namespace regexp */ diff --git a/alib2data/src/regexp/common/RegExpToXMLComposer.h b/alib2data/src/regexp/common/RegExpToXMLComposer.h index e6bc3fa8be..09f64ac523 100644 --- a/alib2data/src/regexp/common/RegExpToXMLComposer.h +++ b/alib2data/src/regexp/common/RegExpToXMLComposer.h @@ -23,34 +23,24 @@ class RegExpToXMLComposer { public: static void composeAlphabet(std::deque<sax::Token>& out, const std::set<alphabet::Symbol>& alphabet); - class Unbounded : public UnboundedRegExpElement::Visitor { + class Unbounded { public: - Unbounded() {} - - static Unbounded UNBOUNDED; - - private: - void Visit(void*, const UnboundedRegExpAlternation& alternation) const; - void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const; - void Visit(void*, const UnboundedRegExpIteration& iteration) const; - void Visit(void*, const UnboundedRegExpSymbol& symbol) const; - void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const; - void Visit(void*, const UnboundedRegExpEmpty& empty) const; + static void visit( const UnboundedRegExpAlternation& alternation, std::deque < sax::Token > & output); + static void visit( const UnboundedRegExpConcatenation& concatenation, std::deque < sax::Token > & output); + static void visit( const UnboundedRegExpIteration& iteration, std::deque < sax::Token > & output); + static void visit( const UnboundedRegExpSymbol& symbol, std::deque < sax::Token > & output); + static void visit( const UnboundedRegExpEpsilon& epsilon, std::deque < sax::Token > & output); + static void visit( const UnboundedRegExpEmpty& empty, std::deque < sax::Token > & output); }; - class Formal : public FormalRegExpElement::Visitor { + class Formal { public: - Formal() {} - - static Formal FORMAL; - - private: - void Visit(void*, const FormalRegExpAlternation& alternation) const; - void Visit(void*, const FormalRegExpConcatenation& concatenation) const; - void Visit(void*, const FormalRegExpIteration& iteration) const; - void Visit(void*, const FormalRegExpSymbol& symbol) const; - void Visit(void*, const FormalRegExpEpsilon& epsilon) const; - void Visit(void*, const FormalRegExpEmpty& empty) const; + static void visit( const FormalRegExpAlternation& alternation, std::deque < sax::Token > & output); + static void visit( const FormalRegExpConcatenation& concatenation, std::deque < sax::Token > & output); + static void visit( const FormalRegExpIteration& iteration, std::deque < sax::Token > & output); + static void visit( const FormalRegExpSymbol& symbol, std::deque < sax::Token > & output); + static void visit( const FormalRegExpEpsilon& epsilon, std::deque < sax::Token > & output); + static void visit( const FormalRegExpEmpty& empty, std::deque < sax::Token > & output); }; }; diff --git a/alib2data/src/regexp/formal/FormalRegExpAlternation.h b/alib2data/src/regexp/formal/FormalRegExpAlternation.h index 4bc686593f..fd534ac2de 100644 --- a/alib2data/src/regexp/formal/FormalRegExpAlternation.h +++ b/alib2data/src/regexp/formal/FormalRegExpAlternation.h @@ -19,8 +19,8 @@ namespace regexp { */ class FormalRegExpAlternation : public FormalRegExpElement, public std::BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpAlternation > { public: - void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( FormalRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit FormalRegExpAlternation ( FormalRegExpElement && left, FormalRegExpElement && right ); diff --git a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h index d15208d7fe..51ce41638e 100644 --- a/alib2data/src/regexp/formal/FormalRegExpConcatenation.h +++ b/alib2data/src/regexp/formal/FormalRegExpConcatenation.h @@ -21,8 +21,8 @@ namespace regexp { */ class FormalRegExpConcatenation : public FormalRegExpElement, public std::BinaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpConcatenation > { public: - void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( FormalRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit FormalRegExpConcatenation ( FormalRegExpElement && left, FormalRegExpElement && right ); diff --git a/alib2data/src/regexp/formal/FormalRegExpElement.h b/alib2data/src/regexp/formal/FormalRegExpElement.h index b694ce8ba4..944dc753f5 100644 --- a/alib2data/src/regexp/formal/FormalRegExpElement.h +++ b/alib2data/src/regexp/formal/FormalRegExpElement.h @@ -12,6 +12,7 @@ #include "../../alphabet/Symbol.h" #include <set> #include <tree> +#include <core/visitor.hpp> namespace regexp { @@ -31,15 +32,52 @@ class FormalRegExpElement : public alib::CommonBase < FormalRegExpElement >, pub public: class Visitor { public: - virtual void Visit ( void *, const FormalRegExpAlternation & ) const = 0; - virtual void Visit ( void *, const FormalRegExpConcatenation & ) const = 0; - virtual void Visit ( void *, const FormalRegExpIteration & ) const = 0; - virtual void Visit ( void *, const FormalRegExpSymbol & ) const = 0; - virtual void Visit ( void *, const FormalRegExpEmpty & ) const = 0; - virtual void Visit ( void *, const FormalRegExpEpsilon & ) const = 0; + virtual void visit ( const FormalRegExpAlternation & ) = 0; + virtual void visit ( const FormalRegExpConcatenation & ) = 0; + virtual void visit ( const FormalRegExpIteration & ) = 0; + virtual void visit ( const FormalRegExpSymbol & ) = 0; + virtual void visit ( const FormalRegExpEmpty & ) = 0; + virtual void visit ( const FormalRegExpEpsilon & ) = 0; }; - virtual void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const = 0; + template < class ReturnType, class Visitorr, class ... Params > + class VisitorContext : public std::VisitorContextAux < ReturnType, Visitorr, Params ... >, public FormalRegExpElement::Visitor { + public: + using std::VisitorContextAux < ReturnType, Visitorr, Params ... >::VisitorContextAux; + + void visit ( const FormalRegExpAlternation & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const FormalRegExpConcatenation & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const FormalRegExpIteration & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const FormalRegExpSymbol & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const FormalRegExpEmpty & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const FormalRegExpEpsilon & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + }; + + template < class ReturnType, class Visitorr, class ... Params > + ReturnType accept ( Params && ... params ) const { + VisitorContext < ReturnType, Visitorr, Params ... > context ( std::forward < Params > ( params ) ... ); + accept ( context ); + return context.getResult ( ); + } + + virtual void accept ( FormalRegExpElement::Visitor & visitor ) const = 0; /** * Creates copy of the element. diff --git a/alib2data/src/regexp/formal/FormalRegExpEmpty.h b/alib2data/src/regexp/formal/FormalRegExpEmpty.h index 5f41279146..0609c82297 100644 --- a/alib2data/src/regexp/formal/FormalRegExpEmpty.h +++ b/alib2data/src/regexp/formal/FormalRegExpEmpty.h @@ -18,8 +18,8 @@ namespace regexp { */ class FormalRegExpEmpty : public FormalRegExpElement, public std::NullaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > { public: - void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( FormalRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit FormalRegExpEmpty ( ); diff --git a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h index 2260db4c3f..77deb0fe33 100644 --- a/alib2data/src/regexp/formal/FormalRegExpEpsilon.h +++ b/alib2data/src/regexp/formal/FormalRegExpEpsilon.h @@ -18,8 +18,8 @@ namespace regexp { */ class FormalRegExpEpsilon : public FormalRegExpElement, public std::NullaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpSymbol > { public: - void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( FormalRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit FormalRegExpEpsilon ( ); diff --git a/alib2data/src/regexp/formal/FormalRegExpIteration.h b/alib2data/src/regexp/formal/FormalRegExpIteration.h index c799ec2811..c687dea427 100644 --- a/alib2data/src/regexp/formal/FormalRegExpIteration.h +++ b/alib2data/src/regexp/formal/FormalRegExpIteration.h @@ -19,8 +19,8 @@ namespace regexp { */ class FormalRegExpIteration : public FormalRegExpElement, public std::UnaryNode < std::smart_ptr < FormalRegExpElement >, std::smart_ptr < const FormalRegExpElement >, FormalRegExpIteration > { public: - void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( FormalRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit FormalRegExpIteration ( FormalRegExpElement && ); diff --git a/alib2data/src/regexp/formal/FormalRegExpStructure.cpp b/alib2data/src/regexp/formal/FormalRegExpStructure.cpp index ba50e5ef31..5e90d8b1f3 100644 --- a/alib2data/src/regexp/formal/FormalRegExpStructure.cpp +++ b/alib2data/src/regexp/formal/FormalRegExpStructure.cpp @@ -58,7 +58,7 @@ bool xmlApi < regexp::FormalRegExpStructure >::first ( const std::deque < sax::T } void xmlApi < regexp::FormalRegExpStructure >::compose ( std::deque < sax::Token > & output, const regexp::FormalRegExpStructure & data ) { - data.getStructure ( ).Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::Formal::FORMAL ); + data.getStructure ( ).accept < void, regexp::RegExpToXMLComposer::Formal > ( output ); } } /* namespace alib */ diff --git a/alib2data/src/regexp/formal/FormalRegExpSymbol.h b/alib2data/src/regexp/formal/FormalRegExpSymbol.h index 568770a84a..5847ac8cde 100644 --- a/alib2data/src/regexp/formal/FormalRegExpSymbol.h +++ b/alib2data/src/regexp/formal/FormalRegExpSymbol.h @@ -20,8 +20,8 @@ class FormalRegExpSymbol : public FormalRegExpElement, public std::NullaryNode < alphabet::Symbol symbol; public: - void Accept ( void * userData, const FormalRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( FormalRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit FormalRegExpSymbol ( int number ); // TODO remove these diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h index 7575e133a7..fdccbd1b19 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpAlternation.h @@ -19,8 +19,8 @@ namespace regexp { */ class UnboundedRegExpAlternation : public UnboundedRegExpElement, public std::VararyNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpAlternation > { public: - void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( UnboundedRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit UnboundedRegExpAlternation ( ); diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h index 4703c0b027..f077f872b3 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpConcatenation.h @@ -19,8 +19,8 @@ namespace regexp { */ class UnboundedRegExpConcatenation : public UnboundedRegExpElement, public std::VararyNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpConcatenation > { public: - void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( UnboundedRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit UnboundedRegExpConcatenation ( ); diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h index dbccf48789..cc832c5e5f 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpElement.h @@ -12,6 +12,7 @@ #include "../../alphabet/Symbol.h" #include <set> #include <tree> +#include <core/visitor.hpp> namespace regexp { @@ -31,15 +32,52 @@ class UnboundedRegExpElement : public alib::CommonBase < UnboundedRegExpElement public: class Visitor { public: - virtual void Visit ( void *, const UnboundedRegExpAlternation & ) const = 0; - virtual void Visit ( void *, const UnboundedRegExpConcatenation & ) const = 0; - virtual void Visit ( void *, const UnboundedRegExpIteration & ) const = 0; - virtual void Visit ( void *, const UnboundedRegExpSymbol & ) const = 0; - virtual void Visit ( void *, const UnboundedRegExpEmpty & ) const = 0; - virtual void Visit ( void *, const UnboundedRegExpEpsilon & ) const = 0; + virtual void visit ( const UnboundedRegExpAlternation & ) = 0; + virtual void visit ( const UnboundedRegExpConcatenation & ) = 0; + virtual void visit ( const UnboundedRegExpIteration & ) = 0; + virtual void visit ( const UnboundedRegExpSymbol & ) = 0; + virtual void visit ( const UnboundedRegExpEmpty & ) = 0; + virtual void visit ( const UnboundedRegExpEpsilon & ) = 0; }; - virtual void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const = 0; + template < class ReturnType, class Visitorr, class ... Params > + class VisitorContext : public std::VisitorContextAux < ReturnType, Visitorr, Params ... >, public UnboundedRegExpElement::Visitor { + public: + using std::VisitorContextAux < ReturnType, Visitorr, Params ... >::VisitorContextAux; + + void visit ( const UnboundedRegExpAlternation & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const UnboundedRegExpConcatenation & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const UnboundedRegExpIteration & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const UnboundedRegExpSymbol & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const UnboundedRegExpEmpty & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + + void visit ( const UnboundedRegExpEpsilon & inherit ) override { + this->call ( inherit, std::make_index_sequence < sizeof ... ( Params ) > { } ); + } + }; + + template < class ReturnType, class Visitorr, class ... Params > + ReturnType accept ( Params && ... params ) const { + VisitorContext < ReturnType, Visitorr, Params ... > context ( std::forward < Params > ( params ) ... ); + accept ( context ); + return context.getResult ( ); + } + + virtual void accept ( UnboundedRegExpElement::Visitor & visitor ) const = 0; /** * Creates copy of the element. diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h index 860c16dfb0..cdfec770e2 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEmpty.h @@ -17,8 +17,8 @@ namespace regexp { */ class UnboundedRegExpEmpty : public UnboundedRegExpElement, public std::NullaryNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpSymbol > { public: - void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( UnboundedRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit UnboundedRegExpEmpty ( ); diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h index 24c240d7e7..32b8eeed32 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpEpsilon.h @@ -17,8 +17,8 @@ namespace regexp { */ class UnboundedRegExpEpsilon : public UnboundedRegExpElement, public std::NullaryNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpSymbol > { public: - void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( UnboundedRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit UnboundedRegExpEpsilon ( ); diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h index e6b3d06210..54d9d0b0e0 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpIteration.h @@ -19,8 +19,8 @@ namespace regexp { */ class UnboundedRegExpIteration : public UnboundedRegExpElement, public std::UnaryNode < std::smart_ptr < UnboundedRegExpElement >, std::smart_ptr < const UnboundedRegExpElement >, UnboundedRegExpIteration > { public: - void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( UnboundedRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit UnboundedRegExpIteration ( UnboundedRegExpElement && ); diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp b/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp index dd47bb4a0b..36f1c9ba71 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpStructure.cpp @@ -58,7 +58,7 @@ bool xmlApi < regexp::UnboundedRegExpStructure >::first ( const std::deque < sax } void xmlApi < regexp::UnboundedRegExpStructure >::compose ( std::deque < sax::Token > & output, const regexp::UnboundedRegExpStructure & data ) { - data.getStructure ( ).Accept ( ( void * ) & output, regexp::RegExpToXMLComposer::Unbounded::UNBOUNDED ); + data.getStructure ( ).accept < void, regexp::RegExpToXMLComposer::Unbounded > ( output ); } } /* namespace alib */ diff --git a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h index 013de4c1fe..fdddca278a 100644 --- a/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h +++ b/alib2data/src/regexp/unbounded/UnboundedRegExpSymbol.h @@ -20,8 +20,8 @@ class UnboundedRegExpSymbol : public UnboundedRegExpElement, public std::Nullary alphabet::Symbol symbol; public: - void Accept ( void * userData, const UnboundedRegExpElement::Visitor & visitor ) const { - visitor.Visit ( userData, * this ); + void accept ( UnboundedRegExpElement::Visitor & visitor ) const { + visitor.visit ( * this ); } explicit UnboundedRegExpSymbol ( int number ); diff --git a/alib2str/src/regexp/RegExpToStringComposer.cpp b/alib2str/src/regexp/RegExpToStringComposer.cpp index a0ac860672..2e5aa43494 100644 --- a/alib2str/src/regexp/RegExpToStringComposer.cpp +++ b/alib2str/src/regexp/RegExpToStringComposer.cpp @@ -24,8 +24,7 @@ RegExpToStringComposer::RegistratorWrapper<void, UnboundedRegExp> RegExpToString void RegExpToStringComposer::compose(std::ostream& output, const UnboundedRegExpStructure& regexp) { Priority tmp = Priority::ALTERNATION; std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output); - RegExpToStringComposer composer; - regexp.getStructure().Accept((void*) &out, composer); + regexp.getStructure().accept<void, RegExpToStringComposer::Unbounded > (out); } void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExp& regexp) { @@ -37,17 +36,14 @@ RegExpToStringComposer::RegistratorWrapper<void, FormalRegExp> RegExpToStringCom void RegExpToStringComposer::compose(std::ostream& output, const FormalRegExpStructure& regexp) { Priority tmp = Priority::ALTERNATION; std::tuple<Priority&, std::ostream&> out = std::tie(tmp, output); - RegExpToStringComposer composer; - regexp.getStructure().Accept((void*) &out, composer); + regexp.getStructure().accept<void, RegExpToStringComposer::Formal > (out); } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternation& alternation) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ) { if(alternation.getElements().size() == 0) { std::get<1>(out) << "#0"; } else if(alternation.getElements().size() == 1) { - alternation.getElements()[0]->Accept(userData, *this); + alternation.getElements()[0]->accept<void, RegExpToStringComposer::Unbounded > (out); } else { Priority outerPriorityMinimum = std::get<0>(out); if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; @@ -59,20 +55,18 @@ void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpAlternat std::get<1>(out) << '+'; } std::get<0>(out) = Priority::ALTERNATION; - element->Accept(userData, *this); + element->accept<void, RegExpToStringComposer::Unbounded > (out); } if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcatenation& concatenation) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & out ) { Priority outerPriorityMinimum = std::get<0>(out); if(concatenation.getElements().size() == 0) { std::get<1>(out) << "#E"; } else if(concatenation.getElements().size() == 1) { - concatenation.getElements()[0]->Accept(userData, *this); + concatenation.getElements()[0]->accept<void, RegExpToStringComposer::Unbounded > (out); } else { if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; bool first = true; @@ -83,85 +77,69 @@ void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpConcaten std::get<1>(out) << ' '; } std::get<0>(out) = Priority::CONCATENATION; - element->Accept(userData, *this); + element->accept<void, RegExpToStringComposer::Unbounded > (out); } if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpIteration& iteration) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & out ) { std::get<0>(out) = Priority::FACTOR; - iteration.getElement().Accept(userData, *this); + iteration.getElement().accept<void, RegExpToStringComposer::Unbounded > (out); std::get<1>(out) << "*"; } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpSymbol& symbol) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & out ) { alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol()); } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEpsilon&) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); +void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEpsilon&, std::tuple<Priority&, std::ostream &> & out ) { std::get<1>(out) << "#E"; } -void RegExpToStringComposer::Visit(void* userData, const UnboundedRegExpEmpty&) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); +void RegExpToStringComposer::Unbounded::visit( const UnboundedRegExpEmpty&, std::tuple<Priority&, std::ostream &> & out ) { std::get<1>(out) << "#0"; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpAlternation& alternation) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Formal::visit( const FormalRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ) { Priority outerPriorityMinimum = std::get<0>(out); if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; std::get<0>(out) = Priority::ALTERNATION; - alternation.getLeftElement().Accept(userData, *this); + alternation.getLeftElement().accept<void, RegExpToStringComposer::Formal > (out); std::get<1>(out) << '+'; - alternation.getRightElement().Accept(userData, *this); + alternation.getRightElement().accept<void, RegExpToStringComposer::Formal > (out); if(outerPriorityMinimum == Priority::CONCATENATION || outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpConcatenation& concatenation) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Formal::visit( const FormalRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & out ) { Priority outerPriorityMinimum = std::get<0>(out); if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << '('; std::get<0>(out) = Priority::CONCATENATION; - concatenation.getLeftElement().Accept(userData, *this); + concatenation.getLeftElement().accept<void, RegExpToStringComposer::Formal > (out); std::get<1>(out) << ' '; - concatenation.getRightElement().Accept(userData, *this); + concatenation.getRightElement().accept<void, RegExpToStringComposer::Formal > (out); if(outerPriorityMinimum == Priority::FACTOR) std::get<1>(out) << ')'; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpIteration& iteration) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Formal::visit( const FormalRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & out ) { std::get<0>(out) = Priority::FACTOR; - iteration.getElement().Accept(userData, *this); + iteration.getElement().accept<void, RegExpToStringComposer::Formal > (out); std::get<1>(out) << "*"; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpSymbol& symbol) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); - +void RegExpToStringComposer::Formal::visit( const FormalRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & out ) { alib::stringApi<alphabet::Symbol>::compose(std::get<1>(out), symbol.getSymbol()); } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEpsilon&) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); +void RegExpToStringComposer::Formal::visit( const FormalRegExpEpsilon&, std::tuple<Priority&, std::ostream &> & out ) { std::get<1>(out) << "#E"; } -void RegExpToStringComposer::Visit(void* userData, const FormalRegExpEmpty&) const { - std::tuple<Priority&, std::ostream&> &out = *((std::tuple<Priority&, std::ostream&>*) userData); +void RegExpToStringComposer::Formal::visit( const FormalRegExpEmpty&, std::tuple<Priority&, std::ostream &> & out ) { std::get<1>(out) << "#0"; } diff --git a/alib2str/src/regexp/RegExpToStringComposer.h b/alib2str/src/regexp/RegExpToStringComposer.h index 4d74dbe4fc..6323c8dc2f 100644 --- a/alib2str/src/regexp/RegExpToStringComposer.h +++ b/alib2str/src/regexp/RegExpToStringComposer.h @@ -18,22 +18,8 @@ namespace regexp { -class RegExpToStringComposer : public std::SingleDispatchFirstStaticParam<RegExpToStringComposer, void, std::ostream&, const RegExpBase &>, UnboundedRegExpElement::Visitor, FormalRegExpElement::Visitor { +class RegExpToStringComposer : public std::SingleDispatchFirstStaticParam<RegExpToStringComposer, void, std::ostream&, const RegExpBase &> { private: - void Visit(void*, const UnboundedRegExpAlternation& alternation) const; - void Visit(void*, const UnboundedRegExpConcatenation& concatenation) const; - void Visit(void*, const UnboundedRegExpIteration& iteration) const; - void Visit(void*, const UnboundedRegExpSymbol& symbol) const; - void Visit(void*, const UnboundedRegExpEpsilon& epsilon) const; - void Visit(void*, const UnboundedRegExpEmpty& empty) const; - - void Visit(void*, const FormalRegExpAlternation& alternation) const; - void Visit(void*, const FormalRegExpConcatenation& concatenation) const; - void Visit(void*, const FormalRegExpIteration& iteration) const; - void Visit(void*, const FormalRegExpSymbol& symbol) const; - void Visit(void*, const FormalRegExpEpsilon& epsilon) const; - void Visit(void*, const FormalRegExpEmpty& empty) const; - enum class Priority { ALTERNATION, CONCATENATION, @@ -52,6 +38,26 @@ public: static void compose(std::ostream& out, const UnboundedRegExpStructure& regexp); static void compose(std::ostream& out, const FormalRegExp& regexp); static void compose(std::ostream& out, const FormalRegExpStructure& regexp); + + class Unbounded { + public: + static void visit( const UnboundedRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & out ); + static void visit( const UnboundedRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & output); + static void visit( const UnboundedRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & output); + static void visit( const UnboundedRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & output); + static void visit( const UnboundedRegExpEpsilon& epsilon, std::tuple<Priority&, std::ostream &> & output); + static void visit( const UnboundedRegExpEmpty& empty, std::tuple<Priority&, std::ostream &> & output); + }; + + class Formal { + public: + static void visit( const FormalRegExpAlternation& alternation, std::tuple<Priority&, std::ostream &> & output); + static void visit( const FormalRegExpConcatenation& concatenation, std::tuple<Priority&, std::ostream &> & output); + static void visit( const FormalRegExpIteration& iteration, std::tuple<Priority&, std::ostream &> & output); + static void visit( const FormalRegExpSymbol& symbol, std::tuple<Priority&, std::ostream &> & output); + static void visit( const FormalRegExpEpsilon& epsilon, std::tuple<Priority&, std::ostream &> & output); + static void visit( const FormalRegExpEmpty& empty, std::tuple<Priority&, std::ostream &> & output); + }; }; } /* namespace regexp */ -- GitLab