From beea963bfb38286a08a0bca1a33076d56aaac1fb Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Mon, 23 May 2016 15:25:45 +0200
Subject: [PATCH] refactor regexp parsing

---
 .../src/regexp/RegExpFromStringParser.cpp     | 114 ++++++------------
 alib2str/src/regexp/RegExpFromStringParser.h  |  17 +--
 2 files changed, 49 insertions(+), 82 deletions(-)

diff --git a/alib2str/src/regexp/RegExpFromStringParser.cpp b/alib2str/src/regexp/RegExpFromStringParser.cpp
index 11f7f6354d..5aca1664fa 100644
--- a/alib2str/src/regexp/RegExpFromStringParser.cpp
+++ b/alib2str/src/regexp/RegExpFromStringParser.cpp
@@ -21,9 +21,9 @@ RegExp RegExpFromStringParser::parseRegExp(std::istream& input) const {
 }
 
 RegExp RegExpFromStringParser::parseRegExp(std::istream& input, const std::set<FEATURES>& features) const {
-	UnboundedRegExpElement* element = this->alternation(input);
-	UnboundedRegExp regexp(std::move(*element));
-	delete element;
+	std::rvalue_ref < UnboundedRegExpElement > element = this->alternation(input);
+	UnboundedRegExp regexp(std::move(element));
+
 	if(features.count(FEATURES::UNBOUNDED)) return RegExp{regexp};
 
 	if(features.count(FEATURES::FORMAL)) return RegExp{FormalRegExp{regexp}};
@@ -31,129 +31,95 @@ RegExp RegExpFromStringParser::parseRegExp(std::istream& input, const std::set<F
 	throw exception::CommonException("Invalid input");
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::alternation(std::istream& input) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternation(std::istream& input) const {
 	return this->alternationCont(input, this->concatenation(input));
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::alternationCont(std::istream& input, UnboundedRegExpElement* left) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left) const {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::PLUS) {
-		try {
-			UnboundedRegExpElement* right = this->concatenation(input);
-			UnboundedRegExpAlternation* res = new UnboundedRegExpAlternation();
-			res->appendElement(std::move(*left));
-			res->appendElement(std::move(*right));
-			delete right;
-			delete left;
-
-			return this->alternationContCont(input, res);
-		} catch (...) {
-			delete left;
-			throw;
-		}
+		UnboundedRegExpAlternation res;
+		res.appendElement(std::move(left));
+		res.appendElement(this->concatenation(input));
+
+		return this->alternationContCont(input, std::move ( res ) );
 	} else {
 		m_RegexpLexer.putback(input, token);
 		return left;
 	}
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::alternationContCont(std::istream& input, UnboundedRegExpAlternation* res) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::alternationContCont(std::istream& input, UnboundedRegExpAlternation res) const {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::PLUS) {
-		try {
-			UnboundedRegExpElement* next = this->concatenation(input);
-			res->appendElement(std::move(*next));
-			delete next;
-
-			return this->alternationContCont(input, res);
-		} catch (...) {
-			delete res;
-			throw;
-		}
+		res.appendElement(this->concatenation(input));
+
+		return this->alternationContCont(input, std::move ( res ) );
 	} else {
 		m_RegexpLexer.putback(input, token);
-		return res;
+		return std::rvalue_ref < UnboundedRegExpElement > ( std::move ( res ).plunder() );
 	}
 }
 
-
-UnboundedRegExpElement* RegExpFromStringParser::concatenation(std::istream& input) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenation(std::istream& input) const {
 	return this->concatenationCont(input, this->factor(input));
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::concatenationCont(std::istream& input, UnboundedRegExpElement* left) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left) const {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) {
-		try {
-			m_RegexpLexer.putback(input, token);
-			UnboundedRegExpElement* right = this->factor(input);
-			UnboundedRegExpConcatenation* res = new UnboundedRegExpConcatenation();
-			res->appendElement(std::move(*left));
-			res->appendElement(std::move(*right));
-			delete right;
-			delete left;
-
-			return this->concatenationContCont(input, res);
-		} catch (...) {
-			delete left;
-			throw;
-		}
+		m_RegexpLexer.putback(input, token);
+		UnboundedRegExpConcatenation res;
+		res.appendElement(std::move(left));
+		res.appendElement(this->factor(input));
+
+		return this->concatenationContCont(input, std::move ( res ) );
 	} else {
 		m_RegexpLexer.putback(input, token);
 		return left;
 	}
-	return NULL; //unreachable but produces warning if not present
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::concatenationContCont(std::istream& input, UnboundedRegExpConcatenation* res) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::concatenationContCont(std::istream& input, UnboundedRegExpConcatenation res) const {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::ERROR || token.type == RegExpFromStringLexer::TokenType::LPAR || token.type == RegExpFromStringLexer::TokenType::EPS || token.type == RegExpFromStringLexer::TokenType::EMPTY) {
-		try {
-			m_RegexpLexer.putback(input, token);
-			UnboundedRegExpElement* next = this->factor(input);
-			res->appendElement(std::move(*next));
-			delete next;
-
-			return this->concatenationContCont(input, res);
-		} catch (...) {
-			delete res;
-			throw;
-		}
+		m_RegexpLexer.putback(input, token);
+		res.appendElement(this->factor(input));
+
+		return this->concatenationContCont(input, std::move ( res ) );
 	} else {
 		m_RegexpLexer.putback(input, token);
-		return res;
+		return std::rvalue_ref < UnboundedRegExpElement > ( std::move ( res ).plunder() );
 	}
-	return NULL; //unreachable but produces warning if not present
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::factor(std::istream& input) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::factor(std::istream& input) const {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::LPAR) {
-		UnboundedRegExpElement* base = this->alternation(input);
+		std::rvalue_ref < UnboundedRegExpElement > base = this->alternation(input);
 		token = m_RegexpLexer.next(input);
 		if(token.type != RegExpFromStringLexer::TokenType::RPAR) throw exception::CommonException("Expected RPAR");
-		return this->star(input, base);
+		return this->star(input, std::move ( base ) );
 	} else if(token.type == RegExpFromStringLexer::TokenType::EPS) {
-		return this->star(input, new UnboundedRegExpEpsilon());
+		return this->star(input, std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpEpsilon ( ) ) );
 	} else if(token.type == RegExpFromStringLexer::TokenType::EMPTY) {
-		return this->star(input, new UnboundedRegExpEmpty());
+		return this->star(input, std::rvalue_ref < UnboundedRegExpElement > ( new UnboundedRegExpEmpty ( ) ) );
 	} else if(token.type == RegExpFromStringLexer::TokenType::ERROR) {
-		UnboundedRegExpSymbol* res = new UnboundedRegExpSymbol(alib::stringApi<alphabet::Symbol>::parse(input));
-		return this->star(input, res);
+		UnboundedRegExpSymbol res(alib::stringApi<alphabet::Symbol>::parse(input));
+		return this->star(input, std::move ( res ) );
 	} else {
 		throw exception::CommonException("Unrecognised token at factor rule");
 	}
 }
 
