From eff95ec84b019fb31b2f28ba3b0cbb86b3c39983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <peckato1@fit.cvut.cz> Date: Sat, 22 Feb 2014 21:31:09 +0100 Subject: [PATCH] alib: regexp - method to check if epsilon is in language described by regexp Conflicts: alib/src/regexp/Alternation.cpp alib/src/regexp/Alternation.h alib/src/regexp/Concatenation.cpp alib/src/regexp/Concatenation.h alib/src/regexp/Iteration.cpp alib/src/regexp/Iteration.h alib/src/regexp/RegExpElement.h alib/src/regexp/RegExpEmpty.cpp alib/src/regexp/RegExpEmpty.h alib/src/regexp/RegExpEpsilon.cpp alib/src/regexp/RegExpEpsilon.h alib/src/regexp/RegExpSymbol.cpp alib/src/regexp/RegExpSymbol.h --- alib/src/regexp/Alternation.cpp | 20 ++++++++++++++------ alib/src/regexp/Alternation.h | 9 +++++++-- alib/src/regexp/Concatenation.cpp | 20 ++++++++++++++------ alib/src/regexp/Concatenation.h | 6 +++++- alib/src/regexp/Iteration.cpp | 7 +++++-- alib/src/regexp/Iteration.h | 8 ++++++-- alib/src/regexp/RegExp.cpp | 7 +++++++ alib/src/regexp/RegExp.h | 5 +++++ alib/src/regexp/RegExpElement.cpp | 1 + alib/src/regexp/RegExpElement.h | 16 ++++++++++------ alib/src/regexp/RegExpEmpty.cpp | 4 ++++ alib/src/regexp/RegExpEmpty.h | 7 ++++++- alib/src/regexp/RegExpEpsilon.cpp | 6 +++++- alib/src/regexp/RegExpEpsilon.h | 7 ++++++- alib/src/regexp/RegExpSymbol.cpp | 4 ++++ alib/src/regexp/RegExpSymbol.h | 9 +++++++-- 16 files changed, 106 insertions(+), 30 deletions(-) diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp index 23e5ed7409..2284faced6 100644 --- a/alib/src/regexp/Alternation.cpp +++ b/alib/src/regexp/Alternation.cpp @@ -76,25 +76,25 @@ bool Alternation::operator<(const Alternation& other) const { int otherSize = other.elements.size(); if(thisSize < otherSize) return true; if(thisSize > otherSize) return false; - + auto thisIter = this->elements.begin(); auto otherIter = other.elements.begin(); for(; thisIter != this->elements.end(); thisIter++, otherIter++) { if(**thisIter < **otherIter) return true; } - + return false; } bool Alternation::operator==(const Alternation& other) const { if(this->elements.size() != other.elements.size()) return false; - + auto thisIter = this->elements.begin(); auto otherIter = other.elements.begin(); for(; thisIter != this->elements.end(); thisIter++, otherIter++) { if(**thisIter != **otherIter) return false; } - + return true; } @@ -103,13 +103,13 @@ bool Alternation::operator>(const Alternation& other) const { int otherSize = other.elements.size(); if(thisSize < otherSize) return false; if(thisSize > otherSize) return true; - + auto thisIter = this->elements.begin(); auto otherIter = other.elements.begin(); for(; thisIter != this->elements.end(); thisIter++, otherIter++) { if(**thisIter > **otherIter) return true; } - + return false; } @@ -129,5 +129,13 @@ bool Alternation::operator>(const RegExpEmpty&) const { return true; } +bool Alternation::containsEmptyString() const { + for(const auto& e : getElements()) + if(e->containsEmptyString()) + return true; + + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Alternation.h b/alib/src/regexp/Alternation.h index 20c154d766..cfeb34d639 100644 --- a/alib/src/regexp/Alternation.h +++ b/alib/src/regexp/Alternation.h @@ -42,11 +42,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() const; - + virtual bool operator<(const RegExpElement&) const; virtual bool operator==(const RegExpElement&) const; virtual bool operator>(const RegExpElement&) const; - + virtual bool operator<(const Concatenation&) const; virtual bool operator<(const Alternation&) const; virtual bool operator==(const Alternation&) const; @@ -55,6 +55,11 @@ public: virtual bool operator>(const RegExpSymbol&) const; virtual bool operator>(const RegExpEpsilon&) const; virtual bool operator>(const RegExpEmpty&) const; + + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.cpp b/alib/src/regexp/Concatenation.cpp index 983e1e2e6b..395f02a4d6 100644 --- a/alib/src/regexp/Concatenation.cpp +++ b/alib/src/regexp/Concatenation.cpp @@ -72,25 +72,25 @@ bool Concatenation::operator<(const Concatenation& other) const { int otherSize = other.elements.size(); if(thisSize < otherSize) return true; if(thisSize > otherSize) return false; - + auto thisIter = this->elements.begin(); auto otherIter = other.elements.begin(); for(; thisIter != this->elements.end(); thisIter++, otherIter++) { if(**thisIter < **otherIter) return true; } - + return false; } bool Concatenation::operator==(const Concatenation& other) const { if(this->elements.size() != other.elements.size()) return false; - + auto thisIter = this->elements.begin(); auto otherIter = other.elements.begin(); for(; thisIter != this->elements.end(); thisIter++, otherIter++) { if(**thisIter != **otherIter) return false; } - + return true; } @@ -99,13 +99,13 @@ bool Concatenation::operator>(const Concatenation& other) const { int otherSize = other.elements.size(); if(thisSize < otherSize) return false; if(thisSize > otherSize) return true; - + auto thisIter = this->elements.begin(); auto otherIter = other.elements.begin(); for(; thisIter != this->elements.end(); thisIter++, otherIter++) { if(**thisIter > **otherIter) return true; } - + return false; } @@ -129,4 +129,12 @@ bool Concatenation::operator>(const RegExpEmpty&) const { return true; } +bool Concatenation::containsEmptyString() const { + for( const auto& e : getElements()) + if( ! e->containsEmptyString()) + return false; + + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Concatenation.h b/alib/src/regexp/Concatenation.h index 4df5512342..e35d05eac2 100644 --- a/alib/src/regexp/Concatenation.h +++ b/alib/src/regexp/Concatenation.h @@ -46,7 +46,7 @@ public: virtual bool operator<(const RegExpElement&) const; virtual bool operator==(const RegExpElement&) const; virtual bool operator>(const RegExpElement&) const; - + virtual bool operator<(const Concatenation&) const; virtual bool operator==(const Concatenation&) const; virtual bool operator>(const Concatenation&) const; @@ -56,6 +56,10 @@ public: virtual bool operator>(const RegExpEpsilon&) const; virtual bool operator>(const RegExpEmpty&) const; + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/Iteration.cpp b/alib/src/regexp/Iteration.cpp index 8126596a4c..399a3ee371 100644 --- a/alib/src/regexp/Iteration.cpp +++ b/alib/src/regexp/Iteration.cpp @@ -65,7 +65,6 @@ RegExpElement* Iteration::clone() const { return new Iteration(*this); } - bool Iteration::operator<(const RegExpElement& other) const { return !(other > *this || other == *this); } @@ -77,7 +76,7 @@ bool Iteration::operator==(const RegExpElement& other) const { bool Iteration::operator>(const RegExpElement& other) const { return !(other < *this || other == *this); } - + bool Iteration::operator<(const Concatenation&) const { return true; } @@ -110,5 +109,9 @@ bool Iteration::operator>(const RegExpEmpty&) const { return true; } +bool Iteration::containsEmptyString() const { + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Iteration.h b/alib/src/regexp/Iteration.h index 7f5c23cbb0..ab34a89deb 100644 --- a/alib/src/regexp/Iteration.h +++ b/alib/src/regexp/Iteration.h @@ -48,11 +48,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() const; - + virtual bool operator<(const RegExpElement&) const; virtual bool operator==(const RegExpElement&) const; virtual bool operator>(const RegExpElement&) const; - + virtual bool operator<(const Concatenation&) const; virtual bool operator<(const Alternation&) const; virtual bool operator<(const Iteration&) const; @@ -62,6 +62,10 @@ public: virtual bool operator>(const RegExpEpsilon&) const; virtual bool operator>(const RegExpEmpty&) const; + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExp.cpp b/alib/src/regexp/RegExp.cpp index b35657c0d9..65b63e54a0 100644 --- a/alib/src/regexp/RegExp.cpp +++ b/alib/src/regexp/RegExp.cpp @@ -74,6 +74,13 @@ bool RegExp::isEmpty() const { return regExp == NULL || dynamic_cast<const RegExpEmpty*>(regExp); } +bool RegExp::containsEmptyString() const { + if(regExp) + return regExp->containsEmptyString(); + + return false; +} + void RegExp::toXML(ostream& out) { RegExpPrinter::toXML(*this, out); } diff --git a/alib/src/regexp/RegExp.h b/alib/src/regexp/RegExp.h index e31198ae94..def92709e7 100644 --- a/alib/src/regexp/RegExp.h +++ b/alib/src/regexp/RegExp.h @@ -60,6 +60,11 @@ public: */ bool isEmpty() const; + /** + * @return true if regexp matches empty string (epsilon) + */ + bool containsEmptyString() const; + /** * Prints XML representation of the RegExp to the output stream. * @param out output stream to which print the RegExp diff --git a/alib/src/regexp/RegExpElement.cpp b/alib/src/regexp/RegExpElement.cpp index f6198be509..4b1cfb8834 100644 --- a/alib/src/regexp/RegExpElement.cpp +++ b/alib/src/regexp/RegExpElement.cpp @@ -10,6 +10,7 @@ namespace regexp { RegExpElement::~RegExpElement() { + } bool RegExpElement::operator!=(const RegExpElement& other) const { diff --git a/alib/src/regexp/RegExpElement.h b/alib/src/regexp/RegExpElement.h index 6365c1da0a..206c80759d 100644 --- a/alib/src/regexp/RegExpElement.h +++ b/alib/src/regexp/RegExpElement.h @@ -32,34 +32,38 @@ public: * @return copy of the element */ virtual RegExpElement* clone() const = 0; - + virtual bool operator<(const RegExpElement&) const = 0; virtual bool operator==(const RegExpElement&) const = 0; virtual bool operator>(const RegExpElement&) const = 0; - + virtual bool operator!=(const RegExpElement&) const; - + virtual bool operator<(const Concatenation&) const; virtual bool operator<(const Alternation&) const; virtual bool operator<(const Iteration&) const; virtual bool operator<(const RegExpSymbol&) const; virtual bool operator<(const RegExpEpsilon&) const; virtual bool operator<(const RegExpEmpty&) const; - + virtual bool operator==(const Concatenation&) const; virtual bool operator==(const Alternation&) const; virtual bool operator==(const Iteration&) const; virtual bool operator==(const RegExpSymbol&) const; virtual bool operator==(const RegExpEpsilon&) const; virtual bool operator==(const RegExpEmpty&) const; - + virtual bool operator>(const Concatenation&) const; virtual bool operator>(const Alternation&) const; virtual bool operator>(const Iteration&) const; virtual bool operator>(const RegExpSymbol&) const; virtual bool operator>(const RegExpEpsilon&) const; virtual bool operator>(const RegExpEmpty&) const; - + + /** + * @return true if this subtree of regexp matches empty string (epsilon) + */ + virtual bool containsEmptyString() const = 0; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEmpty.cpp b/alib/src/regexp/RegExpEmpty.cpp index 16c579eaef..28683e657f 100644 --- a/alib/src/regexp/RegExpEmpty.cpp +++ b/alib/src/regexp/RegExpEmpty.cpp @@ -53,5 +53,9 @@ bool RegExpEmpty::operator==(const RegExpEmpty&) const { return true; } +bool RegExpEmpty::containsEmptyString() const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEmpty.h b/alib/src/regexp/RegExpEmpty.h index 2c5ffb0827..7fb80a8935 100644 --- a/alib/src/regexp/RegExpEmpty.h +++ b/alib/src/regexp/RegExpEmpty.h @@ -25,7 +25,7 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() const; - + virtual bool operator<(const RegExpElement&) const; virtual bool operator==(const RegExpElement&) const; virtual bool operator>(const RegExpElement&) const; @@ -36,6 +36,11 @@ public: virtual bool operator<(const RegExpSymbol&) const; virtual bool operator<(const RegExpEpsilon&) const; virtual bool operator==(const RegExpEmpty&) const; + + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEpsilon.cpp b/alib/src/regexp/RegExpEpsilon.cpp index 11645bb8bd..0d7c64f159 100644 --- a/alib/src/regexp/RegExpEpsilon.cpp +++ b/alib/src/regexp/RegExpEpsilon.cpp @@ -52,6 +52,10 @@ bool RegExpEpsilon::operator==(const RegExpEpsilon&) const { bool RegExpEpsilon::operator>(const RegExpEmpty&) const { return true; } - + +bool RegExpEpsilon::containsEmptyString() const { + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEpsilon.h b/alib/src/regexp/RegExpEpsilon.h index 4c0f028251..351df1bde6 100644 --- a/alib/src/regexp/RegExpEpsilon.h +++ b/alib/src/regexp/RegExpEpsilon.h @@ -27,7 +27,7 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() const; - + virtual bool operator<(const RegExpElement&) const; virtual bool operator==(const RegExpElement&) const; virtual bool operator>(const RegExpElement&) const; @@ -38,6 +38,11 @@ public: virtual bool operator<(const RegExpSymbol&) const; virtual bool operator==(const RegExpEpsilon&) const; virtual bool operator>(const RegExpEmpty&) const; + + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpSymbol.cpp b/alib/src/regexp/RegExpSymbol.cpp index 1e524be73f..1ecb2bcf90 100644 --- a/alib/src/regexp/RegExpSymbol.cpp +++ b/alib/src/regexp/RegExpSymbol.cpp @@ -66,5 +66,9 @@ bool RegExpSymbol::operator>(const RegExpEmpty&) const { return true; } +bool RegExpSymbol::containsEmptyString() const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpSymbol.h b/alib/src/regexp/RegExpSymbol.h index ddd17e9d29..1b7b4982b1 100644 --- a/alib/src/regexp/RegExpSymbol.h +++ b/alib/src/regexp/RegExpSymbol.h @@ -29,11 +29,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() const; - + virtual bool operator<(const RegExpElement&) const; virtual bool operator==(const RegExpElement&) const; virtual bool operator>(const RegExpElement&) const; - + virtual bool operator<(const Concatenation&) const; virtual bool operator<(const Alternation&) const; virtual bool operator<(const Iteration&) const; @@ -43,6 +43,11 @@ public: virtual bool operator>(const RegExpEpsilon&) const; virtual bool operator>(const RegExpEmpty&) const; + + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */ -- GitLab