From e00e1c428305248b75bc5eace78b1efdb7d19f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Fri, 7 Mar 2014 20:10:42 +0100 Subject: [PATCH] RegExp::isEmpty is now correct if called on unoptimized regexp. closes #15 --- alib/src/regexp/Alternation.cpp | 8 ++++++++ alib/src/regexp/Alternation.h | 5 +++++ alib/src/regexp/Concatenation.cpp | 10 +++++++++- alib/src/regexp/Concatenation.h | 5 +++++ alib/src/regexp/Iteration.cpp | 4 ++++ alib/src/regexp/Iteration.h | 5 +++++ alib/src/regexp/RegExp.cpp | 2 +- alib/src/regexp/RegExpElement.h | 5 +++++ alib/src/regexp/RegExpEmpty.cpp | 4 ++++ alib/src/regexp/RegExpEmpty.h | 5 +++++ alib/src/regexp/RegExpEpsilon.cpp | 4 ++++ alib/src/regexp/RegExpEpsilon.h | 5 +++++ alib/src/regexp/RegExpSymbol.cpp | 4 ++++ alib/src/regexp/RegExpSymbol.h | 7 ++++++- 14 files changed, 70 insertions(+), 3 deletions(-) diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp index 1c557224ef..81ff4f56fa 100644 --- a/alib/src/regexp/Alternation.cpp +++ b/alib/src/regexp/Alternation.cpp @@ -106,5 +106,13 @@ bool Alternation::containsEmptyString() const { return false; } +bool Alternation::isEmpty() const { + for(const auto& e : getElements()) + if(!e->isEmpty()) + return true; + + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Alternation.h b/alib/src/regexp/Alternation.h index 52b8f8c184..e01aac375c 100644 --- a/alib/src/regexp/Alternation.h +++ b/alib/src/regexp/Alternation.h @@ -55,6 +55,11 @@ public: * @copydoc RegExpElement::containsEmptyString() const */ bool containsEmptyString() const; + + /** + * @copydoc RegExpElement::isEmpty() const + */ + bool isEmpty() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.cpp b/alib/src/regexp/Concatenation.cpp index c43e767dfd..602ebde3c8 100644 --- a/alib/src/regexp/Concatenation.cpp +++ b/alib/src/regexp/Concatenation.cpp @@ -95,11 +95,19 @@ bool Concatenation::operator==(const Concatenation& other) const { } bool Concatenation::containsEmptyString() const { - for( const auto& e : getElements()) + for(const auto& e : getElements()) if( ! e->containsEmptyString()) return false; return true; } +bool Concatenation::isEmpty() const { + for(const auto& e : getElements()) + if(!e->isEmpty()) + return false; + + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.h b/alib/src/regexp/Concatenation.h index 9fead277d3..55b465ed9a 100644 --- a/alib/src/regexp/Concatenation.h +++ b/alib/src/regexp/Concatenation.h @@ -54,6 +54,11 @@ public: * @copydoc RegExpElement::containsEmptyString() const */ bool containsEmptyString() const; + + /** + * @copydoc RegExpElement::isEmpty() const + */ + bool isEmpty() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/Iteration.cpp b/alib/src/regexp/Iteration.cpp index 85e68a1025..3495f4a6bc 100644 --- a/alib/src/regexp/Iteration.cpp +++ b/alib/src/regexp/Iteration.cpp @@ -97,5 +97,9 @@ bool Iteration::containsEmptyString() const { return true; } +bool Iteration::isEmpty() const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Iteration.h b/alib/src/regexp/Iteration.h index 7466b2aedc..f7b755113c 100644 --- a/alib/src/regexp/Iteration.h +++ b/alib/src/regexp/Iteration.h @@ -62,6 +62,11 @@ public: * @copydoc RegExpElement::containsEmptyString() const */ bool containsEmptyString() const; + + /** + * @copydoc RegExpElement::isEmpty() const + */ + bool isEmpty() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExp.cpp b/alib/src/regexp/RegExp.cpp index 2200f3999f..246a5ee7eb 100644 --- a/alib/src/regexp/RegExp.cpp +++ b/alib/src/regexp/RegExp.cpp @@ -71,7 +71,7 @@ void RegExp::setRegExp(RegExpElement* regExp) { } bool RegExp::isEmpty() const { - return regExp == NULL || dynamic_cast<const RegExpEmpty*>(regExp); + return regExp == NULL || regExp->isEmpty(); } bool RegExp::containsEmptyString() const { diff --git a/alib/src/regexp/RegExpElement.h b/alib/src/regexp/RegExpElement.h index 69421fde01..58fe62bab1 100644 --- a/alib/src/regexp/RegExpElement.h +++ b/alib/src/regexp/RegExpElement.h @@ -59,6 +59,11 @@ public: * @return true if this subtree of regexp matches empty string (epsilon) */ virtual bool containsEmptyString() const = 0; + + /** + * @return true if this subtree describes empty language + */ + virtual bool isEmpty() const = 0; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEmpty.cpp b/alib/src/regexp/RegExpEmpty.cpp index f7b5ad4f95..553cfd650f 100644 --- a/alib/src/regexp/RegExpEmpty.cpp +++ b/alib/src/regexp/RegExpEmpty.cpp @@ -57,5 +57,9 @@ bool RegExpEmpty::containsEmptyString() const { return false; } +bool RegExpEmpty::isEmpty() const { + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEmpty.h b/alib/src/regexp/RegExpEmpty.h index 7fb80a8935..3578afa59f 100644 --- a/alib/src/regexp/RegExpEmpty.h +++ b/alib/src/regexp/RegExpEmpty.h @@ -41,6 +41,11 @@ public: * @copydoc RegExpElement::containsEmptyString() const */ bool containsEmptyString() const; + + /** + * @copydoc RegExpElement::isEmpty() const + */ + bool isEmpty() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEpsilon.cpp b/alib/src/regexp/RegExpEpsilon.cpp index ff8fbb4b12..e102539f5f 100644 --- a/alib/src/regexp/RegExpEpsilon.cpp +++ b/alib/src/regexp/RegExpEpsilon.cpp @@ -53,5 +53,9 @@ bool RegExpEpsilon::containsEmptyString() const { return true; } +bool RegExpEpsilon::isEmpty() const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEpsilon.h b/alib/src/regexp/RegExpEpsilon.h index a7dced2eaf..28b8a6c0a4 100644 --- a/alib/src/regexp/RegExpEpsilon.h +++ b/alib/src/regexp/RegExpEpsilon.h @@ -42,6 +42,11 @@ public: * @copydoc RegExpElement::containsEmptyString() const */ bool containsEmptyString() const; + + /** + * @copydoc RegExpElement::isEmpty() const + */ + bool isEmpty() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpSymbol.cpp b/alib/src/regexp/RegExpSymbol.cpp index 66b85aed26..f71609fc71 100644 --- a/alib/src/regexp/RegExpSymbol.cpp +++ b/alib/src/regexp/RegExpSymbol.cpp @@ -58,6 +58,10 @@ bool RegExpSymbol::containsEmptyString() const { return false; } +bool RegExpSymbol::isEmpty() const { + return false; +} + const string& RegExpSymbol::getSymbol() const { return this->symbol; } diff --git a/alib/src/regexp/RegExpSymbol.h b/alib/src/regexp/RegExpSymbol.h index 77d24348e9..54e1b618aa 100644 --- a/alib/src/regexp/RegExpSymbol.h +++ b/alib/src/regexp/RegExpSymbol.h @@ -46,8 +46,13 @@ public: * @copydoc RegExpElement::containsEmptyString() const */ bool containsEmptyString() const; - + const string& getSymbol() const; + + /** + * @copydoc RegExpElement::isEmpty() const + */ + bool isEmpty() const; }; } /* namespace regexp */ -- GitLab