From 5c6aa6048a5de91df7db24971ae271e07e1af186 Mon Sep 17 00:00:00 2001
From: Jan Travnicek <Jan.Travnicek@fit.cvut.cz>
Date: Fri, 20 Jun 2014 12:14:18 +0200
Subject: [PATCH] Fix bottom of the stack symbol

---
 alib2/src/alphabet/BlankSymbol.h              |  2 +-
 alib2/src/alphabet/BottomOfTheStackSymbol.cpp | 54 +++++++++++++++++++
 alib2/src/alphabet/BottomOfTheStackSymbol.h   | 45 ++++++++++++++++
 alib2/src/alphabet/SymbolBase.cpp             |  9 ++++
 alib2/src/alphabet/SymbolBase.h               |  5 +-
 alib2/src/alphabet/SymbolFromStringLexer.cpp  |  3 ++
 alib2/src/alphabet/SymbolFromStringLexer.h    |  1 +
 alib2/src/alphabet/SymbolFromStringParser.cpp |  3 ++
 alib2/src/alphabet/SymbolFromXMLParser.cpp    |  5 ++
 alib2/src/alphabet/SymbolToStringComposer.cpp |  7 ++-
 alib2/src/alphabet/SymbolToStringComposer.h   |  2 +
 alib2/src/alphabet/SymbolToXMLComposer.cpp    |  8 ++-
 alib2/src/alphabet/SymbolToXMLComposer.h      |  1 +
 alib2/src/label/LabelFromXMLParser.cpp        |  2 +-
 14 files changed, 142 insertions(+), 5 deletions(-)
 create mode 100644 alib2/src/alphabet/BottomOfTheStackSymbol.cpp
 create mode 100644 alib2/src/alphabet/BottomOfTheStackSymbol.h

diff --git a/alib2/src/alphabet/BlankSymbol.h b/alib2/src/alphabet/BlankSymbol.h
index 25bfcb4a34..7f330893e7 100644
--- a/alib2/src/alphabet/BlankSymbol.h
+++ b/alib2/src/alphabet/BlankSymbol.h
@@ -2,7 +2,7 @@
  * BlankSymbol.h
  *
  *  Created on: Mar 26, 2013
- *      Author: Jan Trávníček
+ *      Author: Jan Travnicek
  */
 
 #ifndef BLANK_SYMBOL_H_
