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