From 9d34022924aaa0a18c02e48ca899c996bc3cdf16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Thu, 18 Sep 2014 20:23:08 +0200 Subject: [PATCH] algo: Thompson API --- aconversions2/src/ConversionHandler.cpp | 3 +- alib2algo/src/conversions/re2fa/Thompson.cpp | 348 ++++++++++--------- alib2algo/src/conversions/re2fa/Thompson.h | 50 +-- 3 files changed, 207 insertions(+), 194 deletions(-) diff --git a/aconversions2/src/ConversionHandler.cpp b/aconversions2/src/ConversionHandler.cpp index d523dced31..150544a0c7 100644 --- a/aconversions2/src/ConversionHandler.cpp +++ b/aconversions2/src/ConversionHandler.cpp @@ -208,8 +208,7 @@ void ConversionHandler::convertREtoFSM( void ) break; } case THOMPSON_NFA: { - conversions::re2fa::Thompson conv; - alib::DataFactory::toStdout(conv.convert(regexp)); + alib::DataFactory::toStdout(conversions::re2fa::Thompson::convert(regexp)); break; } case GLUSHKOV_NFA: diff --git a/alib2algo/src/conversions/re2fa/Thompson.cpp b/alib2algo/src/conversions/re2fa/Thompson.cpp index 48b8abedc3..092f08422b 100644 --- a/alib2algo/src/conversions/re2fa/Thompson.cpp +++ b/alib2algo/src/conversions/re2fa/Thompson.cpp @@ -2,11 +2,10 @@ * Thompson.cpp * * Created on: 11. 1. 2014 - * Author: tomas + * Author: Tomas Pecka */ #include "Thompson.h" #include <tuple> -#include <automaton/Automaton.h> namespace conversions { @@ -14,252 +13,263 @@ namespace conversions namespace re2fa { -Thompson::Thompson(void){} -Thompson::~Thompson(void){} - automaton::EpsilonNFA Thompson::convert(const regexp::RegExp& regexp) { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> out(automaton::EpsilonNFA(), 0, nullptr, nullptr); - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA* out = NULL; + regexp.getData().Accept((void*) &out, Thompson::THOMPSON); + automaton::EpsilonNFA res = std::move(*out); + delete out; + return res; +} + +template<class T> +automaton::EpsilonNFA Thompson::convert(const T& regexp) +{ + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> out(automaton::EpsilonNFA(), 0, nullptr, nullptr); - regexp.getData().Accept((void*) &out, *this); + automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton.setInputSymbols(regexp.getAlphabet()); - automaton.setInitialStates({*std::get<2>(out)}); - automaton.setFinalStates(std::set<automaton::State>{*std::get<3>(out)}); + regexp.getRegExp().Accept((void*) &out, Thompson::THOMPSON); - return std::get<0>(out); + automaton.setInitialStates({*std::get<2>(out)}); + automaton.setFinalStates(std::set<automaton::State>{*std::get<3>(out)}); + + return automaton; } -void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) +// ---------------------------------------------------------------------------- + +void Thompson::Visit(void* userData, const regexp::FormalRegExp& regexp) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData); + out = new automaton::EpsilonNFA(this->convert(regexp)); +} - automaton.setInputSymbols(regexp.getAlphabet()); - regexp.getRegExp().Accept((void*) &out, *this); +void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + automaton::EpsilonNFA* & out = *((automaton::EpsilonNFA**) userData); + out = new automaton::EpsilonNFA(this->convert(regexp)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) +// ---------------------------------------------------------------------------- + +void Thompson::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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); + 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); - 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); + 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); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) +void Thompson::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA& automaton = std::get<0>(out); - static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(userData, *this); - const automaton::State* leftHead = std::get<2>(out); - const automaton::State* leftTail = std::get<3>(out); + static_cast<const regexp::FormalRegExpElement&>(concatenation.getLeftElement()).Accept(userData, *this); + const automaton::State* leftHead = std::get<2>(out); + const automaton::State* leftTail = std::get<3>(out); - static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this); - automaton.addTransition(*leftTail, string::Epsilon::EPSILON, *std::get<2>(out)); + static_cast<const regexp::FormalRegExpElement&>(concatenation.getRightElement()).Accept(userData, *this); + automaton.addTransition(*leftTail, string::Epsilon::EPSILON, *std::get<2>(out)); - std::get<2>(out) = &(*automaton.getStates().find(*leftHead)); - // std::get<3>(out) = std::get<3>(out); + std::get<2>(out) = &(*automaton.getStates().find(*leftHead)); + // std::get<3>(out) = std::get<3>(out); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) +void Thompson::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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)); - 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)); + static_cast<const regexp::FormalRegExpElement&>(iteration.getElement()).Accept(userData, *this); + automaton.addTransition(head, string::Epsilon::EPSILON, *std::get<2>(out)); + 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)); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) +void Thompson::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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)); + automaton.addTransition(head, symbol.getSymbol(), tail); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) +void Thompson::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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)); + automaton.addTransition(head, string::Epsilon::EPSILON, tail); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) +void Thompson::Visit(void* userData, const regexp::FormalRegExpEmpty&) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State tail = automaton::State(std::get<1>(out)++); + automaton.addState(head); + automaton.addState(tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExp& regexp) -{ - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); - - automaton.setInputSymbols(regexp.getAlphabet()); - regexp.getRegExp().Accept((void*) &out, *this); -} +// ---------------------------------------------------------------------------- -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) +void Thompson::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); - - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - 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); - } - - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); + + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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); + } + + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) +void Thompson::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); - std::vector<std::pair<const automaton::State*, const automaton::State*>> 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))); - } + std::vector<std::pair<const automaton::State*, const automaton::State*>> 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(size_t i = 1; i < tails.size(); i++) - automaton.addTransition(*tails[i-1].second, string::Epsilon::EPSILON, *tails[i].first); + 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; + std::get<2>(out) = tails[0].first; + std::get<3>(out) = tails[tails.size()-1].second; } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) +void Thompson::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); - - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - 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)); - 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)); - - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); + + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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)); + 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)); + + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) +void Thompson::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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)); + automaton.addTransition(head, symbol.getSymbol(), tail); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) +void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + 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)); + automaton.addTransition(head, string::Epsilon::EPSILON, tail); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } -void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) +void Thompson::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const { - std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; - automaton::EpsilonNFA& automaton = std::get<0>(out); + std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*> &out = *(std::tuple<automaton::EpsilonNFA, int, const automaton::State*, const automaton::State*>*) userData; + automaton::EpsilonNFA& automaton = std::get<0>(out); - automaton::State head = automaton::State(std::get<1>(out)++); - automaton::State tail = automaton::State(std::get<1>(out)++); - automaton.addState(head); - automaton.addState(tail); + automaton::State head = automaton::State(std::get<1>(out)++); + automaton::State tail = automaton::State(std::get<1>(out)++); + automaton.addState(head); + automaton.addState(tail); - std::get<2>(out) = &(*automaton.getStates().find(head)); - std::get<3>(out) = &(*automaton.getStates().find(tail)); + std::get<2>(out) = &(*automaton.getStates().find(head)); + std::get<3>(out) = &(*automaton.getStates().find(tail)); } +const Thompson Thompson::THOMPSON; + } /* namespace re2fa */ } /* namespace conversions */ diff --git a/alib2algo/src/conversions/re2fa/Thompson.h b/alib2algo/src/conversions/re2fa/Thompson.h index 6b82bc9a7a..d3365ec0b9 100644 --- a/alib2algo/src/conversions/re2fa/Thompson.h +++ b/alib2algo/src/conversions/re2fa/Thompson.h @@ -2,7 +2,7 @@ * Thompson.h * * Created on: 11. 1. 2014 - * Author: tomas + * Author: Tomas Pecka */ #ifndef THOMPSON_H_ @@ -27,34 +27,38 @@ namespace re2fa * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.21.7450&rep=rep1&type=ps * Melichar 2.112 */ -class Thompson : public regexp::VisitableRegExpBase::visitor_type, regexp::FormalRegExpElement::visitor_type, regexp::UnboundedRegExpElement::visitor_type +class Thompson : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type { public: - /** - * Performs conversion. - * @return nondeterministic finite automaton with epsilon transitions accepting language described by the regexp - */ - Thompson(void); - ~Thompson(void); - automaton::EpsilonNFA convert(const regexp::RegExp& regexp); + /** + * Performs conversion. + * @param regexp regexp to convert + * @return nondeterministic finite automaton with epsilon transitions accepting language described by the regexp + */ + static automaton::EpsilonNFA convert(const regexp::RegExp& regexp); + + template<class T> + static automaton::EpsilonNFA convert(const T& regexp); private: - void Visit(void*, const regexp::UnboundedRegExp& regexp); - void Visit(void*, const regexp::FormalRegExp& regexp); + void Visit(void*, const regexp::UnboundedRegExp& regexp) const; + void Visit(void*, const regexp::FormalRegExp& regexp) const; + + 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; - void Visit(void*, const regexp::UnboundedRegExpAlternation& alternation); - void Visit(void*, const regexp::UnboundedRegExpConcatenation& concatenation); - void Visit(void*, const regexp::UnboundedRegExpIteration& iteration); - void Visit(void*, const regexp::UnboundedRegExpSymbol& symbol); - void Visit(void*, const regexp::UnboundedRegExpEpsilon& epsilon); - void Visit(void*, const regexp::UnboundedRegExpEmpty& empty); + 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; - void Visit(void*, const regexp::FormalRegExpAlternation& alternation); - void Visit(void*, const regexp::FormalRegExpConcatenation& concatenation); - void Visit(void*, const regexp::FormalRegExpIteration& iteration); - void Visit(void*, const regexp::FormalRegExpSymbol& symbol); - void Visit(void*, const regexp::FormalRegExpEpsilon& epsilon); - void Visit(void*, const regexp::FormalRegExpEmpty& empty); + static const Thompson THOMPSON; }; } /* namespace re2fa */ -- GitLab