diff --git a/alib2/src/alphabet/BottomOfTheStackSymbol.cpp b/alib2/src/alphabet/BottomOfTheStackSymbol.cpp
new file mode 100644
index 0000000000..7aa1015591
--- /dev/null
+++ b/alib2/src/alphabet/BottomOfTheStackSymbol.cpp
@@ -0,0 +1,54 @@
+/*
+ * BottomOfTheStackSymbol.cpp
+ *
+ *  Created on: Jun 19, 2014
+ *      Author: Jan Travnicek
+ */
+
+#include "BottomOfTheStackSymbol.h"
+
+namespace alphabet {
+
+BottomOfTheStackSymbol::BottomOfTheStackSymbol() {
+
+}
+
+SymbolBase* BottomOfTheStackSymbol::clone() const {
+	return new BottomOfTheStackSymbol(*this);
+}
+
+SymbolBase* BottomOfTheStackSymbol::plunder() && {
+	return new BottomOfTheStackSymbol(std::move(*this));
+}
+
+bool BottomOfTheStackSymbol::operator <(const SymbolBase& other) const {
+	return other > *this;
+}
+
+bool BottomOfTheStackSymbol::operator ==(const SymbolBase& other) const {
+	return other == *this;
+}
+
+bool BottomOfTheStackSymbol::operator >(const SymbolBase& other) const {
+	return other < *this;
+}
+
+bool BottomOfTheStackSymbol::operator ==(const BottomOfTheStackSymbol&) const {
+	return true;
+}
+
+bool BottomOfTheStackSymbol::operator <(const BottomOfTheStackSymbol&) const {
+	return false;
+}
+
+void BottomOfTheStackSymbol::operator>>(std::ostream& out) const {
+	out << "(Blank symbol)";
+}
+
+BottomOfTheStackSymbol::operator std::string () const {
+	return "";
+}
+
+BottomOfTheStackSymbol BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK = BottomOfTheStackSymbol();
+
+} /* namespace alphabet */
diff --git a/alib2/src/alphabet/BottomOfTheStackSymbol.h b/alib2/src/alphabet/BottomOfTheStackSymbol.h
new file mode 100644
index 0000000000..eebc152cca
--- /dev/null
+++ b/alib2/src/alphabet/BottomOfTheStackSymbol.h
@@ -0,0 +1,45 @@
+/*
+ * BottomOfTheStackSymbol.h
+ *
+ *  Created on: Jun 19, 2014
+ *      Author: Jan Travnicek
+ */
+
+#ifndef BOTTOM_OF_THE_STACK_SYMBOL_H_
+#define BOTTOM_OF_THE_STACK_SYMBOL_H_
+
+#include "Symbol.h"
+
+namespace alphabet {
+
+/**
+ * Represents blank symbol in an alphabet.
+ */
+class BottomOfTheStackSymbol : public std::element<BottomOfTheStackSymbol, SymbolBase> {
+public:
+	/**
+	 * Creates a blank symbol.
+	 * @param symbol name of the symbol
+	 */
+	BottomOfTheStackSymbol();
+
+	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 BottomOfTheStackSymbol& other) const;
+	virtual bool operator <(const BottomOfTheStackSymbol& other) const;
+
+	virtual void operator>>(std::ostream& out) const;
+	
+	virtual operator std::string () const;
+
+	static BottomOfTheStackSymbol BOTTOM_OF_THE_STACK;
+};
+
+} /* namespace alphabet */
+
+#endif /* BOTTOM_OF_THE_STACK_SYMBOL_H_ */
diff --git a/alib2/src/alphabet/SymbolBase.cpp b/alib2/src/alphabet/SymbolBase.cpp
index 58e7c3300e..9027bb8672 100644
--- a/alib2/src/alphabet/SymbolBase.cpp
+++ b/alib2/src/alphabet/SymbolBase.cpp
@@ -10,6 +10,7 @@
 
 #include "LabeledSymbol.h"
 #include "BlankSymbol.h"
