From a7ab5bb309e2cf96ca843c4c70a3d3259da94d0e Mon Sep 17 00:00:00 2001
From: dehnert <dehnert@cs.rwth-aachen.de>
Date: Thu, 3 Jan 2013 23:46:45 +0100
Subject: [PATCH] More fun with Spirit.

---
 src/ir/expressions/BaseExpression.h           | 33 ++++++++
 .../BinaryBooleanFunctionExpression.h         | 63 +++++++++++++++
 .../BinaryNumericalFunctionExpression.h       | 63 +++++++++++++++
 src/ir/expressions/BinaryRelationExpression.h | 64 +++++++++++++++
 src/ir/expressions/BooleanLiteral.h           | 51 ++++++++++++
 src/ir/expressions/ConstantExpression.h       | 47 +++++++++++
 src/ir/expressions/DoubleLiteral.h            | 47 +++++++++++
 src/ir/expressions/Expressions.h              | 21 +++++
 src/ir/expressions/IntegerLiteral.h           | 47 +++++++++++
 .../UnaryBooleanFunctionExpression.h          | 56 +++++++++++++
 .../UnaryNumericalFunctionExpression.h        | 56 +++++++++++++
 src/ir/expressions/VariableExpression.h       | 47 +++++++++++
 src/parser/PrismParser.h                      | 80 ++++++++++++-------
 13 files changed, 646 insertions(+), 29 deletions(-)
 create mode 100644 src/ir/expressions/BaseExpression.h
 create mode 100644 src/ir/expressions/BinaryBooleanFunctionExpression.h
 create mode 100644 src/ir/expressions/BinaryNumericalFunctionExpression.h
 create mode 100644 src/ir/expressions/BinaryRelationExpression.h
 create mode 100644 src/ir/expressions/BooleanLiteral.h
 create mode 100644 src/ir/expressions/ConstantExpression.h
 create mode 100644 src/ir/expressions/DoubleLiteral.h
 create mode 100644 src/ir/expressions/Expressions.h
 create mode 100644 src/ir/expressions/IntegerLiteral.h
 create mode 100644 src/ir/expressions/UnaryBooleanFunctionExpression.h
 create mode 100644 src/ir/expressions/UnaryNumericalFunctionExpression.h
 create mode 100644 src/ir/expressions/VariableExpression.h

