From 3e61f7365d321d8d98bcbd228ec63c8b3797677b 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

---
 alib/src/regexp/Alternation.cpp   | 8 ++++++++
 alib/src/regexp/Alternation.h     | 5 +++++
 alib/src/regexp/Concatenation.cpp | 9 +++++++++
 alib/src/regexp/Concatenation.h   | 4 ++++
 alib/src/regexp/Iteration.cpp     | 4 ++++
 alib/src/regexp/Iteration.h       | 5 +++++
 alib/src/regexp/RegExp.cpp        | 7 +++++++
 alib/src/regexp/RegExp.h          | 5 +++++
 alib/src/regexp/RegExpElement.cpp | 1 +
 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    | 5 +++++
 16 files changed, 80 insertions(+)

diff --git a/alib/src/regexp/Alternation.cpp b/alib/src/regexp/Alternation.cpp
index df3a0c7f3a..2103548d53 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 d728756a04..c237a10498 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 be3dda2631..1404382056 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 6175fc6757..e239009e0d 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 b99bb60c1c..3ea0614175 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 23faa47a2b..6455197147 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 727dc909a1..bf74530485 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 3f0220309a..1242304c60 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 d7231b3c07..25f706ba7a 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 2cc340c6b3..ee7a13d2f2 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 3c5b5711ac..fbfa0371c3 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 937d04e679..dbdf6f4e9f 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 fff799e81c..80b12b4076 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 2d48546fcc..ff3bfb3d1c 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 95f5642371..f460d55496 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 bb6db856d9..588680bf2d 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 */
-- 
GitLab