From 710f4a1822d869705cc00ee12499491283a31b69 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Sat, 28 Jun 2014 09:10:46 +0200
Subject: [PATCH] EndOfFile symbol

---
 alib2/src/alphabet/EndSymbol.cpp              | 54 +++++++++++++++++++
 alib2/src/alphabet/EndSymbol.h                | 45 ++++++++++++++++
 alib2/src/alphabet/SymbolBase.cpp             |  9 ++++
 alib2/src/alphabet/SymbolBase.h               |  5 +-
 alib2/src/alphabet/SymbolFeatures.h           |  9 ++--
 alib2/src/alphabet/SymbolFromStringLexer.cpp  |  3 ++
 alib2/src/alphabet/SymbolFromStringLexer.h    |  1 +
 alib2/src/alphabet/SymbolFromStringParser.cpp |  3 ++
 alib2/src/alphabet/SymbolFromXMLParser.cpp    | 11 +++-
 alib2/src/alphabet/SymbolFromXMLParser.h      |  1 +
 alib2/src/alphabet/SymbolToStringComposer.cpp |  6 +++
 alib2/src/alphabet/SymbolToStringComposer.h   |  1 +
 alib2/src/alphabet/SymbolToXMLComposer.cpp    |  7 +++
 alib2/src/alphabet/SymbolToXMLComposer.h      |  1 +
 14 files changed, 150 insertions(+), 6 deletions(-)
 create mode 100644 alib2/src/alphabet/EndSymbol.cpp
 create mode 100644 alib2/src/alphabet/EndSymbol.h

diff --git a/alib2/src/alphabet/EndSymbol.cpp b/alib2/src/alphabet/EndSymbol.cpp
new file mode 100644
index 0000000000..05efd4a4f3
--- /dev/null
+++ b/alib2/src/alphabet/EndSymbol.cpp
@@ -0,0 +1,54 @@
+/*
+ * EndSymbol.cpp
+ *
+ *  Created on: Jun 19, 2014
+ *      Author: Jan Travnicek
+ */
+
+#include "EndSymbol.h"
+
+namespace alphabet {
+
+EndSymbol::EndSymbol() {
+
+}
+
+SymbolBase* EndSymbol::clone() const {
+	return new EndSymbol(*this);
+}
+
+SymbolBase* EndSymbol::plunder() && {
+	return new EndSymbol(std::move(*this));
+}
+
+bool EndSymbol::operator <(const SymbolBase& other) const {
+	return other > *this;
+}
+
+bool EndSymbol::operator ==(const SymbolBase& other) const {
+	return other == *this;
+}
+
+bool EndSymbol::operator >(const SymbolBase& other) const {
+	return other < *this;
+}
+
+bool EndSymbol::operator ==(const EndSymbol&) const {
+	return true;
+}
+
+bool EndSymbol::operator <(const EndSymbol&) const {
+	return false;
+}
+
+void EndSymbol::operator>>(std::ostream& out) const {
+	out << "(Blank symbol)";
+}
+
+EndSymbol::operator std::string () const {
+	return "";
+}
+
+EndSymbol EndSymbol::END = EndSymbol();
+
+} /* namespace alphabet */
diff --git a/alib2/src/alphabet/EndSymbol.h b/alib2/src/alphabet/EndSymbol.h
new file mode 100644
index 0000000000..9640b4fe29
--- /dev/null
+++ b/alib2/src/alphabet/EndSymbol.h
@@ -0,0 +1,45 @@
+/*
+ * EndSymbol.h
+ *
+ *  Created on: Jun 19, 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef END_SYMBOL_H_
+#define END_SYMBOL_H_
+
+#include "Symbol.h"
+
+namespace alphabet {
+
+/**
+ * Represents blank symbol in an alphabet.
+ */
+class EndSymbol : public std::element<EndSymbol, SymbolBase> {
+public:
+	/**
+	 * Creates a blank symbol.
+	 * @param symbol name of the symbol
+	 */
+	EndSymbol();
+
+	virtual SymbolBase* clone() const;
+	virtual SymbolBase* plunder() &&;
+	
+	virtual bool operator <(const SymbolBase& other) const;
+	virtual bool operator ==(const SymbolBase& other) const;
+	virtual bool operator >(const SymbolBase& other) const;
+
+	virtual bool operator ==(const EndSymbol& other) const;
+	virtual bool operator <(const EndSymbol& other) const;
+
+	virtual void operator>>(std::ostream& out) const;
+	
+	virtual operator std::string () const;
+
+	static EndSymbol END;
+};
+
+} /* namespace alphabet */
+
+#endif /* END_SYMBOL_H_ */
diff --git a/alib2/src/alphabet/SymbolBase.cpp b/alib2/src/alphabet/SymbolBase.cpp
index 9027bb8672..b26548fa9e 100644
--- a/alib2/src/alphabet/SymbolBase.cpp
+++ b/alib2/src/alphabet/SymbolBase.cpp
@@ -11,6 +11,7 @@
 #include "LabeledSymbol.h"
 #include "BlankSymbol.h"
 #include "BottomOfTheStackSymbol.h"
