Browse Source
			
			
			Further work on PrismParser and the related PRISM classes...
			
				
		Further work on PrismParser and the related PRISM classes...
	
		
	
			
				Former-commit-id: be4ae055dd
			
			
				main
			
			
		
				 23 changed files with 925 additions and 385 deletions
			
			
		- 
					98src/parser/PrismParser.cpp
 - 
					35src/parser/PrismParser.h
 - 
					415src/parser/prismparser/PrismGrammar.cpp
 - 
					230src/parser/prismparser/PrismGrammar.h
 - 
					70src/parser/prismparser/PrismParser.cpp
 - 
					36src/parser/prismparser/PrismParser.h
 - 
					4src/storage/expressions/BinaryBooleanFunctionExpression.cpp
 - 
					4src/storage/expressions/Expression.cpp
 - 
					1src/storage/expressions/Expression.h
 - 
					4src/storage/prism/BooleanVariable.h
 - 
					8src/storage/prism/Command.cpp
 - 
					3src/storage/prism/Command.h
 - 
					3src/storage/prism/Constant.cpp
 - 
					2src/storage/prism/IntegerVariable.cpp
 - 
					8src/storage/prism/LocatedInformation.cpp
 - 
					14src/storage/prism/LocatedInformation.h
 - 
					37src/storage/prism/Module.cpp
 - 
					6src/storage/prism/Module.h
 - 
					106src/storage/prism/Program.cpp
 - 
					49src/storage/prism/Program.h
 - 
					15src/storage/prism/Update.cpp
 - 
					5src/storage/prism/Update.h
 - 
					157test/functional/parser/PrismParserTest.cpp
 
@ -1,98 +0,0 @@ | 
				
			|||
#include "src/parser/PrismParser.h"
 | 
				
			|||
 | 
				
			|||
#include "src/parser/prismparser/PrismGrammar.h"
 | 
				
			|||
 | 
				
			|||
// If the parser fails due to ill-formed data, this exception is thrown.
 | 
				
			|||
#include "src/exceptions/WrongFormatException.h"
 | 
				
			|||
 | 
				
			|||
// Needed for file IO.
 | 
				
			|||
#include <fstream>
 | 
				
			|||
#include <iomanip>
 | 
				
			|||
#include <limits>
 | 
				
			|||
 | 
				
			|||
#include "log4cplus/logger.h"
 | 
				
			|||
#include "log4cplus/loggingmacros.h"
 | 
				
			|||
#include "log4cplus/consoleappender.h"
 | 
				
			|||
#include "log4cplus/fileappender.h"
 | 
				
			|||
log4cplus::Logger logger; | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace parser { | 
				
			|||
        storm::prism::Program PrismParserFromFile(std::string const& filename) { | 
				
			|||
            // Open file and initialize result.
 | 
				
			|||
            std::ifstream inputFileStream(filename, std::ios::in); | 
				
			|||
            storm::prism::Program result; | 
				
			|||
             | 
				
			|||
            // Now try to parse the contents of the file.
 | 
				
			|||
            try { | 
				
			|||
                result = PrismParser(inputFileStream, filename); | 
				
			|||
            } catch(std::exception& e) { | 
				
			|||
                // In case of an exception properly close the file before passing exception.
 | 
				
			|||
                inputFileStream.close(); | 
				
			|||
                throw e; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            // Close the stream in case everything went smoothly and return result.
 | 
				
			|||
            inputFileStream.close(); | 
				
			|||
            return result; | 
				
			|||
        } | 
				
			|||
         | 
				
			|||
        storm::prism::Program PrismParser(std::istream& inputStream, std::string const& filename) { | 
				
			|||
            // Prepare iterators to input.
 | 
				
			|||
            // TODO: Right now, this parses the whole contents of the file into a string first.
 | 
				
			|||
            // While this is usually not necessary, because there exist adapters that make an input stream
 | 
				
			|||
            // iterable in both directions without storing it into a string, using the corresponding
 | 
				
			|||
            // Boost classes gives an awful output under valgrind and is thus disabled for the time being.
 | 
				
			|||
            std::string fileContent((std::istreambuf_iterator<char>(inputStream)), (std::istreambuf_iterator<char>())); | 
				
			|||
            BaseIteratorType stringIteratorBegin = fileContent.begin(); | 
				
			|||
            BaseIteratorType stringIteratorEnd = fileContent.end(); | 
				
			|||
            PositionIteratorType positionIteratorBegin(stringIteratorBegin, stringIteratorEnd, filename); | 
				
			|||
            PositionIteratorType positionIteratorBegin2(stringIteratorBegin, stringIteratorEnd, filename); | 
				
			|||
            PositionIteratorType positionIteratorEnd; | 
				
			|||
             | 
				
			|||
            // Prepare resulting intermediate representation of input.
 | 
				
			|||
            storm::prism::Program result; | 
				
			|||
             | 
				
			|||
            // In order to instantiate the grammar, we have to pass the type of the skipping parser.
 | 
				
			|||
            // As this is more complex, we let Boost figure out the actual type for us.
 | 
				
			|||
            storm::parser::prism::PrismGrammar grammar; | 
				
			|||
            try { | 
				
			|||
                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
 | 
				
			|||
                // First run.
 | 
				
			|||
                LOG4CPLUS_INFO(logger, "Start parsing..."); | 
				
			|||
                qi::phrase_parse(positionIteratorBegin, positionIteratorEnd, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); | 
				
			|||
                LOG4CPLUS_INFO(logger, "Finished parsing, here is the parsed program:" << std::endl << result); | 
				
			|||
 | 
				
			|||
            } catch(const qi::expectation_failure<PositionIteratorType>& e) { | 
				
			|||
                // If the parser expected content different than the one provided, display information
 | 
				
			|||
                // about the location of the error.
 | 
				
			|||
                const boost::spirit::classic::file_position_base<std::string>& pos = e.first.get_position(); | 
				
			|||
                 | 
				
			|||
                // Construct the error message including a caret display of the position in the
 | 
				
			|||
                // erroneous line.
 | 
				
			|||
                std::stringstream msg; | 
				
			|||
                std::string line = e.first.get_currentline(); | 
				
			|||
                while (line.find('\t') != std::string::npos) line.replace(line.find('\t'),1," "); | 
				
			|||
                msg << pos.file << ", line " << pos.line << ", column " << pos.column | 
				
			|||
				<< ": parse error: expected " << e.what_ << std::endl << "\t" | 
				
			|||
				<< line << std::endl << "\t"; | 
				
			|||
                int i = 0; | 
				
			|||
                for (i = 1; i < pos.column; ++i) { | 
				
			|||
                    msg << "-"; | 
				
			|||
                } | 
				
			|||
                msg << "^"; | 
				
			|||
                for (; i < 80; ++i) { | 
				
			|||
                    msg << "-"; | 
				
			|||
                } | 
				
			|||
                msg << std::endl; | 
				
			|||
                 | 
				
			|||
                std::cerr << msg.str(); | 
				
			|||
                 | 
				
			|||
                // Now propagate exception.
 | 
				
			|||
                throw storm::exceptions::WrongFormatException() << msg.str(); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            return result; | 
				
			|||
        } | 
				
			|||
    } // namespace parser
 | 
				
			|||
} // namespace storm
 | 
				
			|||
@ -1,35 +0,0 @@ | 
				
			|||
#ifndef STORM_PARSER_PRISMPARSER_H_ | 
				
			|||
#define STORM_PARSER_PRISMPARSER_H_ | 
				
			|||
 | 
				
			|||
// All classes of the intermediate representation are used. | 
				
			|||
#include "src/storage/prism/Program.h" | 
				
			|||
 | 
				
			|||
// Used for file input. | 
				
			|||
#include <istream> | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace parser { | 
				
			|||
        using namespace storm::prism; | 
				
			|||
        using namespace storm::expressions; | 
				
			|||
         | 
				
			|||
        /*! | 
				
			|||
         * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax. | 
				
			|||
         * | 
				
			|||
         * @param filename the name of the file to parse. | 
				
			|||
         * @return The resulting PRISM program. | 
				
			|||
         */ | 
				
			|||
        storm::prism::Program PrismParserFromFile(std::string const& filename); | 
				
			|||
         | 
				
			|||
        /*! | 
				
			|||
         * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax. | 
				
			|||
         * | 
				
			|||
         * @param inputStream The input stream to parse. | 
				
			|||
         * @param filename The name of the file the input stream belongs to. | 
				
			|||
         * @return The resulting PRISM program. | 
				
			|||
         */ | 
				
			|||
        storm::prism::Program PrismParser(std::istream& inputStream, std::string const& filename); | 
				
			|||
         | 
				
			|||
    } // namespace parser | 
				
			|||
} // namespace storm | 
				
			|||
 | 
				
			|||