diff --git a/src/ir/expressions/BaseExpression.h b/src/ir/expressions/BaseExpression.h
new file mode 100644
index 000000000..aea967901
--- /dev/null
+++ b/src/ir/expressions/BaseExpression.h
@@ -0,0 +1,33 @@
+/*
+ * Expression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef EXPRESSION_H_
+#define EXPRESSION_H_
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class BaseExpression {
+
+public:
+	virtual ~BaseExpression() {
+
+	}
+
+	virtual std::string toString() const = 0;
+};
+
+}
+
+}
+
+}
+
+#endif /* EXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryBooleanFunctionExpression.h b/src/ir/expressions/BinaryBooleanFunctionExpression.h
new file mode 100644
index 000000000..a5688f188
--- /dev/null
+++ b/src/ir/expressions/BinaryBooleanFunctionExpression.h
@@ -0,0 +1,63 @@
+/*
+ * BinaryBooleanFunctionExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef BINARYBOOLEANFUNCTIONEXPRESSION_H_
+#define BINARYBOOLEANFUNCTIONEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+#include <boost/fusion/include/adapt_struct.hpp>
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class BinaryBooleanFunctionExpression : public BaseExpression {
+public:
+	enum FunctorType {AND, OR, XOR, IMPLIES} functor;
+	BaseExpression* left;
+	BaseExpression* right;
+
+	BinaryBooleanFunctionExpression(BaseExpression* left, BaseExpression* right, FunctorType functor) {
+		this->left = left;
+		this->right = right;
+		this->functor = functor;
+	}
+
+	virtual ~BinaryBooleanFunctionExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		std::string result = left->toString();
+		switch (functor) {
+		case AND: result += " & "; break;
+		case OR: result += " | "; break;
+		case XOR: result += " ^ "; break;
+		case IMPLIES: result += " => "; break;
+		}
+		result += right->toString();
+
+		return result;
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::BinaryBooleanFunctionExpression,
+    (storm::ir::expressions::BaseExpression*, left)
+    (storm::ir::expressions::BaseExpression*, right)
+    (storm::ir::expressions::BinaryBooleanFunctionExpression::FunctorType, functor)
+)
+
+#endif /* BINARYBOOLEANFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryNumericalFunctionExpression.h b/src/ir/expressions/BinaryNumericalFunctionExpression.h
new file mode 100644
index 000000000..9df88dc91
--- /dev/null
+++ b/src/ir/expressions/BinaryNumericalFunctionExpression.h
@@ -0,0 +1,63 @@
+/*
+ * BinaryFunctionExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef BINARYFUNCTIONEXPRESSION_H_
+#define BINARYFUNCTIONEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class BinaryNumericalFunctionExpression : public BaseExpression {
+public:
+	BaseExpression* left;
+	BaseExpression* right;
+	enum FunctorType {PLUS, MINUS, TIMES, DIVIDE} functor;
+
+	BinaryNumericalFunctionExpression(BaseExpression* left, BaseExpression* right, FunctorType functor) {
+		this->left = left;
+		this->right = right;
+		this->functor = functor;
+	}
+
+	virtual ~BinaryNumericalFunctionExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		std::string result = left->toString();
+		switch (functor) {
+		case PLUS: result += " + "; break;
+		case MINUS: result += " - "; break;
+		case TIMES: result += " * "; break;
+		case DIVIDE: result += " / "; break;
+		}
+		result += right->toString();
+
+		return result;
+	}
+
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::BinaryNumericalFunctionExpression,
+    (storm::ir::expressions::BaseExpression*, left)
+    (storm::ir::expressions::BaseExpression*, right)
+    (storm::ir::expressions::BinaryNumericalFunctionExpression::FunctorType, functor)
+)
+
+#endif /* BINARYFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/BinaryRelationExpression.h b/src/ir/expressions/BinaryRelationExpression.h
new file mode 100644
index 000000000..f765d0d85
--- /dev/null
+++ b/src/ir/expressions/BinaryRelationExpression.h
@@ -0,0 +1,64 @@
+/*
+ * BinaryRelationExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef BINARYRELATIONEXPRESSION_H_
+#define BINARYRELATIONEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class BinaryRelationExpression : public BaseExpression {
+public:
+	BaseExpression* left;
+	BaseExpression* right;
+	enum RelationType {EQUAL, LESS, LESS_OR_EQUAL, GREATER, GREATER_OR_EQUAL} relation;
+
+	BinaryRelationExpression(BaseExpression* left, BaseExpression* right, RelationType relation) {
+		this->left = left;
+		this->right = right;
+		this->relation = relation;
+	}
+
+	virtual ~BinaryRelationExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		std::string result = left->toString();
+		switch (relation) {
+		case EQUAL: result += " == "; break;
+		case LESS: result += " < "; break;
+		case LESS_OR_EQUAL: result += " <= "; break;
+		case GREATER: result += " > "; break;
+		case GREATER_OR_EQUAL: result += " >= "; break;
+		}
+		result += right->toString();
+
+		return result;
+	}
+
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::BinaryRelationExpression,
+    (storm::ir::expressions::BaseExpression*, left)
+    (storm::ir::expressions::BaseExpression*, right)
+    (storm::ir::expressions::BinaryRelationExpression::RelationType, relation)
+)
+
+#endif /* BINARYRELATIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/BooleanLiteral.h b/src/ir/expressions/BooleanLiteral.h
new file mode 100644
index 000000000..c2300cded
--- /dev/null
+++ b/src/ir/expressions/BooleanLiteral.h
@@ -0,0 +1,51 @@
+/*
+ * BooleanLiteral.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef BOOLEANLITERAL_H_
+#define BOOLEANLITERAL_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class BooleanLiteral : public BaseExpression {
+public:
+	bool value;
+
+	BooleanLiteral(bool value) {
+		this->value = value;
+	}
+
+	virtual ~BooleanLiteral() {
+
+	}
+
+	virtual std::string toString() const {
+		if (value) {
+			return std::string("true");
+		} else {
+			return std::string("false");
+		}
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::BooleanLiteral,
+    (bool, value)
+)
+
+#endif /* BOOLEANLITERAL_H_ */
diff --git a/src/ir/expressions/ConstantExpression.h b/src/ir/expressions/ConstantExpression.h
new file mode 100644
index 000000000..38581d1e4
--- /dev/null
+++ b/src/ir/expressions/ConstantExpression.h
@@ -0,0 +1,47 @@
+/*
+ * ConstantExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef CONSTANTEXPRESSION_H_
+#define CONSTANTEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class ConstantExpression : public BaseExpression {
+public:
+	std::string constantName;
+
+	ConstantExpression(std::string constantName) {
+		this->constantName = constantName;
+	}
+
+	virtual ~ConstantExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		return constantName;
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::ConstantExpression,
+    (std::string, constantName)
+)
+
+#endif /* CONSTANTEXPRESSION_H_ */
diff --git a/src/ir/expressions/DoubleLiteral.h b/src/ir/expressions/DoubleLiteral.h
new file mode 100644
index 000000000..8aca54125
--- /dev/null
+++ b/src/ir/expressions/DoubleLiteral.h
@@ -0,0 +1,47 @@
+/*
+ * DoubleLiteral.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef DOUBLELITERAL_H_
+#define DOUBLELITERAL_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class DoubleLiteral : public BaseExpression {
+public:
+	double value;
+
+	DoubleLiteral(double value) {
+		this->value = value;
+	}
+
+	virtual ~DoubleLiteral() {
+
+	}
+
+	virtual std::string toString() const {
+		return boost::lexical_cast<std::string>(value);
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::DoubleLiteral,
+    (double, value)
+)
+
+#endif /* DOUBLELITERAL_H_ */
diff --git a/src/ir/expressions/Expressions.h b/src/ir/expressions/Expressions.h
new file mode 100644
index 000000000..868fff365
--- /dev/null
+++ b/src/ir/expressions/Expressions.h
@@ -0,0 +1,21 @@
+/*
+ * Expressions.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef EXPRESSIONS_H_
+#define EXPRESSIONS_H_
+
+#include "BinaryBooleanFunctionExpression.h"
+#include "BinaryNumericalFunctionExpression.h"
+#include "BinaryRelationExpression.h"
+#include "BooleanLiteral.h"
+#include "DoubleLiteral.h"
+#include "IntegerLiteral.h"
+#include "UnaryBooleanFunctionExpression.h"
+#include "UnaryNumericalFunctionExpression.h"
+#include "VariableExpression.h"
+
+#endif /* EXPRESSIONS_H_ */
diff --git a/src/ir/expressions/IntegerLiteral.h b/src/ir/expressions/IntegerLiteral.h
new file mode 100644
index 000000000..bea4c1743
--- /dev/null
+++ b/src/ir/expressions/IntegerLiteral.h
@@ -0,0 +1,47 @@
+/*
+ * IntegerLiteral.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef INTEGERLITERAL_H_
+#define INTEGERLITERAL_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class IntegerLiteral : public BaseExpression {
+public:
+	int value;
+
+	IntegerLiteral(int value) {
+		this->value = value;
+	}
+
+	virtual ~IntegerLiteral() {
+
+	}
+
+	virtual std::string toString() const {
+		return boost::lexical_cast<std::string>(value);
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::IntegerLiteral,
+    (int, value)
+)
+
+#endif /* INTEGERLITERAL_H_ */
diff --git a/src/ir/expressions/UnaryBooleanFunctionExpression.h b/src/ir/expressions/UnaryBooleanFunctionExpression.h
new file mode 100644
index 000000000..14c75a87f
--- /dev/null
+++ b/src/ir/expressions/UnaryBooleanFunctionExpression.h
@@ -0,0 +1,56 @@
+/*
+ * UnaryBooleanFunctionExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef UNARYBOOLEANFUNCTIONEXPRESSION_H_
+#define UNARYBOOLEANFUNCTIONEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class UnaryBooleanFunctionExpression : public BaseExpression {
+public:
+	BaseExpression* child;
+	enum FunctorType {NOT} functor;
+
+	UnaryBooleanFunctionExpression(BaseExpression* child, FunctorType functor) {
+		this->child = child;
+		this->functor = functor;
+	}
+
+	virtual ~UnaryBooleanFunctionExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		std::string result = "";
+		switch (functor) {
+		case NOT: result += "!"; break;
+		}
+		result += child->toString();
+
+		return result;
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::UnaryBooleanFunctionExpression,
+    (storm::ir::expressions::BaseExpression*, child)
+    (storm::ir::expressions::UnaryBooleanFunctionExpression::FunctorType, functor)
+)
+
+#endif /* UNARYBOOLEANFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/UnaryNumericalFunctionExpression.h b/src/ir/expressions/UnaryNumericalFunctionExpression.h
new file mode 100644
index 000000000..c367cffd2
--- /dev/null
+++ b/src/ir/expressions/UnaryNumericalFunctionExpression.h
@@ -0,0 +1,56 @@
+/*
+ * UnaryFunctionExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef UNARYFUNCTIONEXPRESSION_H_
+#define UNARYFUNCTIONEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class UnaryNumericalFunctionExpression : public BaseExpression {
+public:
+	BaseExpression* child;
+	enum FunctorType {MINUS} functor;
+
+	UnaryNumericalFunctionExpression(BaseExpression* child, FunctorType functor) {
+		this->child = child;
+		this->functor = functor;
+	}
+
+	virtual ~UnaryNumericalFunctionExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		std::string result = "";
+		switch (functor) {
+		case MINUS: result += "-"; break;
+		}
+		result += child->toString();
+
+		return result;
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::UnaryNumericalFunctionExpression,
+    (storm::ir::expressions::BaseExpression*, child)
+    (storm::ir::expressions::UnaryNumericalFunctionExpression::FunctorType, functor)
+)
+
+#endif /* UNARYFUNCTIONEXPRESSION_H_ */
diff --git a/src/ir/expressions/VariableExpression.h b/src/ir/expressions/VariableExpression.h
new file mode 100644
index 000000000..9a1121503
--- /dev/null
+++ b/src/ir/expressions/VariableExpression.h
@@ -0,0 +1,47 @@
+/*
+ * VariableExpression.h
+ *
+ *  Created on: 03.01.2013
+ *      Author: chris
+ */
+
+#ifndef VARIABLEEXPRESSION_H_
+#define VARIABLEEXPRESSION_H_
+
+#include "src/ir/expressions/BaseExpression.h"
+
+namespace storm {
+
+namespace ir {
+
+namespace expressions {
+
+class VariableExpression : public BaseExpression {
+public:
+	std::string variableName;
+
+	VariableExpression(std::string variableName) {
+		this->variableName = variableName;
+	}
+
+	virtual ~VariableExpression() {
+
+	}
+
+	virtual std::string toString() const {
+		return variableName;
+	}
+};
+
+}
+
+}
+
+}
+
+BOOST_FUSION_ADAPT_STRUCT(
+    storm::ir::expressions::VariableExpression,
+    (std::string, variableName)
+)
+
+#endif /* VARIABLEEXPRESSION_H_ */
diff --git a/src/parser/PrismParser.h b/src/parser/PrismParser.h
index 5b74df99a..a8073bb95 100644
--- a/src/parser/PrismParser.h
+++ b/src/parser/PrismParser.h
@@ -15,25 +15,7 @@
 #include <boost/fusion/include/adapt_struct.hpp>
 #include <boost/fusion/include/io.hpp>
 
