/* * File: Keywords.h * Author: nafur * * Created on April 10, 2013, 6:03 PM */ #ifndef BASEGRAMMAR_H #define BASEGRAMMAR_H #include "Includes.h" #include "VariableState.h" namespace storm { namespace parser { namespace prism { /*! * This is the base class for all expression grammars. * It takes care of implementing a singleton, stores a VariableState and implements some common helper routines. */ template class BaseGrammar { public: /*! * Constructor. */ BaseGrammar(std::shared_ptr& state) : state(state) {} /*! * Create and return a new instance of class T, usually the subclass. * @param state VariableState to be given to the constructor. * @returns Instance of class T. */ static T& instance(std::shared_ptr state = nullptr) { if (BaseGrammar::instanceObject == nullptr) { BaseGrammar::instanceObject = std::shared_ptr(new T(state)); if (!state->firstRun) BaseGrammar::instanceObject->secondRun(); } return *BaseGrammar::instanceObject; } /*! * Clear the cached instance. */ static void resetInstance() { BaseGrammar::instanceObject = nullptr; } /*! * Notify the cached object, that we will begin with the second parsing run. */ static void secondRun() { if (BaseGrammar::instanceObject != nullptr) { BaseGrammar::instanceObject->prepareSecondRun(); } } /*! * Create a new boolean literal with the given value. * @param value Value of the literal. * @returns Boolean literal. */ std::shared_ptr createBoolLiteral(const bool value) { return std::shared_ptr(new BooleanLiteralExpression(value)); } /*! * Create a new double literal with the given value. * @param value Value of the literal. * @returns Double literal. */ std::shared_ptr createDoubleLiteral(const double value) { return std::shared_ptr(new DoubleLiteralExpression(value)); } /*! * Create a new integer literal with the given value. * @param value Value of the literal. * @returns Integer literal. */ std::shared_ptr createIntLiteral(const int_fast64_t value) { return std::shared_ptr(new IntegerLiteralExpression(value)); } /*! * Create a new plus expression. If addition is true, it will be an addition, otherwise a subtraction. * @param left Left operand. * @param addition Flag for addition or subtraction. * @param right Right operand. * @param type Return type. * @returns Plus expression. */ std::shared_ptr createPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right, BaseExpression::ReturnType type) { if (addition) { return std::shared_ptr(new BinaryNumericalFunctionExpression(type, left, right, BinaryNumericalFunctionExpression::PLUS)); } else { return std::shared_ptr(new BinaryNumericalFunctionExpression(type, left, right, BinaryNumericalFunctionExpression::MINUS)); } } /*! * Create a new double plus expression. If addition is true, it will be an addition, otherwise a subtraction. * @param left Left operand. * @param addition Flag for addition or subtraction. * @param right Right operand. * @returns Double plus expression. */ std::shared_ptr createDoublePlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { return this->createPlus(left, addition, right, BaseExpression::double_); } /*! * Create a new integer plus expression. If addition is true, it will be an addition, otherwise a subtraction. * @param left Left operand. * @param addition Flag for addition or subtraction. * @param right Right operand. * @returns Integer plus expression. */ std::shared_ptr createIntPlus(const std::shared_ptr left, bool addition, const std::shared_ptr right) { return this->createPlus(left, addition, right, BaseExpression::int_); } /*! * Create a new integer multiplication expression. * @param left Left operand. * @param right Right operand. * @returns Integer multiplication expression. */ std::shared_ptr createIntMult(const std::shared_ptr left, const std::shared_ptr right) { return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::int_, left, right, BinaryNumericalFunctionExpression::TIMES)); } /*! * Create a new integer multiplication expression. If multiplication is true, it will be an multiplication, otherwise a division. * @param left Left operand. * @param addition Flag for multiplication or division. * @param right Right operand. * @returns Integer multiplication expression. */ std::shared_ptr createDoubleMult(const std::shared_ptr left, bool multiplication, const std::shared_ptr right) { if (multiplication) { return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::TIMES)); } else { return std::shared_ptr(new BinaryNumericalFunctionExpression(BaseExpression::double_, left, right, BinaryNumericalFunctionExpression::DIVIDE)); } } /*! * Create a new binary relation expression. * @param left Left operand. * @param relationType Type of binary relation. * @param right Right operand. * @returns Binary relation expression. */ std::shared_ptr createRelation(std::shared_ptr left, BinaryRelationExpression::RelationType relationType, std::shared_ptr right) { return std::shared_ptr(new BinaryRelationExpression(left, right, relationType)); } /*! * Create a new negation expression. * @param child Expression to be negated. * @returns Negation expression. */ std::shared_ptr createNot(std::shared_ptr child) { return std::shared_ptr(new UnaryBooleanFunctionExpression(child, UnaryBooleanFunctionExpression::NOT)); } /*! * Create a new And expression. * @param left Left operand. * @param right Right operand. * @returns And expression. */ std::shared_ptr createAnd(std::shared_ptr left, std::shared_ptr right) { //std::cerr << "Creating " << left->toString() << " & " << right->toString() << std::endl; return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::AND)); } /*! * Create a new Or expression. * @param left Left operand. * @param right Right operand. * @returns Or expression. */ std::shared_ptr createOr(std::shared_ptr left, std::shared_ptr right) { return std::shared_ptr(new BinaryBooleanFunctionExpression(left, right, BinaryBooleanFunctionExpression::OR)); } /*! * Retrieve boolean variable by name. * @param name Variable name. * @returns Boolean variable. */ std::shared_ptr getBoolVariable(const std::string name) { return state->getBooleanVariableExpression(name); } /*! * Retrieve integer variable by name. * @param name Variable name. * @returns Integer variable. */ std::shared_ptr getIntVariable(const std::string name) { return state->getIntegerVariableExpression(name); } /*! * Base method to switch to second run. This does nothing. * Any subclass that needs to do something in order to proceed to the second run should override this method. */ virtual void prepareSecondRun() {} protected: /*! * Pointer to variable state. */ std::shared_ptr state; private: static std::shared_ptr instanceObject; static bool inSecondRun; }; template std::shared_ptr BaseGrammar::instanceObject; } } } #endif /* BASEGRAMMAR_H */