+#include "BottomOfTheStackSymbol.h"
 
 namespace alphabet {
 
@@ -34,6 +35,10 @@ bool SymbolBase::operator==(const BlankSymbol&) const {
 	return false;
 }
 
+bool SymbolBase::operator==(const BottomOfTheStackSymbol&) const {
+	return false;
+}
+
 bool SymbolBase::operator<(const LabeledSymbol& other) const {
 	return typeid(*this).before(typeid(other));
 }
@@ -42,4 +47,8 @@ bool SymbolBase::operator<(const BlankSymbol& other) const {
 	return typeid(*this).before(typeid(other));
 }
 
+bool SymbolBase::operator<(const BottomOfTheStackSymbol& 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 8b61aa1e2a..7aee1dd676 100644
--- a/alib2/src/alphabet/SymbolBase.h
+++ b/alib2/src/alphabet/SymbolBase.h
@@ -15,11 +15,12 @@ namespace alphabet {
 
 class LabeledSymbol;
 class BlankSymbol;
+class BottomOfTheStackSymbol;
 
 /**
  * Represents symbol in an alphabet.
  */
-class SymbolBase : public std::elementBase<LabeledSymbol, BlankSymbol> {
+class SymbolBase : public std::elementBase<LabeledSymbol, BlankSymbol, BottomOfTheStackSymbol> {
 public:
 	virtual ~SymbolBase() noexcept;
 
@@ -33,9 +34,11 @@ 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 LabeledSymbol& other) const;
 	virtual bool operator<(const BlankSymbol& other) const;
+	virtual bool operator<(const BottomOfTheStackSymbol& other) const;
 
 	friend std::ostream& operator<<(std::ostream&, const SymbolBase&);
 
diff --git a/alib2/src/alphabet/SymbolFromStringLexer.cpp b/alib2/src/alphabet/SymbolFromStringLexer.cpp
index 281064ae2a..aad58e353c 100644
--- a/alib2/src/alphabet/SymbolFromStringLexer.cpp
+++ b/alib2/src/alphabet/SymbolFromStringLexer.cpp
@@ -37,6 +37,9 @@ L1:
 	} else if(character == 'B') {
 		m_Current.type = TokenType::BLANK;
 		return *this;
+	} else if(character == 'Z') {
+		m_Current.type = TokenType::BOTTOM;
+		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 5667d05ebe..83f46d61ad 100644
--- a/alib2/src/alphabet/SymbolFromStringLexer.h
+++ b/alib2/src/alphabet/SymbolFromStringLexer.h
@@ -10,6 +10,7 @@ class SymbolFromStringLexer {
 public:
 	enum class TokenType {
 		BLANK,
+		BOTTOM,
 		TEOF,
 		ERROR,
 	};
diff --git a/alib2/src/alphabet/SymbolFromStringParser.cpp b/alib2/src/alphabet/SymbolFromStringParser.cpp
index cf1cd464da..66a8635e1d 100644
--- a/alib2/src/alphabet/SymbolFromStringParser.cpp
+++ b/alib2/src/alphabet/SymbolFromStringParser.cpp
@@ -1,6 +1,7 @@
 #include "SymbolFromStringParser.h"
 #include "../AlibException.h"
 #include "BlankSymbol.h"
+#include "BottomOfTheStackSymbol.h"
 #include "LabeledSymbol.h"
 
 namespace alphabet {
@@ -14,6 +15,8 @@ Symbol* SymbolFromStringParser::parse() {
 	switch(token.type) {
 	case SymbolFromStringLexer::TokenType::BLANK:
 		return new Symbol(BlankSymbol());
+	case SymbolFromStringLexer::TokenType::BOTTOM:
+		return new Symbol(BottomOfTheStackSymbol());
 	case SymbolFromStringLexer::TokenType::ERROR: {
 		label::Label* label = m_LabelParser.parse();
 		if(label != NULL) {
diff --git a/alib2/src/alphabet/SymbolFromXMLParser.cpp b/alib2/src/alphabet/SymbolFromXMLParser.cpp
index 92bbfa6b41..650cd201cc 100644
--- a/alib2/src/alphabet/SymbolFromXMLParser.cpp
+++ b/alib2/src/alphabet/SymbolFromXMLParser.cpp
@@ -9,6 +9,7 @@
 
 #include "../sax/ParserException.h"
 #include "BlankSymbol.h"
+#include "BottomOfTheStackSymbol.h"
 #include "LabeledSymbol.h"
 #include "../label/Label.h"
 
@@ -26,6 +27,10 @@ Symbol SymbolFromXMLParser::parse(std::list<sax::Token>& input) const {
 		popToken(input, sax::Token::TokenType::START_ELEMENT, "BlankSymbol");
 		popToken(input, sax::Token::TokenType::END_ELEMENT, "BlankSymbol");
 		return Symbol(BlankSymbol());
+	} else if(isToken(input, sax::Token::TokenType::START_ELEMENT, "BottomOfTheStackSymbol")) {
+		popToken(input, sax::Token::TokenType::START_ELEMENT, "BottomOfTheStackSymbol");
+		popToken(input, sax::Token::TokenType::END_ELEMENT, "BottomOfTheStackSymbol");
+		return Symbol(BlankSymbol());
 	} else {
 		throw sax::ParserException(sax::Token("", sax::Token::TokenType::START_ELEMENT), input.front());
 	}
diff --git a/alib2/src/alphabet/SymbolToStringComposer.cpp b/alib2/src/alphabet/SymbolToStringComposer.cpp
index 5c49ef2968..3788626c94 100644
--- a/alib2/src/alphabet/SymbolToStringComposer.cpp
+++ b/alib2/src/alphabet/SymbolToStringComposer.cpp
@@ -8,7 +8,6 @@
 #include "SymbolToStringComposer.h"
 #include "../label/LabelToStringComposer.h"
 #include <algorithm>
-#include "../label/Label.h"
 #include "LabeledSymbol.h"
 
 namespace alphabet {
@@ -26,6 +25,12 @@ void SymbolToStringComposer::Visit(void* userData, const BlankSymbol&) {
 	out << "#B";
 }
 
+void SymbolToStringComposer::Visit(void* userData, const BottomOfTheStackSymbol&) {
+	std::stringstream &out = *((std::stringstream*) userData);
+
+	out << "#Z";
+}
+
 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 4f4b16837d..237e61f69c 100644
--- a/alib2/src/alphabet/SymbolToStringComposer.h
+++ b/alib2/src/alphabet/SymbolToStringComposer.h
@@ -22,6 +22,8 @@ class SymbolToStringComposer : public SymbolBase::visitor_type {
 	void Visit(void*, const Symbol& symbol);
 	void Visit(void*, const LabeledSymbol& symbol);
 	void Visit(void*, const BlankSymbol& symbol);
+	void Visit(void*, const BottomOfTheStackSymbol& symbol);
+
 public:
 	/**
 	 * Prints text representation of Symbol to the output stream.
diff --git a/alib2/src/alphabet/SymbolToXMLComposer.cpp b/alib2/src/alphabet/SymbolToXMLComposer.cpp
index f6a25fc10a..cd6e06dd38 100644
--- a/alib2/src/alphabet/SymbolToXMLComposer.cpp
+++ b/alib2/src/alphabet/SymbolToXMLComposer.cpp
@@ -6,7 +6,6 @@
  */
 
 #include "SymbolToXMLComposer.h"
-#include "LabeledSymbol.h"
 
 #include "../ToXMLComposers.h"
 
@@ -19,6 +18,13 @@ void SymbolToXMLComposer::Visit(void* userData, const BlankSymbol&) const {
 	out.push_back(sax::Token("BlankSymbol", sax::Token::TokenType::END_ELEMENT));
 }
 
+void SymbolToXMLComposer::Visit(void* userData, const BottomOfTheStackSymbol&) const {
+	std::list<sax::Token> &out = *((std::list<sax::Token>*) userData);
+
+	out.push_back(sax::Token("BottomOfTheStackSymbol", sax::Token::TokenType::START_ELEMENT));
+	out.push_back(sax::Token("BottomOfTheStackSymbol", 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 ab826bfd79..e83d301fb0 100644
--- a/alib2/src/alphabet/SymbolToXMLComposer.h
+++ b/alib2/src/alphabet/SymbolToXMLComposer.h
@@ -22,6 +22,7 @@ class SymbolToXMLComposer : public SymbolBase::const_visitor_type {
 	void Visit(void*, const Symbol& symbol) const;
 	void Visit(void*, const LabeledSymbol& symbol) const;
 	void Visit(void*, const BlankSymbol& symbol) const;
+	void Visit(void*, const BottomOfTheStackSymbol& symbol) const;
 
 public:
 	/**
diff --git a/alib2/src/label/LabelFromXMLParser.cpp b/alib2/src/label/LabelFromXMLParser.cpp
index 66b345c040..43995a545d 100644
--- a/alib2/src/label/LabelFromXMLParser.cpp
+++ b/alib2/src/label/LabelFromXMLParser.cpp
@@ -35,4 +35,4 @@ Label LabelFromXMLParser::parse(std::list<sax::Token>& input) const {
 	}
 }
 
-} /* namespace string */
+} /* namespace label */
-- 
GitLab