-namespace storm {
-namespace parser {
-class intConstDef {
-public:
-	std::string name;
-	int value;
-
-	void print() {
-		std::cout << "(" << name << ", " << value << ")" << std::endl;
-	}
-};
-}
-}
-
-BOOST_FUSION_ADAPT_STRUCT(
-    storm::parser::intConstDef,
-    (std::string, name)
-    (int, value)
-)
+#include "src/ir/expressions/Expressions.h"
 
 namespace storm {
 
@@ -41,6 +23,7 @@ namespace parser {
 
 namespace qi = boost::spirit::qi;
 namespace ascii = boost::spirit::ascii;
+namespace phoenix = boost::phoenix;
 
 class PrismParser {
 
@@ -51,7 +34,7 @@ public:
 		std::string::const_iterator end = str.end();
 		prismGrammar<std::string::const_iterator> grammar;
 
-		intConstDef result;
+		storm::ir::expressions::BaseExpression* result;
 		bool r = phrase_parse(iter, end, grammar, ascii::space, result);
 
 		std::cout << r << std::endl;
@@ -59,8 +42,7 @@ public:
 		if (r && iter == end) {
 			std::cout << "-------------------------\n";
 			std::cout << "Parsing succeeded\n";
-			result.print();
-			// std::cout << "result = " << result << std::endl;
+			std::cout << "result = " << result << std::endl;
 			std::cout << "-------------------------\n";
 		} else {
 			std::string rest(iter, end);
@@ -72,19 +54,59 @@ public:
 	}
 
 private:
+	struct keywords_ : qi::symbols<char, unsigned> {
+		keywords_() {
+			add
+				("dtmc", 1)
+				("ctmc", 2)
+				("mdp", 3)
+				("ctmdp", 4)
+				("const", 5)
+				("int", 6)
+				("bool", 7)
+				("module", 8)
+				("endmodule", 9)
+				("rewards", 10)
+				("endrewards", 11)
+				("true", 12)
+				("false", 13)
+			;
+		}
+	};
+
+	struct variables_ : qi::symbols<char, std::string> {
+		// Intentionally left empty. This map is filled during parsing.
+	};
+
+	struct modules_ : qi::symbols<char, unsigned> {
+		// Intentionally left empty. This map is filled during parsing.
+	};
+
 	template<typename Iterator>
-	struct prismGrammar : qi::grammar<Iterator, intConstDef(), ascii::space_type> {
+	struct prismGrammar : qi::grammar<Iterator, storm::ir::expressions::BaseExpression*(), ascii::space_type> {
 
 		prismGrammar() : prismGrammar::base_type(start) {
-			identifierName %= +(qi::char_);
-			integerConstantDefinition %= qi::lit("const") >> qi::lit("int") >> identifierName >> "=" >> qi::int_ >> ";";
+			// identifierName %= qi::lexeme[qi::char_("a-zA-Z_") >> *qi::char_("a-zA-Z_0-9")];
+			// integerConstantDefinition %= qi::lit("const") >> qi::lit("int") >> identifierName >> "=" >> qi::int_ >> ";";
+
+			start %= literalExpression;
 
-			start %= integerConstantDefinition;
+			literalExpression %= (booleanLiteralExpression | integerLiteralExpression | doubleLiteralExpression);
+			booleanLiteralExpression = qi::bool_[qi::_val = phoenix::new_<storm::ir::expressions::BooleanLiteral>(qi::_1)];
+			integerLiteralExpression = qi::int_[qi::_val = phoenix::new_<storm::ir::expressions::IntegerLiteral>(qi::_1)];
+			doubleLiteralExpression = qi::double_[qi::_val = phoenix::new_<storm::ir::expressions::DoubleLiteral>(qi::_1)];
 		}
 
-		qi::rule<Iterator, intConstDef(), ascii::space_type> start;
-		qi::rule<Iterator, intConstDef(), ascii::space_type> integerConstantDefinition;
-		qi::rule<Iterator, std::string(), ascii::space_type> identifierName;
+		qi::rule<Iterator, storm::ir::expressions::BaseExpression*(), ascii::space_type> start;
+
+		// The expression rules.
+		qi::rule<Iterator, storm::ir::expressions::BaseExpression*(), ascii::space_type> literalExpression;
+		qi::rule<Iterator, storm::ir::expressions::BaseExpression*(), ascii::space_type> booleanLiteralExpression;
+		qi::rule<Iterator, storm::ir::expressions::BaseExpression*(), ascii::space_type> integerLiteralExpression;
+		qi::rule<Iterator, storm::ir::expressions::BaseExpression*(), ascii::space_type> doubleLiteralExpression;
+
+		// qi::rule<Iterator, intConstDef(), ascii::space_type> integerConstantDefinition;
+		// qi::rule<Iterator, std::string(), ascii::space_type> identifierName;
 
 	};
 };