diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp index df3a0c7f3a22cf4c6c7d7c2a35eef56b797b17e4..2103548d5353a39f940ef9bb52be9ab5cace74d4 100644 --- a/alib/src/regexp/Alternation.cpp +++ b/alib/src/regexp/Alternation.cpp @@ -54,5 +54,13 @@ RegExpElement* Alternation::clone() const { return new Alternation(*this); } +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 d728756a04a31828ab3e14848732a08191a00838..c237a10498803856e2c026b74fce0869fe6d302e 100644 --- a/alib/src/regexp/Alternation.h +++ b/alib/src/regexp/Alternation.h @@ -42,6 +42,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() 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 be3dda2631a8f0d533a7d2731f3908b9ab73f473..1404382056ad880b652b129f1c561289555f48f4 100644 --- a/alib/src/regexp/Concatenation.cpp +++ b/alib/src/regexp/Concatenation.cpp @@ -54,4 +54,13 @@ RegExpElement* Concatenation::clone() const { return new Concatenation(*this); } +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 6175fc67574d075162d22cd2f58885ed73ef65a6..e239009e0d5d44912e1816587a4b1dc0f5eac021 100644 --- a/alib/src/regexp/Concatenation.h +++ b/alib/src/regexp/Concatenation.h @@ -43,6 +43,10 @@ public: */ RegExpElement* clone() 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 b99bb60c1c3a098947e5d191061dc1d4849e8ba1..3ea0614175d91a2205bd503dea9039764b8659d1 100644 --- a/alib/src/regexp/Iteration.cpp +++ b/alib/src/regexp/Iteration.cpp @@ -65,5 +65,9 @@ RegExpElement* Iteration::clone() const { return new Iteration(*this); } +bool Iteration::containsEmptyString() const { + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/Iteration.h b/alib/src/regexp/Iteration.h index 23faa47a2b9379826bed4cd1e7a5d51e6fbe9f92..645519714732ed334b762bf8bdce5fc2cd0159a0 100644 --- a/alib/src/regexp/Iteration.h +++ b/alib/src/regexp/Iteration.h @@ -48,6 +48,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() 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 727dc909a1040177934b61829bd423e44bc198a5..bf745304852efdef9267941a52f9e073186f9cc6 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 3f0220309a5cc394895b0a199a1df44a8bb82402..1242304c603afbdb73bbfaad0f5cb8899a7f29e0 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 d7231b3c07966d117afbd903ef011838569cb75b..25f706ba7a5b268057cf0052a7a962771a0d8855 100644 --- a/alib/src/regexp/RegExpElement.cpp +++ b/alib/src/regexp/RegExpElement.cpp @@ -10,6 +10,7 @@ namespace regexp { RegExpElement::~RegExpElement() { + } } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpElement.h b/alib/src/regexp/RegExpElement.h index 2cc340c6b3d88fb6faf14ba9ac6a533833aedcff..ee7a13d2f2b190ecdbd48c2961caa2032cd98006 100644 --- a/alib/src/regexp/RegExpElement.h +++ b/alib/src/regexp/RegExpElement.h @@ -24,6 +24,11 @@ public: * @return copy of the element */ virtual RegExpElement* clone() const = 0; + + /** + * @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 3c5b5711ac36921712a284f6fea4b5e3a916b392..fbfa0371c3bbeb86477577cb69084d81439e14ad 100644 --- a/alib/src/regexp/RegExpEmpty.cpp +++ b/alib/src/regexp/RegExpEmpty.cpp @@ -16,5 +16,9 @@ RegExpElement* RegExpEmpty::clone() const { return new RegExpEmpty(); } +bool RegExpEmpty::containsEmptyString() const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEmpty.h b/alib/src/regexp/RegExpEmpty.h index 937d04e6797cd4858fc83e8d8b3a3e2f0807d931..dbdf6f4e9f5c89c79d1e4e938c3cadbc09ac4817 100644 --- a/alib/src/regexp/RegExpEmpty.h +++ b/alib/src/regexp/RegExpEmpty.h @@ -25,6 +25,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() 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 fff799e81c8e469c0a02edd5319ea5f5beb846a0..80b12b40763dc494af3712dc6d17936a258e41ad 100644 --- a/alib/src/regexp/RegExpEpsilon.cpp +++ b/alib/src/regexp/RegExpEpsilon.cpp @@ -16,5 +16,9 @@ RegExpElement* RegExpEpsilon::clone() const { return new RegExpEpsilon(); } +bool RegExpEpsilon::containsEmptyString() const { + return true; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpEpsilon.h b/alib/src/regexp/RegExpEpsilon.h index 2d48546fcc99b3137e7967d17c4c8f29d6b2859f..ff3bfb3d1c2440cd6520ecfb3841ba2ec5d79ace 100644 --- a/alib/src/regexp/RegExpEpsilon.h +++ b/alib/src/regexp/RegExpEpsilon.h @@ -27,6 +27,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() 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 95f5642371bfae32c6b138bb31bc3bff2da28b3c..f460d554964dfc33ef510ca48d1dbf434757b8ce 100644 --- a/alib/src/regexp/RegExpSymbol.cpp +++ b/alib/src/regexp/RegExpSymbol.cpp @@ -21,5 +21,9 @@ RegExpElement* RegExpSymbol::clone() const { return new RegExpSymbol(this->symbol); } +bool RegExpSymbol::containsEmptyString() const { + return false; +} + } /* namespace regexp */ diff --git a/alib/src/regexp/RegExpSymbol.h b/alib/src/regexp/RegExpSymbol.h index bb6db856d9d6835ccd6cd9d2fa350f5fa1a27e8a..588680bf2d35be94a1d26f154d2aed6f68e9f8f4 100644 --- a/alib/src/regexp/RegExpSymbol.h +++ b/alib/src/regexp/RegExpSymbol.h @@ -29,6 +29,11 @@ public: * @copydoc RegExpElement::clone() const */ RegExpElement* clone() const; + + /** + * @copydoc RegExpElement::containsEmptyString() const + */ + bool containsEmptyString() const; }; } /* namespace regexp */