From 3fac516b8e8016c6226c5b8f10dac8fb7f4e4d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Fri, 12 Sep 2014 19:34:19 +0200 Subject: [PATCH] algo: re deriv: API, leaks --- aderivation2/src/aderivation.cpp | 19 ++-- alib2algo/src/regexp/RegExpDerivation.cpp | 104 +++++++++++++--------- alib2algo/src/regexp/RegExpDerivation.h | 49 +++++----- examples2/string/linear.xml | 12 +++ 4 files changed, 117 insertions(+), 67 deletions(-) create mode 100644 examples2/string/linear.xml diff --git a/aderivation2/src/aderivation.cpp b/aderivation2/src/aderivation.cpp index e3dce5733e..a4eb0bb26d 100644 --- a/aderivation2/src/aderivation.cpp +++ b/aderivation2/src/aderivation.cpp @@ -1,5 +1,5 @@ /* - * aintegral.cpp + * aderivation.cpp * * Created on: 19. 1. 2014 * Author: Tomas Pecka @@ -23,16 +23,25 @@ int main(int argc, char** argv) return -1; } + if(argc == 2) + { + regexp::RegExp regexp = alib::DataFactory::fromStdin<regexp::RegExp>(); + string::LinearString* string = static_cast<string::LinearString*>(std::move(alib::DataFactory::fromFile<string::LinearString>(argv[1])).plunder()); + alib::DataFactory::toStdout(regexp::RegExpDerivation::derivation(regexp, *string)); + delete string; + return 0; + } + if(argc == 3) { regexp::RegExp regexp = alib::DataFactory::fromFile<regexp::RegExp>(argv[1]); string::LinearString* string = static_cast<string::LinearString*>(std::move(alib::DataFactory::fromFile<string::LinearString>(argv[2])).plunder()); - - regexp::RegExpDerivation derive; - alib::DataFactory::toStdout(derive.derivation(regexp, *string)); - + alib::DataFactory::toStdout(regexp::RegExpDerivation::derivation(regexp, *string)); + delete string; return 0; } + + return -1; } catch(const exception::AlibException& exception) { diff --git a/alib2algo/src/regexp/RegExpDerivation.cpp b/alib2algo/src/regexp/RegExpDerivation.cpp index 819a6f9055..3c168fcc51 100644 --- a/alib2algo/src/regexp/RegExpDerivation.cpp +++ b/alib2algo/src/regexp/RegExpDerivation.cpp @@ -10,35 +10,66 @@ namespace regexp { -RegExpDerivation::RegExpDerivation(){} -RegExpDerivation::~RegExpDerivation(){} - regexp::RegExp RegExpDerivation::derivation(const regexp::RegExp& regexp, const string::LinearString& string) { - std::pair<regexp::RegExp, string::LinearString> out(regexp, string); - regexp.getData().Accept((void*) &out, *this); - return out.first; + std::pair<regexp::RegExp*, const string::LinearString> out(nullptr, string); + regexp.getData().Accept((void*) &out, RegExpDerivation::REGEXP_DERIVATION); + regexp::RegExp res = std::move(*(out.first)); + delete out.first; + return res; } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) +regexp::FormalRegExp RegExpDerivation::derivation(const regexp::FormalRegExp& regexp, const string::LinearString& string) { - std::pair<regexp::RegExp, string::LinearString> &ret = *(std::pair<regexp::RegExp, string::LinearString>*) userData; - const regexp::FormalRegExpElement* newRegExp = regexp.getRegExp().clone(); - for(const auto& symbol : ret.second.getContent()) + for(const auto& symbol : string.getContent()) { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> out(symbol, nullptr); - newRegExp->Accept((void*) &out, *this); + newRegExp->Accept((void*) &out, RegExpDerivation::REGEXP_DERIVATION); delete newRegExp; newRegExp = out.second; } - ret.first = regexp::RegExp{regexp::FormalRegExp(std::move(*newRegExp))}; + regexp::FormalRegExp res(std::move(*newRegExp)); delete newRegExp; + return res; +} + +regexp::UnboundedRegExp RegExpDerivation::derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString& string) +{ + const regexp::UnboundedRegExpElement* newRegExp = regexp.getRegExp().clone(); + + for(const auto& symbol : string.getContent()) + { + std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> out(symbol, nullptr); + newRegExp->Accept((void*) &out, RegExpDerivation::REGEXP_DERIVATION); + delete newRegExp; + newRegExp = out.second; + } + + regexp::UnboundedRegExp res(std::move(*newRegExp)); + delete newRegExp; + return res; +} + +// ---------------------------------------------------------------------------- + +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExp& regexp) const +{ + std::pair<regexp::RegExp*, const string::LinearString>& out = *((std::pair<regexp::RegExp*, const string::LinearString>*) userData); + out.first = new regexp::RegExp(this->derivation(regexp, out.second)); } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) const +{ + std::pair<regexp::RegExp*, const string::LinearString>& out = *((std::pair<regexp::RegExp*, const string::LinearString>*) userData); + out.first = new regexp::RegExp(this->derivation(regexp, out.second)); +} + +// ---------------------------------------------------------------------------- + +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpAlternation& alternation) const { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::FormalRegExpElement*>*) userData); @@ -53,7 +84,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpAlternati delete rightDerivative; } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatenation& concatenation) const { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::FormalRegExpElement*>*) userData); @@ -76,7 +107,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpConcatena } } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpIteration& iteration) const { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::FormalRegExpElement*>*) userData); @@ -89,7 +120,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpIteration delete iter; } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpSymbol& symbol) const { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::FormalRegExpElement*>*) userData); @@ -100,37 +131,22 @@ void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpSymbol& s } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpEpsilon&) +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpEpsilon&) const { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::FormalRegExpElement*>*) userData); out.second = new regexp::FormalRegExpEmpty(); } -void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpEmpty&) +void RegExpDerivation::Visit(void* userData, const regexp::FormalRegExpEmpty&) const { std::pair<alphabet::Symbol, regexp::FormalRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::FormalRegExpElement*>*) userData); out.second = new regexp::FormalRegExpEmpty(); } -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExp& regexp) -{ - std::pair<regexp::RegExp, string::LinearString> &ret = *(std::pair<regexp::RegExp, string::LinearString>*) userData; +// ---------------------------------------------------------------------------- - const regexp::UnboundedRegExpElement* newRegExp = regexp.getRegExp().clone(); - for(const auto& symbol : ret.second.getContent()) - { - std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> out(symbol, nullptr); - newRegExp->Accept((void*) &out, *this); - delete newRegExp; - newRegExp = out.second; - } - - ret.first = regexp::RegExp{regexp::UnboundedRegExp(std::move(*newRegExp))}; - delete newRegExp; -} - -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpAlternation& alternation) const { std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*>*) userData); regexp::UnboundedRegExpAlternation* ret = new regexp::UnboundedRegExpAlternation(); @@ -145,7 +161,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpAltern out.second = ret; } -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcatenation& concatenation) const { std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*>*) userData); regexp::UnboundedRegExpAlternation* ret = new regexp::UnboundedRegExpAlternation(); @@ -159,7 +175,11 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat auto succeedingElement = child; while(++succeedingElement != concatenation.getElements().end()) - concat->appendElement(std::move(*(*succeedingElement)->clone())); + { + regexp::UnboundedRegExpElement* tmp = (*succeedingElement)->clone(); + concat->appendElement(std::move(*tmp)); + delete tmp; + } ret->appendElement(std::move(*concat)); delete concat; @@ -172,7 +192,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpConcat out.second = ret; } -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpIteration& iteration) const { std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*>*) userData); @@ -189,7 +209,7 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpIterat out.second = ret; } -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpSymbol& symbol) const { std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*>*) userData); @@ -199,16 +219,18 @@ void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpSymbol out.second = new regexp::UnboundedRegExpEmpty(); } -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpEpsilon&) const { std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*>*) userData); out.second = new regexp::UnboundedRegExpEmpty(); } -void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) +void RegExpDerivation::Visit(void* userData, const regexp::UnboundedRegExpEmpty&) const { std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*> &out = *((std::pair<alphabet::Symbol, regexp::UnboundedRegExpElement*>*) userData); out.second = new regexp::UnboundedRegExpEmpty(); } +const RegExpDerivation RegExpDerivation::REGEXP_DERIVATION; + } /* namespace regexp */ diff --git a/alib2algo/src/regexp/RegExpDerivation.h b/alib2algo/src/regexp/RegExpDerivation.h index 6c34809732..a9efd8b1f6 100644 --- a/alib2algo/src/regexp/RegExpDerivation.h +++ b/alib2algo/src/regexp/RegExpDerivation.h @@ -13,7 +13,6 @@ #include <regexp/unbounded/UnboundedRegExpElements.h> #include <string/LinearString.h> -#include <string/StringBase.h> namespace regexp { @@ -25,30 +24,38 @@ namespace regexp * - Melichar, definition 2.91 in chapter 2.4.3 * - Brzozowski, J. A. - Derivatives of regular expressions (1964) */ -class RegExpDerivation : public regexp::VisitableRegExpBase::visitor_type, regexp::FormalRegExpElement::visitor_type, regexp::UnboundedRegExpElement::visitor_type +class RegExpDerivation : public regexp::VisitableRegExpBase::const_visitor_type, regexp::FormalRegExpElement::const_visitor_type, regexp::UnboundedRegExpElement::const_visitor_type { public: - RegExpDerivation(); - ~RegExpDerivation(); - regexp::RegExp derivation(const regexp::RegExp& regexp, const string::LinearString& string); + /** + * @param regexp RegExp to derivate + * @param string String to derivate given RegExp over + * @return derivative of regexp + */ + static regexp::RegExp derivation(const regexp::RegExp& regexp, const string::LinearString& string); + + static regexp::FormalRegExp derivation(const regexp::FormalRegExp& regexp, const string::LinearString& string); + static regexp::UnboundedRegExp derivation(const regexp::UnboundedRegExp& regexp, const string::LinearString& string); private: - 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); - 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); - - void Visit(void*, const regexp::UnboundedRegExp& empty); - void Visit(void*, const regexp::FormalRegExp& empty); + void Visit(void*, const regexp::FormalRegExp& empty) const; + void Visit(void*, const regexp::UnboundedRegExp& empty) const; + + 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::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 const RegExpDerivation REGEXP_DERIVATION; }; } /* namespace regexp */ diff --git a/examples2/string/linear.xml b/examples2/string/linear.xml new file mode 100644 index 0000000000..253da38c05 --- /dev/null +++ b/examples2/string/linear.xml @@ -0,0 +1,12 @@ +<?xml version="1.0"?> +<LinearString> + <alphabet> + <LabeledSymbol><StringLabel>1</StringLabel></LabeledSymbol> + <LabeledSymbol><StringLabel>2</StringLabel></LabeledSymbol> + <LabeledSymbol><StringLabel>3</StringLabel></LabeledSymbol> + </alphabet> + <LabeledSymbol><StringLabel>1</StringLabel></LabeledSymbol> + <LabeledSymbol><StringLabel>2</StringLabel></LabeledSymbol> + <LabeledSymbol><StringLabel>1</StringLabel></LabeledSymbol> +</LinearString> + -- GitLab