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