+#include "EndSymbol.h"
 
 namespace alphabet {
 
@@ -39,6 +40,10 @@ bool SymbolBase::operator==(const BottomOfTheStackSymbol&) const {
 	return false;
 }
 
+bool SymbolBase::operator==(const EndSymbol&) const {
+	return false;
+}
+
 bool SymbolBase::operator<(const LabeledSymbol& other) const {
 	return typeid(*this).before(typeid(other));
 }
@@ -51,4 +56,8 @@ bool SymbolBase::operator<(const BottomOfTheStackSymbol& other) const {
 	return typeid(*this).before(typeid(other));
 }
 
+bool SymbolBase::operator<(const EndSymbol& other) const {
+	return typeid(*this).before(typeid(other));
+}
+
 } /* namespace alphabet */
diff --git a/alib2/src/alphabet/SymbolBase.h b/alib2/src/alphabet/SymbolBase.h
index 7aee1dd676..fae6048427 100644
--- a/alib2/src/alphabet/SymbolBase.h
+++ b/alib2/src/alphabet/SymbolBase.h
@@ -16,11 +16,12 @@ namespace alphabet {
 class LabeledSymbol;
 class BlankSymbol;
 class BottomOfTheStackSymbol;
+class EndSymbol;
 
 /**
  * Represents symbol in an alphabet.
  */
-class SymbolBase : public std::elementBase<LabeledSymbol, BlankSymbol, BottomOfTheStackSymbol> {
+class SymbolBase : public std::elementBase<LabeledSymbol, BlankSymbol, BottomOfTheStackSymbol, EndSymbol> {
 public:
 	virtual ~SymbolBase() noexcept;
 
@@ -35,10 +36,12 @@ public:
 	virtual bool operator==(const LabeledSymbol& other) const;
 	virtual bool operator==(const BlankSymbol& other) const;
 	virtual bool operator==(const BottomOfTheStackSymbol& other) const;
+	virtual bool operator==(const EndSymbol& other) const;
 
 	virtual bool operator<(const LabeledSymbol& other) const;
 	virtual bool operator<(const BlankSymbol& other) const;
 	virtual bool operator<(const BottomOfTheStackSymbol& other) const;
+	virtual bool operator<(const EndSymbol& other) const;
 
 	friend std::ostream& operator<<(std::ostream&, const SymbolBase&);
 
diff --git a/alib2/src/alphabet/SymbolFeatures.h b/alib2/src/alphabet/SymbolFeatures.h
index 2219a4fb01..a7743c9b36 100644
--- a/alib2/src/alphabet/SymbolFeatures.h
+++ b/alib2/src/alphabet/SymbolFeatures.h
@@ -8,12 +8,13 @@
 #ifndef LABEL_FEATURES_H_
 #define LABEL_FEATURES_H_
 
-namespace label {
+namespace alphabet {
 
 enum class FEATURES {
-	LABELED_SYMBOL,
-	BLANK_SYMBOL,
-	BOTTOM_OF_THE_STACK_SYMBOL
+	LABELED,
+	BLANK,
+	BOTTOM,
+	END
 };
 
 } /* namespace label */
diff --git a/alib2/src/alphabet/SymbolFromStringLexer.cpp b/alib2/src/alphabet/SymbolFromStringLexer.cpp
index aad58e353c..52af8b1f47 100644
--- a/alib2/src/alphabet/SymbolFromStringLexer.cpp
+++ b/alib2/src/alphabet/SymbolFromStringLexer.cpp
@@ -40,6 +40,9 @@ L1:
 	} else if(character == 'Z') {
 		m_Current.type = TokenType::BOTTOM;
 		return *this;
+	} else if(character == 'E') {
+		m_Current.type = TokenType::END;
+		return *this;
 	} else {
 		m_In.seekg(pos);
 		m_Current.type = TokenType::ERROR;
diff --git a/alib2/src/alphabet/SymbolFromStringLexer.h b/alib2/src/alphabet/SymbolFromStringLexer.h
index 83f46d61ad..d5d572c2cd 100644
--- a/alib2/src/alphabet/SymbolFromStringLexer.h
+++ b/alib2/src/alphabet/SymbolFromStringLexer.h
@@ -11,6 +11,7 @@ public:
 	enum class TokenType {
 		BLANK,
 		BOTTOM,
+		END,
 		TEOF,
 		ERROR,
 	};
diff --git a/alib2/src/alphabet/SymbolFromStringParser.cpp b/alib2/src/alphabet/SymbolFromStringParser.cpp
index 527fe7795f..28f0f16ae2 100644
--- a/alib2/src/alphabet/SymbolFromStringParser.cpp
+++ b/alib2/src/alphabet/SymbolFromStringParser.cpp
@@ -2,6 +2,7 @@
 #include "../AlibException.h"
 #include "BlankSymbol.h"
 #include "BottomOfTheStackSymbol.h"
+#include "EndSymbol.h"
 #include "LabeledSymbol.h"
 
 namespace alphabet {
@@ -17,6 +18,8 @@ Symbol SymbolFromStringParser::parse() {
 		return Symbol(BlankSymbol());
 	case SymbolFromStringLexer::TokenType::BOTTOM:
 		return Symbol(BottomOfTheStackSymbol());
+	case SymbolFromStringLexer::TokenType::END:
+		return Symbol(EndSymbol());
 	case SymbolFromStringLexer::TokenType::ERROR:
 		return Symbol(LabeledSymbol(m_LabelParser.parse()));
 	case SymbolFromStringLexer::TokenType::TEOF:
diff --git a/alib2/src/alphabet/SymbolFromXMLParser.cpp b/alib2/src/alphabet/SymbolFromXMLParser.cpp
index 903d8fb56a..6ef74c5c3d 100644
--- a/alib2/src/alphabet/SymbolFromXMLParser.cpp
+++ b/alib2/src/alphabet/SymbolFromXMLParser.cpp
@@ -10,6 +10,7 @@
 #include "../sax/ParserException.h"
 #include "BlankSymbol.h"
 #include "BottomOfTheStackSymbol.h"
+#include "EndSymbol.h"
 #include "LabeledSymbol.h"
 #include "../label/Label.h"
 
@@ -24,8 +25,10 @@ Symbol SymbolFromXMLParser::parse(std::list<sax::Token>& input) const {
 		return parseBlankSymbol(input);
 	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "BottomOfTheStackSymbol")) {
 		return parseBlankSymbol(input);
+	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "EndSymbol")) {
+		return parseEndSymbol(input);
 	} else {
-		throw sax::ParserException(sax::Token("LabeledSymbol, BlankSymbol, BottomOfTheStackSymbol", sax::Token::TokenType::START_ELEMENT), input.front());
+		throw sax::ParserException(sax::Token("LabeledSymbol, BlankSymbol, BottomOfTheStackSymbol, EndSymbol", sax::Token::TokenType::START_ELEMENT), input.front());
 	}
 }
 
@@ -48,6 +51,12 @@ Symbol SymbolFromXMLParser::parseBottomOfTheStackSymbol(std::list<sax::Token>& i
 	return Symbol(BottomOfTheStackSymbol());
 }
 
+Symbol SymbolFromXMLParser::parseEndSymbol(std::list<sax::Token>& input) const {
+	popToken(input, sax::Token::TokenType::START_ELEMENT, "EndSymbol");
+	popToken(input, sax::Token::TokenType::END_ELEMENT, "EndSymbol");
+	return Symbol(EndSymbol());
+}
+
 Symbol SymbolFromXMLParser::parseValue(std::list<sax::Token>& input) const {
 	Symbol res = parse(input);
 
diff --git a/alib2/src/alphabet/SymbolFromXMLParser.h b/alib2/src/alphabet/SymbolFromXMLParser.h
index 0761c30f8c..243a105f74 100644
--- a/alib2/src/alphabet/SymbolFromXMLParser.h
+++ b/alib2/src/alphabet/SymbolFromXMLParser.h
@@ -43,6 +43,7 @@ class SymbolFromXMLParser : public sax::FromXMLParser {
 	Symbol parseLabeledSymbol(std::list<sax::Token>& input) const;
 	Symbol parseBlankSymbol(std::list<sax::Token>& input) const;
 	Symbol parseBottomOfTheStackSymbol(std::list<sax::Token>& input) const;
+	Symbol parseEndSymbol(std::list<sax::Token>& input) const;
 	/**
 	 * Parses the XML tokens and returns symbol. The input is destroyed in the process.
 	 * @param input XML tokens represented as list of tokens
diff --git a/alib2/src/alphabet/SymbolToStringComposer.cpp b/alib2/src/alphabet/SymbolToStringComposer.cpp
index 3788626c94..48ea246c22 100644
--- a/alib2/src/alphabet/SymbolToStringComposer.cpp
+++ b/alib2/src/alphabet/SymbolToStringComposer.cpp
@@ -31,6 +31,12 @@ void SymbolToStringComposer::Visit(void* userData, const BottomOfTheStackSymbol&
 	out << "#Z";
 }
 
+void SymbolToStringComposer::Visit(void* userData, const EndSymbol&) {
+	std::stringstream &out = *((std::stringstream*) userData);
+
+	out << "#E";
+}
+
 void SymbolToStringComposer::Visit(void* userData, const Symbol& symbol) {
 	symbol.getSymbol().Accept(userData, *this);
 
diff --git a/alib2/src/alphabet/SymbolToStringComposer.h b/alib2/src/alphabet/SymbolToStringComposer.h
index 237e61f69c..7a11e46f49 100644
--- a/alib2/src/alphabet/SymbolToStringComposer.h
+++ b/alib2/src/alphabet/SymbolToStringComposer.h
@@ -23,6 +23,7 @@ class SymbolToStringComposer : public SymbolBase::visitor_type {
 	void Visit(void*, const LabeledSymbol& symbol);
 	void Visit(void*, const BlankSymbol& symbol);
 	void Visit(void*, const BottomOfTheStackSymbol& symbol);
+	void Visit(void*, const EndSymbol& symbol);
 
 public:
 	/**
diff --git a/alib2/src/alphabet/SymbolToXMLComposer.cpp b/alib2/src/alphabet/SymbolToXMLComposer.cpp
index cd6e06dd38..9db9866913 100644
--- a/alib2/src/alphabet/SymbolToXMLComposer.cpp
+++ b/alib2/src/alphabet/SymbolToXMLComposer.cpp
@@ -25,6 +25,13 @@ void SymbolToXMLComposer::Visit(void* userData, const BottomOfTheStackSymbol&) c
 	out.push_back(sax::Token("BottomOfTheStackSymbol", sax::Token::TokenType::END_ELEMENT));
 }
 
+void SymbolToXMLComposer::Visit(void* userData, const EndSymbol&) const {
+	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
+
+	out.push_back(sax::Token("EndSymbol", sax::Token::TokenType::START_ELEMENT));
+	out.push_back(sax::Token("EndSymbol", sax::Token::TokenType::END_ELEMENT));
+}
+
 void SymbolToXMLComposer::Visit(void* userData, const LabeledSymbol& symbol) const {
 	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
 
diff --git a/alib2/src/alphabet/SymbolToXMLComposer.h b/alib2/src/alphabet/SymbolToXMLComposer.h
index e83d301fb0..2e68d01686 100644
--- a/alib2/src/alphabet/SymbolToXMLComposer.h
+++ b/alib2/src/alphabet/SymbolToXMLComposer.h
@@ -23,6 +23,7 @@ class SymbolToXMLComposer : public SymbolBase::const_visitor_type {
 	void Visit(void*, const LabeledSymbol& symbol) const;
 	void Visit(void*, const BlankSymbol& symbol) const;
 	void Visit(void*, const BottomOfTheStackSymbol& symbol) const;
+	void Visit(void*, const EndSymbol& symbol) const;
 
 public:
 	/**
-- 
GitLab