-UnboundedRegExpElement* RegExpFromStringParser::star(std::istream& input, UnboundedRegExpElement* elem) const {
+std::rvalue_ref < UnboundedRegExpElement > RegExpFromStringParser::star(std::istream& input, UnboundedRegExpElement && elem) const {
 	RegExpFromStringLexer::Token token = m_RegexpLexer.next(input);
 	if(token.type == RegExpFromStringLexer::TokenType::STAR) {
-		UnboundedRegExpIteration* iter = new UnboundedRegExpIteration(std::move(*elem));
-		delete elem;
-		return this->star(input, iter);
+		UnboundedRegExpIteration iter ( std::move ( elem ) );
+		return this->star(input, std::move ( iter ) );
 	} else {
 		m_RegexpLexer.putback(input, token);
-		return elem;
+		return std::rvalue_ref < UnboundedRegExpElement > ( std::move ( elem ).plunder() );
 	}
 }
 
diff --git a/alib2str/src/regexp/RegExpFromStringParser.h b/alib2str/src/regexp/RegExpFromStringParser.h
index 04cafb95b7..b0f786e23e 100644
--- a/alib2str/src/regexp/RegExpFromStringParser.h
+++ b/alib2str/src/regexp/RegExpFromStringParser.h
@@ -12,6 +12,7 @@
 #include "RegExpFromStringLexer.h"
 
 #include <set>
+#include <memory>
 
 namespace alib {
 
@@ -27,16 +28,16 @@ public:
 	RegExpFromStringParser() {}
 
 private:
-	UnboundedRegExpElement* alternation(std::istream& input) const;
-	UnboundedRegExpElement* alternationCont(std::istream& input, UnboundedRegExpElement* left) const;
-	UnboundedRegExpElement* alternationContCont(std::istream& input, UnboundedRegExpAlternation* left) const;
+	std::rvalue_ref < UnboundedRegExpElement > alternation(std::istream& input) const;
+	std::rvalue_ref < UnboundedRegExpElement > alternationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left) const;
+	std::rvalue_ref < UnboundedRegExpElement > alternationContCont(std::istream& input, UnboundedRegExpAlternation left) const;
 
-	UnboundedRegExpElement* concatenation(std::istream& input) const;
-	UnboundedRegExpElement* concatenationCont(std::istream& input, UnboundedRegExpElement* left) const;
-	UnboundedRegExpElement* concatenationContCont(std::istream& input, UnboundedRegExpConcatenation* left) const;
+	std::rvalue_ref < UnboundedRegExpElement > concatenation(std::istream& input) const;
+	std::rvalue_ref < UnboundedRegExpElement > concatenationCont(std::istream& input, std::rvalue_ref < UnboundedRegExpElement > left) const;
+	std::rvalue_ref < UnboundedRegExpElement > concatenationContCont(std::istream& input, UnboundedRegExpConcatenation left) const;
 
-	UnboundedRegExpElement* factor(std::istream& input) const;
-	UnboundedRegExpElement* star(std::istream& input, UnboundedRegExpElement* elem) const;
+	std::rvalue_ref < UnboundedRegExpElement > factor(std::istream& input) const;
+	std::rvalue_ref < UnboundedRegExpElement > star(std::istream& input, UnboundedRegExpElement && elem) const;
 
 	RegExpFromStringLexer m_RegexpLexer;
 
-- 
GitLab