#endif /* STORM_PARSER_PRISMPARSER_H_ */ | 
				
			|||
@ -1,153 +1,372 @@ | 
				
			|||
// #define BOOST_SPIRIT_DEBUG
 | 
				
			|||
#include "src/parser/prismparser/PrismGrammar.h"
 | 
				
			|||
#include "src/exceptions/InvalidArgumentException.h"
 | 
				
			|||
#include "src/exceptions/WrongFormatException.h"
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace parser { | 
				
			|||
        namespace prism { | 
				
			|||
            PrismGrammar::PrismGrammar() : PrismGrammar::base_type(start) { | 
				
			|||
            PrismGrammar::PrismGrammar(std::string const& filename, Iterator first) : PrismGrammar::base_type(start), doExpressionGeneration(false), filename(filename), annotate(first) { | 
				
			|||
                // Parse simple identifier.
 | 
				
			|||
                identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]] - keywords_; | 
				
			|||
                identifier %= qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))]]][qi::_pass = phoenix::bind(&PrismGrammar::isValidIdentifier, phoenix::ref(*this), qi::_1)]; | 
				
			|||
                identifier.name("identifier"); | 
				
			|||
                 | 
				
			|||
                // Parse a composed expression.
 | 
				
			|||
                expression %= (booleanExpression | numericalExpression); | 
				
			|||
                expression.name("expression"); | 
				
			|||
                setExpressionGeneration(doExpressionGeneration); | 
				
			|||
                 | 
				
			|||
                booleanExpression %= orExpression; | 
				
			|||
                expression.name("boolean expression"); | 
				
			|||
                 | 
				
			|||
                orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = qi::_val * qi::_1]; | 
				
			|||
                orExpression.name("boolean expression"); | 
				
			|||
                 | 
				
			|||
                andExpression = notExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> notExpression)[qi::_val = qi::_val * qi::_1]; | 
				
			|||
                andExpression.name("boolean expression"); | 
				
			|||
                 | 
				
			|||
                notExpression = atomicBooleanExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicBooleanExpression)[qi::_val = !qi::_1]; | 
				
			|||
                notExpression.name("boolean expression"); | 
				
			|||
                 | 
				
			|||
                atomicBooleanExpression %= relativeExpression | booleanVariableExpression | qi::lit("(") >> booleanExpression >> qi::lit(")"); | 
				
			|||
                atomicBooleanExpression.name("boolean expression"); | 
				
			|||
                 | 
				
			|||
                relativeExpression = ((numericalExpression >> ">") > numericalExpression)[qi::_val = qi::_1 > qi::_2] | ((numericalExpression >> ">=") > numericalExpression)[qi::_val = qi::_1 >= qi::_2] | ((numericalExpression >> "<") > numericalExpression)[qi::_val = qi::_1 < qi::_2] | ((numericalExpression >> "<=") > numericalExpression)[qi::_val = qi::_1 <= qi::_2]; | 
				
			|||
                relativeExpression.name("relative expression"); | 
				
			|||
                 | 
				
			|||
                booleanVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createBooleanVariable, qi::_1)]; | 
				
			|||
                booleanVariableExpression.name("boolean variable"); | 
				
			|||
                 | 
				
			|||
                numericalExpression %= plusExpression; | 
				
			|||
                numericalExpression.name("numerical expression"); | 
				
			|||
                 | 
				
			|||
                plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = qi::_val + qi::_1] .else_ [qi::_val = qi::_val - qi::_1]]; | 
				
			|||
                plusExpression.name("numerical expression"); | 
				
			|||
                 | 
				
			|||
                multiplicationExpression = atomicNumericalExpression[qi::_val = qi::_1] >> *(qi::lit("*") >> atomicNumericalExpression[qi::_val = qi::_val * qi::_1]); | 
				
			|||
                multiplicationExpression.name("numerical expression"); | 
				
			|||
                 | 
				
			|||
                atomicNumericalExpression %= minMaxExpression | floorCeilExpression | numericalVariableExpression | qi::lit("(") >> numericalExpression >> qi::lit(")"); | 
				
			|||
                atomicNumericalExpression.name("numerical expression"); | 
				
			|||
                 | 
				
			|||
                minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(",") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]]; | 
				
			|||
                minMaxExpression.name("min/max expression"); | 
				
			|||
                 | 
				
			|||
                floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> numericalExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]]; | 
				
			|||
                floorCeilExpression.name("integer floor/ceil expression"); | 
				
			|||
 | 
				
			|||
                numericalVariableExpression = identifier[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleVariable, qi::_1)]; | 
				
			|||
                numericalVariableExpression.name("numerical variable"); | 
				
			|||
                 | 
				
			|||
                modelTypeDefinition = modelType_; | 
				
			|||
                modelTypeDefinition %= modelType_; | 
				
			|||
                modelTypeDefinition.name("model type"); | 
				
			|||
                 | 
				
			|||
                undefinedConstantDefinition = (undefinedBooleanConstantDefinition(qi::_r1) | undefinedIntegerConstantDefinition(qi::_r1) | undefinedDoubleConstantDefinition(qi::_r1)); | 
				
			|||
                undefinedConstantDefinition.name("undefined constant definition"); | 
				
			|||
 | 
				
			|||
                undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedBooleanConstant, phoenix::bind(&GlobalProgramInformation::undefinedBooleanConstants, qi::_r1), qi::_1)]; | 
				
			|||
                undefinedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedBooleanConstant, phoenix::ref(*this), qi::_1)]; | 
				
			|||
                undefinedBooleanConstantDefinition.name("undefined boolean constant declaration"); | 
				
			|||
 | 
				
			|||
                undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedIntegerConstant, phoenix::bind(&GlobalProgramInformation::undefinedIntegerConstants, qi::_r1), qi::_1)]; | 
				
			|||
                undefinedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedIntegerConstant, phoenix::ref(*this), qi::_1)]; | 
				
			|||
                undefinedIntegerConstantDefinition.name("undefined integer constant declaration"); | 
				
			|||
                 | 
				
			|||
                undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addUndefinedDoubleConstant, phoenix::bind(&GlobalProgramInformation::undefinedDoubleConstants, qi::_r1), qi::_1)]; | 
				
			|||
                undefinedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double")) > identifier > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createUndefinedDoubleConstant, phoenix::ref(*this), qi::_1)]; | 
				
			|||
                undefinedDoubleConstantDefinition.name("undefined double constant definition"); | 
				
			|||
 | 
				
			|||
                definedConstantDefinition %= (definedBooleanConstantDefinition(qi::_r1) | definedIntegerConstantDefinition(qi::_r1) | definedDoubleConstantDefinition(qi::_r1)); | 
				
			|||
                definedConstantDefinition.name("defined constant definition"); | 
				
			|||
                undefinedConstantDefinition = (undefinedBooleanConstantDefinition | undefinedIntegerConstantDefinition | undefinedDoubleConstantDefinition); | 
				
			|||
                undefinedConstantDefinition.name("undefined constant definition"); | 
				
			|||
 | 
				
			|||
                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedBooleanConstant, phoenix::bind(&GlobalProgramInformation::definedBooleanConstants, qi::_r1), qi::_1, qi::_2)]; | 
				
			|||
                definedBooleanConstantDefinition = ((qi::lit("const") >> qi::lit("bool") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedBooleanConstant, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                definedBooleanConstantDefinition.name("defined boolean constant declaration"); | 
				
			|||
 | 
				
			|||
                definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedIntegerConstant, phoenix::bind(&GlobalProgramInformation::definedIntegerConstants, qi::_r1), qi::_1, qi::_2)]; | 
				
			|||
                definedIntegerConstantDefinition = ((qi::lit("const") >> qi::lit("int") >> identifier >> qi::lit("=")) > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedIntegerConstant, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                definedIntegerConstantDefinition.name("defined integer constant declaration"); | 
				
			|||
 | 
				
			|||
                definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addDefinedDoubleConstant, phoenix::bind(&GlobalProgramInformation::definedDoubleConstants, qi::_r1), qi::_1, qi::_2)]; | 
				
			|||
                definedDoubleConstantDefinition = ((qi::lit("const") >> qi::lit("double") >> identifier >> qi::lit("=")) > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createDefinedDoubleConstant, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                definedDoubleConstantDefinition.name("defined double constant declaration"); | 
				
			|||
                 | 
				
			|||
                formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addFormula, phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1, qi::_2)]; | 
				
			|||
                definedConstantDefinition %= (definedBooleanConstantDefinition | definedIntegerConstantDefinition | definedDoubleConstantDefinition); | 
				
			|||
                definedConstantDefinition.name("defined constant definition"); | 
				
			|||
                 | 
				
			|||
                formulaDefinition = (qi::lit("formula") > identifier > qi::lit("=") > expression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createFormula, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                formulaDefinition.name("formula definition"); | 
				
			|||
                 | 
				
			|||
                globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1)) | integerVariableDefinition(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1)))); | 
				
			|||
                booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > expression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createBooleanVariable, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                booleanVariableDefinition.name("boolean variable definition"); | 
				
			|||
                 | 
				
			|||
                integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")[phoenix::bind(&PrismGrammar::allowDoubleLiterals, phoenix::ref(*this), false)]) > expression[qi::_a = qi::_1] > qi::lit("..") > expression > qi::lit("]")[phoenix::bind(&PrismGrammar::allowDoubleLiterals, phoenix::ref(*this), true)] > -(qi::lit("init") > expression[qi::_a = qi::_1]) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createIntegerVariable, phoenix::ref(*this), qi::_1, qi::_2, qi::_3, qi::_a)]; | 
				
			|||
                integerVariableDefinition.name("integer variable definition"); | 
				
			|||
                 | 
				
			|||
                variableDefinition = (booleanVariableDefinition[phoenix::push_back(qi::_r1, qi::_1)] | integerVariableDefinition[phoenix::push_back(qi::_r2, qi::_1)]); | 
				
			|||
                variableDefinition.name("variable declaration"); | 
				
			|||
                 | 
				
			|||
                globalVariableDefinition = (qi::lit("global") > (booleanVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalBooleanVariables, qi::_r1), qi::_1)] | integerVariableDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::globalIntegerVariables, qi::_r1), qi::_1)])); | 
				
			|||
                globalVariableDefinition.name("global variable declaration list"); | 
				
			|||
                 | 
				
			|||
                programHeader =         modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1] | 
				
			|||
                                >   *(  undefinedConstantDefinition(qi::_r1) | 
				
			|||
                                    |   definedConstantDefinition(qi::_r1) | 
				
			|||
                                    |   formulaDefinition(qi::_r1) | 
				
			|||
                                    |   globalVariableDefinition(qi::_r1) | 
				
			|||
                                    ); | 
				
			|||
                programHeader = modelTypeDefinition[phoenix::bind(&GlobalProgramInformation::modelType, qi::_r1) = qi::_1] | 
				
			|||
                                    >   *(definedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)] | undefinedConstantDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::constants, qi::_r1), qi::_1)]) | 
				
			|||
                                    >   *(formulaDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::formulas, qi::_r1), qi::_1)]) | 
				
			|||
                                    >   *(globalVariableDefinition(qi::_r1)); | 
				
			|||
                programHeader.name("program header"); | 
				
			|||
  | 
				
			|||
                rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"") | 
				
			|||
                                         > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | 
				
			|||
                                            |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)] | 
				
			|||
                                            ) | 
				
			|||
                                         >> qi::lit("endrewards"))[phoenix::bind(&PrismGrammar::addRewardModel, phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_r1), qi::_1, qi::_a, qi::_b)]; | 
				
			|||
                rewardModelDefinition.name("reward model definition"); | 
				
			|||
                 | 
				
			|||
                stateRewardDefinition = (booleanExpression > qi::lit(":") > numericalExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createStateReward, qi::_1, qi::_2)]; | 
				
			|||
                stateRewardDefinition = (expression > qi::lit(":") > plusExpression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createStateReward, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                stateRewardDefinition.name("state reward definition"); | 
				
			|||
                 | 
				
			|||
                transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit(":") > numericalExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createTransitionReward, qi::_a, qi::_2, qi::_3)]; | 
				
			|||
                transitionRewardDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit(":") > plusExpression > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createTransitionReward, phoenix::ref(*this), qi::_a, qi::_2, qi::_3)]; | 
				
			|||
                transitionRewardDefinition.name("transition reward definition"); | 
				
			|||
 | 
				
			|||
                labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > booleanExpression >> qi::lit(";"))[qi::_pass = phoenix::bind(&PrismGrammar::addLabel, phoenix::bind(&GlobalProgramInformation::labels, qi::_r1), qi::_1, qi::_2)]; | 
				
			|||
                rewardModelDefinition = (qi::lit("rewards") > qi::lit("\"") > identifier > qi::lit("\"") | 
				
			|||
                                         > +(   stateRewardDefinition[phoenix::push_back(qi::_a, qi::_1)] | 
				
			|||
                                             |   transitionRewardDefinition[phoenix::push_back(qi::_b, qi::_1)] | 
				
			|||
                                             ) | 
				
			|||
                                         >> qi::lit("endrewards"))[qi::_val = phoenix::bind(&PrismGrammar::createRewardModel, phoenix::ref(*this), qi::_1, qi::_a, qi::_b)]; | 
				
			|||
                rewardModelDefinition.name("reward model definition"); | 
				
			|||
                 | 
				
			|||
                initialStatesConstruct = (qi::lit("init") > expression > qi::lit("endinit"))[qi::_pass = phoenix::bind(&PrismGrammar::addInitialStatesExpression, phoenix::ref(*this), qi::_1, qi::_r1)]; | 
				
			|||
                initialStatesConstruct.name("initial construct"); | 
				
			|||
                 | 
				
			|||
                labelDefinition = (qi::lit("label") > -qi::lit("\"") > identifier > -qi::lit("\"") > qi::lit("=") > expression >> qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createLabel, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                labelDefinition.name("label definition"); | 
				
			|||
 | 
				
			|||
                assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_pass = phoenix::bind(&PrismGrammar::addAssignment, qi::_r1, qi::_1, qi::_2)]; | 
				
			|||
                assignmentDefinition = (qi::lit("(") > identifier > qi::lit("'") > qi::lit("=") > expression > qi::lit(")"))[qi::_val = phoenix::bind(&PrismGrammar::createAssignment, phoenix::ref(*this), qi::_1, qi::_2)]; | 
				
			|||
                assignmentDefinition.name("assignment"); | 
				
			|||
                assignmentDefinitionList = assignmentDefinition(qi::_r1) % "&"; | 
				
			|||
                assignmentDefinitionList.name("assignment list"); | 
				
			|||
                 | 
				
			|||
                moduleDefinitionList %= +(moduleDefinition(qi::_r1) | moduleRenaming(qi::_r1)); | 
				
			|||
                moduleDefinitionList.name("module list"); | 
				
			|||
                assignmentDefinitionList %= +assignmentDefinition % "&"; | 
				
			|||
                assignmentDefinitionList.name("assignment list"); | 
				
			|||
 | 
				
			|||
                updateDefinition = (((numericalExpression >> qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList(qi::_a))[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, qi::_1, qi::_a)]; | 
				
			|||
                updateDefinition = (((plusExpression > qi::lit(":")) | qi::attr(storm::expressions::Expression::createDoubleLiteral(1))) >> assignmentDefinitionList)[qi::_val = phoenix::bind(&PrismGrammar::createUpdate, phoenix::ref(*this), qi::_1, qi::_2, qi::_r1)]; | 
				
			|||
                updateDefinition.name("update"); | 
				
			|||
                 | 
				
			|||
                updateListDefinition %= +updateDefinition % "+"; | 
				
			|||
                updateListDefinition %= +updateDefinition(qi::_r1) % "+"; | 
				
			|||
                updateListDefinition.name("update list"); | 
				
			|||
                 | 
				
			|||
                commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > booleanExpression > qi::lit("->") > updateListDefinition > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createCommand, qi::_a, qi::_2, qi::_3)]; | 
				
			|||
                commandDefinition = (qi::lit("[") > -(identifier[qi::_a = qi::_1]) > qi::lit("]") > expression > qi::lit("->") > updateListDefinition(qi::_r1) > qi::lit(";"))[qi::_val = phoenix::bind(&PrismGrammar::createCommand, phoenix::ref(*this), qi::_a, qi::_2, qi::_3, qi::_r1)]; | 
				
			|||
                commandDefinition.name("command definition"); | 
				
			|||
 | 
				
			|||
                booleanVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("bool")) > ((qi::lit("init") > booleanExpression) | qi::attr(storm::expressions::Expression::createFalse())) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addBooleanVariable, qi::_r1, qi::_1, qi::_2)]; | 
				
			|||
                booleanVariableDefinition.name("boolean variable definition"); | 
				
			|||
                 | 
				
			|||
                integerVariableDefinition = ((identifier >> qi::lit(":") >> qi::lit("[")) > numericalExpression[qi::_a = qi::_1] > qi::lit("..") > numericalExpression > qi::lit("]") > -(qi::lit("init") > numericalExpression[qi::_a = qi::_1]) > qi::lit(";"))[phoenix::bind(&PrismGrammar::addIntegerVariable, qi::_r1, qi::_1, qi::_2, qi::_3, qi::_a)]; | 
				
			|||
                integerVariableDefinition.name("integer variable definition"); | 
				
			|||
                 | 
				
			|||
                variableDefinition = (booleanVariableDefinition(qi::_r1) | integerVariableDefinition(qi::_r2)); | 
				
			|||
                variableDefinition.name("variable declaration"); | 
				
			|||
 | 
				
			|||
                moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createModule, qi::_1, qi::_a, qi::_b, qi::_2)]; | 
				
			|||
                moduleDefinition = ((qi::lit("module") >> identifier >> *(variableDefinition(qi::_a, qi::_b))) > +commandDefinition(qi::_r1) > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createModule, phoenix::ref(*this), qi::_1, qi::_a, qi::_b, qi::_2, qi::_r1)]; | 
				
			|||
                moduleDefinition.name("module definition"); | 
				
			|||
                 | 
				
			|||
                moduleRenaming = ((qi::lit("module")	>> identifier >> qi::lit("=")) > identifier > qi::lit("[") | 
				
			|||
                moduleRenaming = ((qi::lit("module") >> identifier >> qi::lit("=")) > identifier > qi::lit("[") | 
				
			|||
                                  > ((identifier > qi::lit("=") > identifier)[phoenix::insert(qi::_a, phoenix::construct<std::pair<std::string,std::string>>(qi::_1, qi::_2))] % ",") > qi::lit("]") | 
				
			|||
                                  > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createRenamedModule, qi::_1, qi::_2, qi::_a, qi::_r1)]; | 
				
			|||
                                  > qi::lit("endmodule"))[qi::_val = phoenix::bind(&PrismGrammar::createRenamedModule, phoenix::ref(*this), qi::_1, qi::_2, qi::_a, qi::_r1)]; | 
				
			|||
                moduleRenaming.name("module definition via renaming"); | 
				
			|||
                 | 
				
			|||
                start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(rewardModelDefinition(qi::_a) | labelDefinition(qi::_a)))[qi::_val = phoenix::bind(&PrismGrammar::createProgram, qi::_a, qi::_1)]; | 
				
			|||
                moduleDefinitionList %= +(moduleRenaming(qi::_r1) | moduleDefinition(qi::_r1))[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::modules, qi::_r1), qi::_1)]; | 
				
			|||
                moduleDefinitionList.name("module list"); | 
				
			|||
 | 
				
			|||
                start = (qi::eps > programHeader(qi::_a) > moduleDefinitionList(qi::_a) > *(initialStatesConstruct(qi::_a) | rewardModelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::rewardModels, qi::_a), qi::_1)] | labelDefinition[phoenix::push_back(phoenix::bind(&GlobalProgramInformation::labels, qi::_a), qi::_1)]) > qi::eoi)[qi::_val = phoenix::bind(&PrismGrammar::createProgram, phoenix::ref(*this), qi::_a)]; | 
				
			|||
                start.name("probabilistic program"); | 
				
			|||
 | 
				
			|||
                // Enable location tracking for important entities.
 | 
				
			|||
                auto setLocationInfoFunction = this->annotate(qi::_val, qi::_1, qi::_3); | 
				
			|||
                qi::on_success(undefinedBooleanConstantDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(undefinedIntegerConstantDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(undefinedDoubleConstantDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(definedBooleanConstantDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(definedIntegerConstantDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(definedDoubleConstantDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(booleanVariableDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(integerVariableDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(moduleDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(moduleRenaming, setLocationInfoFunction); | 
				
			|||
                qi::on_success(formulaDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(rewardModelDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(labelDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(commandDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(updateDefinition, setLocationInfoFunction); | 
				
			|||
                qi::on_success(assignmentDefinition, setLocationInfoFunction); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            void PrismGrammar::setExpressionGeneration(bool doExpressionGeneration) { | 
				
			|||
                if (doExpressionGeneration) { | 
				
			|||
                    floorCeilExpression = ((qi::lit("floor")[qi::_a = true] | qi::lit("ceil")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::floor, qi::_1)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::ceil, qi::_1)]]; | 
				
			|||
                    floorCeilExpression.name("floor/ceil expression"); | 
				
			|||
                     | 
				
			|||
                    minMaxExpression = ((qi::lit("min")[qi::_a = true] | qi::lit("max")[qi::_a = false]) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[phoenix::if_(qi::_a) [qi::_val = phoenix::bind(&storm::expressions::Expression::minimum, qi::_1, qi::_2)] .else_ [qi::_val = phoenix::bind(&storm::expressions::Expression::maximum, qi::_1, qi::_2)]]; | 
				
			|||
                    minMaxExpression.name("min/max expression"); | 
				
			|||
                     | 
				
			|||
                    identifierExpression = identifier[qi::_val = phoenix::bind(&PrismGrammar::getIdentifierExpression, phoenix::ref(*this), qi::_1)]; | 
				
			|||
                    identifierExpression.name("identifier expression"); | 
				
			|||
                     | 
				
			|||
                    literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | strict_double[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleLiteral, qi::_1)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)]; | 
				
			|||
                    literalExpression.name("literal expression"); | 
				
			|||
                     | 
				
			|||
                    atomicExpression = minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression; | 
				
			|||
                    atomicExpression.name("atomic expression"); | 
				
			|||
                     | 
				
			|||
                    unaryExpression = atomicExpression[qi::_val = qi::_1] | (qi::lit("!") >> atomicExpression)[qi::_val = !qi::_1] | (qi::lit("-") >> atomicExpression)[qi::_val = -qi::_1]; | 
				
			|||
                    unaryExpression.name("unary expression"); | 
				
			|||
                     | 
				
			|||
                    multiplicationExpression = unaryExpression[qi::_val = qi::_1] >> *((qi::lit("*")[qi::_a = true] | qi::lit("/")[qi::_a = false]) >> unaryExpression[phoenix::if_(qi::_a) [qi::_val = qi::_val * qi::_1] .else_ [qi::_val = qi::_val / qi::_1]]); | 
				
			|||
                    multiplicationExpression.name("multiplication expression"); | 
				
			|||
                     | 
				
			|||
                    plusExpression = multiplicationExpression[qi::_val = qi::_1] >> *((qi::lit("+")[qi::_a = true] | qi::lit("-")[qi::_a = false]) >> multiplicationExpression)[phoenix::if_(qi::_a) [qi::_val = qi::_val + qi::_1] .else_ [qi::_val = qi::_val - qi::_1]]; | 
				
			|||
                    plusExpression.name("plus expression"); | 
				
			|||
                     | 
				
			|||
                    relativeExpression = (plusExpression >> qi::lit(">=") >> plusExpression)[qi::_val = qi::_1 >= qi::_1] | (plusExpression >> qi::lit(">") >> plusExpression)[qi::_val = qi::_1 > qi::_2] | (plusExpression >> qi::lit("<=") >> plusExpression)[qi::_val = qi::_1 <= qi::_2] | (plusExpression >> qi::lit("<") >> plusExpression)[qi::_val = qi::_1 < qi::_2] | (plusExpression >> qi::lit("=") >> plusExpression)[qi::_val = qi::_1 == qi::_2] | (plusExpression >> qi::lit("!=") >> plusExpression)[qi::_val = qi::_1 != qi::_2] | plusExpression[qi::_val = qi::_1]; | 
				
			|||
                    relativeExpression.name("relative expression"); | 
				
			|||
                     | 
				
			|||
                    andExpression = relativeExpression[qi::_val = qi::_1] >> *(qi::lit("&") >> relativeExpression)[qi::_val = qi::_val && qi::_1]; | 
				
			|||
                    andExpression.name("and expression"); | 
				
			|||
                     | 
				
			|||
                    orExpression = andExpression[qi::_val = qi::_1] >> *(qi::lit("|") >> andExpression)[qi::_val = qi::_val || qi::_1]; | 
				
			|||
                    orExpression.name("or expression"); | 
				
			|||
                     | 
				
			|||
                    expression %= orExpression; | 
				
			|||
                    expression.name("expression"); | 
				
			|||
                } else { | 
				
			|||
                    floorCeilExpression = ((qi::lit("floor") | qi::lit("ceil")) >> qi::lit("(") >> plusExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    floorCeilExpression.name("floor/ceil expression"); | 
				
			|||
                     | 
				
			|||
                    minMaxExpression = ((qi::lit("min") | qi::lit("max")) >> qi::lit("(") >> plusExpression >> qi::lit(",") >> plusExpression >> qi::lit(")"))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    minMaxExpression.name("min/max expression"); | 
				
			|||
                     | 
				
			|||
                    identifierExpression = identifier[qi::_val = phoenix::construct<storm::expressions::Expression>(), qi::_pass = phoenix::bind(&PrismGrammar::isValidIdentifier, phoenix::ref(*this), qi::_1)]; | 
				
			|||
                    identifierExpression.name("identifier expression"); | 
				
			|||
                     | 
				
			|||
                    literalExpression = (qi::lit("true") | qi::lit("false") | strict_double | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    literalExpression.name("literal expression"); | 
				
			|||
                     | 
				
			|||
                    atomicExpression = (minMaxExpression | floorCeilExpression | qi::lit("(") >> expression >> qi::lit(")") | literalExpression | identifierExpression)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    atomicExpression.name("atomic expression"); | 
				
			|||
                     | 
				
			|||
                    unaryExpression = (atomicExpression | (qi::lit("!") >> atomicExpression) | (qi::lit("-") >> atomicExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    unaryExpression.name("unary expression"); | 
				
			|||
                     | 
				
			|||
                    multiplicationExpression = (unaryExpression >> *((qi::lit("*") | qi::lit("/")) >> unaryExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    multiplicationExpression.name("multiplication expression"); | 
				
			|||
                     | 
				
			|||
                    plusExpression = (multiplicationExpression >> *((qi::lit("+") | qi::lit("-")) >> multiplicationExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    plusExpression.name("plus expression"); | 
				
			|||
                     | 
				
			|||
                    relativeExpression = ((plusExpression >> qi::lit(">=") >> plusExpression) | (plusExpression >> qi::lit(">") >> plusExpression) | (plusExpression >> qi::lit("<=") >> plusExpression) | (plusExpression >> qi::lit("<") >> plusExpression) | (plusExpression >> qi::lit("=") >> plusExpression) | (plusExpression >> qi::lit("!=") >> plusExpression) | plusExpression)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    relativeExpression.name("relative expression"); | 
				
			|||
                     | 
				
			|||
                    andExpression = (relativeExpression >> *(qi::lit("&") >> relativeExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    andExpression.name("and expression"); | 
				
			|||
                     | 
				
			|||
                    orExpression = (andExpression >> *(qi::lit("|") >> andExpression))[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                    orExpression.name("or expression"); | 
				
			|||
                     | 
				
			|||
                    expression %= orExpression; | 
				
			|||
                    expression.name("expression"); | 
				
			|||
                } | 
				
			|||
                 | 
				
			|||
                // Enable error reporting.
 | 
				
			|||
                qi::on_error<qi::fail>(expression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(orExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(andExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(relativeExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(plusExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(multiplicationExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(unaryExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(atomicExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(literalExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(identifierExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(minMaxExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                qi::on_error<qi::fail>(floorCeilExpression, handler(qi::_1, qi::_2, qi::_3, qi::_4)); | 
				
			|||
                 | 
				
			|||
                // Finally toggle the internal flag.
 | 
				
			|||
                this->doExpressionGeneration = doExpressionGeneration; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            void PrismGrammar::toggleExpressionGeneration() { | 
				
			|||
                setExpressionGeneration(!doExpressionGeneration); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            void PrismGrammar::allowDoubleLiterals(bool flag) { | 
				
			|||
                if (flag) { | 
				
			|||
                    if (this->doExpressionGeneration) { | 
				
			|||
                        literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | strict_double[qi::_val = phoenix::bind(&storm::expressions::Expression::createDoubleLiteral, qi::_1)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)]; | 
				
			|||
                        literalExpression.name("literal expression"); | 
				
			|||
                    } else { | 
				
			|||
                        literalExpression = (qi::lit("true") | qi::lit("false") | strict_double | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                        literalExpression.name("literal expression"); | 
				
			|||
                    } | 
				
			|||
                } else { | 
				
			|||
                    if (this->doExpressionGeneration) { | 
				
			|||
                        literalExpression = qi::lit("true")[qi::_val = phoenix::bind(&storm::expressions::Expression::createTrue)] | qi::lit("false")[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)] | qi::int_[qi::_val = phoenix::bind(&storm::expressions::Expression::createIntegerLiteral, qi::_1)]; | 
				
			|||
                        literalExpression.name("literal expression"); | 
				
			|||
                    } else { | 
				
			|||
                        literalExpression = (qi::lit("true") | qi::lit("false") | qi::int_)[qi::_val = phoenix::bind(&storm::expressions::Expression::createFalse)]; | 
				
			|||
                        literalExpression.name("literal expression"); | 
				
			|||
                    } | 
				
			|||
                } | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            std::string const& PrismGrammar::getFilename() const { | 
				
			|||
                return this->filename; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            bool PrismGrammar::isValidIdentifier(std::string const& identifier) { | 
				
			|||
                if (this->keywords_.find(identifier) != nullptr) { | 
				
			|||
                    return false; | 
				
			|||
                } | 
				
			|||
                return true; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            bool PrismGrammar::addInitialStatesExpression(storm::expressions::Expression initialStatesExpression, GlobalProgramInformation& globalProgramInformation) { | 
				
			|||
                LOG_THROW(!globalProgramInformation.hasInitialStatesExpression, storm::exceptions::InvalidArgumentException, "Program must not define two initial constructs."); | 
				
			|||
                if (globalProgramInformation.hasInitialStatesExpression) { | 
				
			|||
                    return false; | 
				
			|||
                } | 
				
			|||
                globalProgramInformation.hasInitialStatesExpression = true; | 
				
			|||
                globalProgramInformation.initialStatesExpression = initialStatesExpression; | 
				
			|||
                return true; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::expressions::Expression PrismGrammar::getIdentifierExpression(std::string const& identifier) const { | 
				
			|||
                storm::expressions::Expression const* expression = this->identifiers_.find(identifier); | 
				
			|||
                LOG_THROW(expression != nullptr, storm::exceptions::WrongFormatException, "Undeclared identifier '" << identifier << "'."); | 
				
			|||
                return *expression; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Constant PrismGrammar::createUndefinedBooleanConstant(std::string const& newConstant) const { | 
				
			|||
                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant)); | 
				
			|||
                return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Constant PrismGrammar::createUndefinedIntegerConstant(std::string const& newConstant) const { | 
				
			|||
                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant)); | 
				
			|||
                return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Constant PrismGrammar::createUndefinedDoubleConstant(std::string const& newConstant) const { | 
				
			|||
                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant)); | 
				
			|||
                return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Constant PrismGrammar::createDefinedBooleanConstant(std::string const& newConstant, storm::expressions::Expression expression) const { | 
				
			|||
                this->identifiers_.add(newConstant, storm::expressions::Expression::createBooleanConstant(newConstant)); | 
				
			|||
                return storm::prism::Constant(storm::prism::Constant::ConstantType::Bool, newConstant, expression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Constant PrismGrammar::createDefinedIntegerConstant(std::string const& newConstant, storm::expressions::Expression expression) const { | 
				
			|||
                this->identifiers_.add(newConstant, storm::expressions::Expression::createIntegerConstant(newConstant)); | 
				
			|||
                return storm::prism::Constant(storm::prism::Constant::ConstantType::Integer, newConstant, expression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Constant PrismGrammar::createDefinedDoubleConstant(std::string const& newConstant, storm::expressions::Expression expression) const { | 
				
			|||
                this->identifiers_.add(newConstant, storm::expressions::Expression::createDoubleConstant(newConstant)); | 
				
			|||
                return storm::prism::Constant(storm::prism::Constant::ConstantType::Double, newConstant, expression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Formula PrismGrammar::createFormula(std::string const& formulaName, storm::expressions::Expression expression) const { | 
				
			|||
                this->identifiers_.add(formulaName, expression); | 
				
			|||
                return storm::prism::Formula(formulaName, expression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Label PrismGrammar::createLabel(std::string const& labelName, storm::expressions::Expression expression) const { | 
				
			|||
                return storm::prism::Label(labelName, expression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::RewardModel PrismGrammar::createRewardModel(std::string const& rewardModelName, std::vector<storm::prism::StateReward> const& stateRewards, std::vector<storm::prism::TransitionReward> const& transitionRewards) const { | 
				
			|||
                return storm::prism::RewardModel(rewardModelName, stateRewards, transitionRewards, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::StateReward PrismGrammar::createStateReward(storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const { | 
				
			|||
                return storm::prism::StateReward(statePredicateExpression, rewardValueExpression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::TransitionReward PrismGrammar::createTransitionReward(std::string const& actionName, storm::expressions::Expression statePredicateExpression, storm::expressions::Expression rewardValueExpression) const { | 
				
			|||
                return storm::prism::TransitionReward(actionName, statePredicateExpression, rewardValueExpression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Assignment PrismGrammar::createAssignment(std::string const& variableName, storm::expressions::Expression assignedExpression) const { | 
				
			|||
                return storm::prism::Assignment(variableName, assignedExpression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Update PrismGrammar::createUpdate(storm::expressions::Expression likelihoodExpression, std::vector<storm::prism::Assignment> const& assignments, GlobalProgramInformation& globalProgramInformation) const { | 
				
			|||
                ++globalProgramInformation.currentUpdateIndex; | 
				
			|||
                return storm::prism::Update(globalProgramInformation.currentUpdateIndex - 1, likelihoodExpression, assignments, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Command PrismGrammar::createCommand(std::string const& actionName, storm::expressions::Expression guardExpression, std::vector<storm::prism::Update> const& updates, GlobalProgramInformation& globalProgramInformation) const { | 
				
			|||
                ++globalProgramInformation.currentCommandIndex; | 
				
			|||
                return storm::prism::Command(globalProgramInformation.currentCommandIndex - 1, actionName, guardExpression, updates, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::BooleanVariable PrismGrammar::createBooleanVariable(std::string const& variableName, storm::expressions::Expression initialValueExpression) const { | 
				
			|||
                this->identifiers_.add(variableName, storm::expressions::Expression::createBooleanVariable(variableName)); | 
				
			|||
                return storm::prism::BooleanVariable(variableName, initialValueExpression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::IntegerVariable PrismGrammar::createIntegerVariable(std::string const& variableName, storm::expressions::Expression lowerBoundExpression, storm::expressions::Expression upperBoundExpression, storm::expressions::Expression initialValueExpression) const { | 
				
			|||
                this->identifiers_.add(variableName, storm::expressions::Expression::createIntegerVariable(variableName)); | 
				
			|||
                return storm::prism::IntegerVariable(variableName, lowerBoundExpression, upperBoundExpression, initialValueExpression, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Module PrismGrammar::createModule(std::string const& moduleName, std::vector<storm::prism::BooleanVariable> const& booleanVariables, std::vector<storm::prism::IntegerVariable> const& integerVariables, std::vector<storm::prism::Command> const& commands, GlobalProgramInformation& globalProgramInformation) const { | 
				
			|||
                globalProgramInformation.moduleToIndexMap[moduleName] = globalProgramInformation.modules.size(); | 
				
			|||
                return storm::prism::Module(moduleName, booleanVariables, integerVariables, commands, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Module PrismGrammar::createRenamedModule(std::string const& newModuleName, std::string const& oldModuleName, std::map<std::string, std::string> const& renaming, GlobalProgramInformation& globalProgramInformation) const { | 
				
			|||
                auto const& moduleIndexPair = globalProgramInformation.moduleToIndexMap.find(oldModuleName); | 
				
			|||
                LOG_THROW(moduleIndexPair != globalProgramInformation.moduleToIndexMap.end(), storm::exceptions::WrongFormatException, "No module named '" << oldModuleName << "' to rename."); | 
				
			|||
                globalProgramInformation.moduleToIndexMap[newModuleName] = globalProgramInformation.modules.size(); | 
				
			|||
                uint_fast64_t commandBaseIndex = globalProgramInformation.currentCommandIndex; | 
				
			|||
                uint_fast64_t updateBaseIndex = globalProgramInformation.currentUpdateIndex; | 
				
			|||
                storm::prism::Module const& moduleToClone = globalProgramInformation.modules[moduleIndexPair->second]; | 
				
			|||
                globalProgramInformation.currentCommandIndex += moduleToClone.getNumberOfCommands(); | 
				
			|||
                globalProgramInformation.currentUpdateIndex += moduleToClone.getNumberOfUpdates(); | 
				
			|||
                return storm::prism::Module(moduleToClone, newModuleName, commandBaseIndex, updateBaseIndex, renaming, this->getFilename()); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            storm::prism::Program PrismGrammar::createProgram(GlobalProgramInformation const& globalProgramInformation) const { | 
				
			|||
                return storm::prism::Program(globalProgramInformation.modelType, globalProgramInformation.constants, globalProgramInformation.globalBooleanVariables, globalProgramInformation.globalIntegerVariables, globalProgramInformation.formulas, globalProgramInformation.modules, globalProgramInformation.rewardModels, globalProgramInformation.hasInitialStatesExpression, globalProgramInformation.initialStatesExpression, globalProgramInformation.labels, this->getFilename()); | 
				
			|||
            } | 
				
			|||
        } // namespace prism
 | 
				
			|||
    } // namespace parser
 | 
				
			|||
 | 
				
			|||
@ -0,0 +1,70 @@ | 
				
			|||
#include "src/parser/prismparser/PrismParser.h"
 | 
				
			|||
#include "src/parser/prismparser/PrismGrammar.h"
 | 
				
			|||
 | 
				
			|||
// If the parser fails due to ill-formed data, this exception is thrown.
 | 
				
			|||
#include "src/exceptions/ExceptionMacros.h"
 | 
				
			|||
#include "src/exceptions/WrongFormatException.h"
 | 
				
			|||
 | 
				
			|||
// Needed for file IO.
 | 
				
			|||
#include <fstream>
 | 
				
			|||
#include <iomanip>
 | 
				
			|||
#include <limits>
 | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace parser { | 
				
			|||
        storm::prism::Program PrismParser::parse(std::string const& filename, bool typeCheck) { | 
				
			|||
            // Open file and initialize result.
 | 
				
			|||
            std::ifstream inputFileStream(filename, std::ios::in); | 
				
			|||
            LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file " << filename << "."); | 
				
			|||
             | 
				
			|||
            storm::prism::Program result; | 
				
			|||
             | 
				
			|||
            // Now try to parse the contents of the file.
 | 
				
			|||
            try { | 
				
			|||
                std::string fileContent((std::istreambuf_iterator<char>(inputFileStream)), (std::istreambuf_iterator<char>())); | 
				
			|||
                result = parseFromString(fileContent, filename, typeCheck); | 
				
			|||
            } catch(std::exception& e) { | 
				
			|||
                // In case of an exception properly close the file before passing exception.
 | 
				
			|||
                inputFileStream.close(); | 
				
			|||
                throw e; | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            // Close the stream in case everything went smoothly and return result.
 | 
				
			|||
            inputFileStream.close(); | 
				
			|||
            return result; | 
				
			|||
        } | 
				
			|||
         | 
				
			|||
        storm::prism::Program PrismParser::parseFromString(std::string const& input, std::string const& filename, bool typeCheck) { | 
				
			|||
            PositionIteratorType first(input.begin()); | 
				
			|||
            PositionIteratorType iter = first; | 
				
			|||
            PositionIteratorType last(input.end()); | 
				
			|||
             | 
				
			|||
            // Create empty result;
 | 
				
			|||
            storm::prism::Program result; | 
				
			|||
             | 
				
			|||
            // Create grammar.
 | 
				
			|||
            storm::parser::prism::PrismGrammar grammar(filename, first); | 
				
			|||
            try { | 
				
			|||
                // Now parse the content using phrase_parse in order to be able to supply a skipping parser.
 | 
				
			|||
                bool succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); | 
				
			|||
                LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in first pass."); | 
				
			|||
                if (typeCheck) { | 
				
			|||
                    first = PositionIteratorType(input.begin()); | 
				
			|||
                    iter = first; | 
				
			|||
                    last = PositionIteratorType(input.end()); | 
				
			|||
                    grammar.toggleExpressionGeneration(); | 
				
			|||
                    succeeded = qi::phrase_parse(iter, last, grammar, boost::spirit::ascii::space | qi::lit("//") >> *(qi::char_ - qi::eol) >> qi::eol, result); | 
				
			|||
                    LOG_THROW(succeeded,  storm::exceptions::WrongFormatException, "Parsing failed in second pass."); | 
				
			|||
                } | 
				
			|||
            } catch (qi::expectation_failure<PositionIteratorType> const& e) { | 
				
			|||
                // If the parser expected content different than the one provided, display information about the location of the error.
 | 
				
			|||
                std::size_t lineNumber = boost::spirit::get_line(e.first); | 
				
			|||
                 | 
				
			|||
                // Now propagate exception.
 | 
				
			|||
                LOG_THROW(false, storm::exceptions::WrongFormatException, "Parsing error in line " << lineNumber << " of file " << filename << "."); | 
				
			|||
            } | 
				
			|||
             | 
				
			|||
            return result; | 
				
			|||
        } | 
				
			|||
    } // namespace parser
 | 
				
			|||
} // namespace storm
 | 
				
			|||
@ -0,0 +1,36 @@ | 
				
			|||
#ifndef STORM_PARSER_PRISMPARSER_H_ | 
				
			|||
#define STORM_PARSER_PRISMPARSER_H_ | 
				
			|||
 | 
				
			|||
// All classes of the intermediate representation are used. | 
				
			|||
#include "src/storage/prism/Program.h" | 
				
			|||
 | 
				
			|||
// Used for file input. | 
				
			|||
#include <istream> | 
				
			|||
 | 
				
			|||
namespace storm { | 
				
			|||
    namespace parser { | 
				
			|||
        class PrismParser { | 
				
			|||
        public: | 
				
			|||
            /*! | 
				
			|||
             * Parses the given file into the PRISM storage classes assuming it complies with the PRISM syntax. | 
				
			|||
             * | 
				
			|||
             * @param filename the name of the file to parse. | 
				
			|||
             * @param typeCheck Sets whether the expressions are generated and therefore typechecked. | 
				
			|||
             * @return The resulting PRISM program. | 
				
			|||
             */ | 
				
			|||
            static storm::prism::Program parse(std::string const& filename, bool typeCheck = true); | 
				
			|||
             | 
				
			|||
            /*! | 
				
			|||
             * Parses the given input stream into the PRISM storage classes assuming it complies with the PRISM syntax. | 
				
			|||
             * | 
				
			|||
             * @param input The input string to parse. | 
				
			|||
             * @param filename The name of the file from which the input was read. | 
				
			|||
             * @param typeCheck Sets whether the expressions are generated and therefore typechecked. | 
				
			|||
             * @return The resulting PRISM program. | 
				
			|||
             */ | 
				
			|||
            static storm::prism::Program parseFromString(std::string const& input, std::string const& filename, bool typeCheck = true); | 
				
			|||
        }; | 
				
			|||
    } // namespace parser | 
				
			|||
} // namespace storm | 
				
			|||
 | 
				
			|||
#endif /* STORM_PARSER_PRISMPARSER_H_ */ | 
				
			|||
@ -0,0 +1,157 @@ | 
				
			|||
#include "gtest/gtest.h"
 | 
				
			|||
#include "storm-config.h"
 | 
				
			|||
#include "src/parser/prismparser/PrismParser.h"
 | 
				
			|||
 | 
				
			|||
TEST(PrismParser, SimpleParsingOnlyTest) { | 
				
			|||
    std::string testInput = | 
				
			|||
    R"(dtmc | 
				
			|||
    module mod1 | 
				
			|||
        b : bool; | 
				
			|||
        [a] true -> 1: (b'=true); | 
				
			|||
    endmodule)"; | 
				
			|||
     | 
				
			|||
    storm::prism::Program result; | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false)); | 
				
			|||
    EXPECT_EQ(1, result.getNumberOfModules()); | 
				
			|||
    EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType()); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
TEST(PrismParser, StandardModelParsingTest) { | 
				
			|||
    storm::prism::Program result; | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/coin2.nm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/crowds5_5.pm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/csma2_2.nm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/die.pm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/firewire.nm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3.nm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/leader3_5.pm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/two_dice.nm", false)); | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parse(STORM_CPP_TESTS_BASE_PATH "/functional/parser/prism/wlan0_collide.nm", false)); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
TEST(PrismParser, SimpleFullTest) { | 
				
			|||
    std::string testInput = | 
				
			|||
    R"(dtmc | 
				
			|||
    module mod1 | 
				
			|||
        b : bool; | 
				
			|||
        [a] true -> 1: (b'=true); | 
				
			|||
    endmodule)"; | 
				
			|||
     | 
				
			|||
    storm::prism::Program result; | 
				
			|||
    EXPECT_NO_THROW(result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true)); | 
				
			|||
    EXPECT_EQ(1, result.getNumberOfModules()); | 
				
			|||
    EXPECT_EQ(storm::prism::Program::ModelType::DTMC, result.getModelType()); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
TEST(PrismParser, ComplexFullTest) { | 
				
			|||
    std::string testInput = | 
				
			|||
    R"(ma | 
				
			|||
     | 
				
			|||
    const int a; | 
				
			|||
    const int b = 10; | 
				
			|||
    const bool c; | 
				
			|||
    const bool d = true | false; | 
				
			|||
    const double e; | 
				
			|||
    const double f = 9; | 
				
			|||
     | 
				
			|||
    formula test = a >= 10 & (max(a,b) > floor(e)); | 
				
			|||
    formula test2 = a+b; | 
				
			|||
     | 
				
			|||
    global g : bool init false; | 
				
			|||
    global h : [0 .. b]; | 
				
			|||
     | 
				
			|||
    module mod1 | 
				
			|||
        i : bool; | 
				
			|||
        j : bool init c; | 
				
			|||
        k : [125..a] init a; | 
				
			|||
 | 
				
			|||
        [a] test2&false -> (i'=true)&(h'=1+1) + 1 : (j'=floor(a) <= max(k, b) - 1 + k); | 
				
			|||
    endmodule | 
				
			|||
                                               | 
				
			|||
    module mod2 | 
				
			|||
        [b] (k > 3) & false & (min(a, 0) < max(h, k)) -> 1-e: (j'=(1-a) * 2 + floor(f)); | 
				
			|||
    endmodule | 
				
			|||
     | 
				
			|||
    module mod3 = mod2 [ x = y ] endmodule | 
				
			|||
                                                                | 
				
			|||
    label "mal" = max(a, 10) > 0; | 
				
			|||
                                                                | 
				
			|||
    init | 
				
			|||
        true | 
				
			|||
    endinit | 
				
			|||
     | 
				
			|||
    rewards "testrewards" | 
				
			|||
        [stateRew] true : a + 7; | 
				
			|||
        max(f, a) <= 8 : 2*b; | 
				
			|||
    endrewards | 
				
			|||
                                                                | 
				
			|||
    rewards "testrewards2" | 
				
			|||
        [stateRew] true : a + 7; | 
				
			|||
        max(f, a) <= 8 : 2*b; | 
				
			|||
    endrewards)"; | 
				
			|||
     | 
				
			|||
    storm::prism::Program result; | 
				
			|||
    result = storm::parser::PrismParser::parseFromString(testInput, "testfile", true); | 
				
			|||
    std::cout << result << std::endl; | 
				
			|||
    EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType()); | 
				
			|||
    EXPECT_EQ(3, result.getNumberOfModules()); | 
				
			|||
    EXPECT_EQ(2, result.getNumberOfRewardModels()); | 
				
			|||
    EXPECT_EQ(1, result.getNumberOfLabels()); | 
				
			|||
    EXPECT_TRUE(result.definesInitialStatesExpression()); | 
				
			|||
} | 
				
			|||
 | 
				
			|||
TEST(PrismParser, ComplexParsingTest) { | 
				
			|||
    std::string testInput = | 
				
			|||
    R"(ma | 
				
			|||
     | 
				
			|||
    const int a; | 
				
			|||
    const int b = 10; | 
				
			|||
    const bool c; | 
				
			|||
    const bool d = true | false; | 
				
			|||
    const double e; | 
				
			|||
    const double f = 9; | 
				
			|||
     | 
				
			|||
    formula test = (a >= 10 & (max(a, b) > floor(e))); | 
				
			|||
 | 
				
			|||
    global g : bool init false; | 
				
			|||
    global h : [0 .. b]; | 
				
			|||
     | 
				
			|||
    module mod1 | 
				
			|||
        i : bool; | 
				
			|||
        j : bool init c; | 
				
			|||
        k : [125..a] init a; | 
				
			|||
        [a] true -> (i'=true)&(h'=1+1) + 1 : (j'=floor(a) <= max(k, b) - 1 + k); | 
				
			|||
    endmodule | 
				
			|||
                                     | 
				
			|||
    module mod2 | 
				
			|||
        [b] (x > 3) & false & (min(a, b0) < max(as8, b)) -> y: (x'=(1-g) * 2 + a); | 
				
			|||
        [] s=1 -> (a'=a); | 
				
			|||
        [read] c<N-1 -> 1 : (c'=floor(c) + 1); | 
				
			|||
    endmodule | 
				
			|||
                              | 
				
			|||
    module mod3 = mod2 [ x = y ] endmodule | 
				
			|||
              | 
				
			|||
    label "mal" = max(x, i) > 0; | 
				
			|||
                              | 
				
			|||
    init | 
				
			|||
        true | 
				
			|||
    endinit | 
				
			|||
                              | 
				
			|||
    rewards "testrewards" | 
				
			|||
        [stateRew] true : a + 7; | 
				
			|||
        max(z, f) <= 8 : 2*b; | 
				
			|||
    endrewards | 
				
			|||
                              | 
				
			|||
    rewards "testrewards2" | 
				
			|||
        [stateRew] true : a + 7; | 
				
			|||
        max(z, f) <= 8 : 2*b; | 
				
			|||
    endrewards)"; | 
				
			|||
     | 
				
			|||
    storm::prism::Program result; | 
				
			|||
    result = storm::parser::PrismParser::parseFromString(testInput, "testfile", false); | 
				
			|||
    EXPECT_EQ(storm::prism::Program::ModelType::MA, result.getModelType()); | 
				
			|||
    EXPECT_EQ(3, result.getNumberOfModules()); | 
				
			|||
    EXPECT_EQ(2, result.getNumberOfRewardModels()); | 
				
			|||
    EXPECT_EQ(1, result.getNumberOfLabels()); | 
				
			|||
    EXPECT_TRUE(result.definesInitialStatesExpression()); | 
				
			|||
} | 
				
			|||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue