You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
9.5 KiB
158 lines
9.5 KiB
#pragma once
|
|
|
|
// Includes files for file input.
|
|
#include <fstream>
|
|
#include <memory>
|
|
#include <iomanip>
|
|
// Includes files for building and parsing the PGCL program
|
|
#include "storm/parser/SpiritParserDefinitions.h"
|
|
#include "storm/parser/SpiritErrorHandler.h"
|
|
#include "storm/parser/ExpressionParser.h"
|
|
#include "storm/storage/expressions/ExpressionManager.h"
|
|
#include "storm/storage/expressions/Expression.h"
|
|
#include "storm-pgcl/storage/pgcl/PgclProgram.h"
|
|
#include "storm-pgcl/storage/pgcl/AssignmentStatement.h"
|
|
#include "storm-pgcl/storage/pgcl/BooleanExpression.h"
|
|
#include "storm-pgcl/storage/pgcl/UniformExpression.h"
|
|
#include "storm-pgcl/storage/pgcl/IfStatement.h"
|
|
#include "storm-pgcl/storage/pgcl/LoopStatement.h"
|
|
#include "storm-pgcl/storage/pgcl/NondeterministicBranch.h"
|
|
#include "storm-pgcl/storage/pgcl/ObserveStatement.h"
|
|
#include "storm-pgcl/storage/pgcl/ProbabilisticBranch.h"
|
|
#include "storm-pgcl/storage/pgcl/Statement.h"
|
|
|
|
namespace storm {
|
|
namespace pgcl {
|
|
class IfStatement;
|
|
}
|
|
|
|
namespace parser {
|
|
|
|
class PgclParser : public qi::grammar<Iterator, storm::pgcl::PgclProgram(), Skipper> {
|
|
public:
|
|
/*!
|
|
* Parses the given file into the PGCL storage classes in case it
|
|
* complies with the PGCL syntax.
|
|
*
|
|
* @param filename the name of the file to parse.
|
|
* @return The resulting PGCL program.
|
|
*/
|
|
static storm::pgcl::PgclProgram parse(std::string const& filename);
|
|
|
|
/*!
|
|
* Parses the given input stream into the PGCL storage classes in
|
|
* case it complies with the PGCL syntax.
|
|
*
|
|
* @param input The input string to parse.
|
|
* @param filename Name of the file from which the input was read.
|
|
* @return The resulting PGCL program.
|
|
*/
|
|
static storm::pgcl::PgclProgram parseFromString(std::string const& input, std::string const& filename);
|
|
private:
|
|
// Internal constructor used by the parseFromString function.
|
|
PgclParser(std::string const& filename, Iterator first);
|
|
// Nonterminals (and their semantic types) of the PGCL grammar.
|
|
qi::rule<Iterator, storm::pgcl::PgclProgram(), Skipper> program;
|
|
qi::rule<Iterator, std::vector<std::shared_ptr<storm::pgcl::Statement> >(), Skipper> sequenceOfStatements;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::Statement>(), Skipper> statement;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::Statement>(), Skipper> simpleStatement;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::Statement>(), Skipper> compoundStatement;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::IfStatement>(), Skipper> ifElseStatement;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::BranchStatement>(), Skipper> branchStatement;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::LoopStatement>(), Skipper> loopStatement;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::NondeterministicBranch>(), Skipper> nondeterministicBranch;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::ProbabilisticBranch>(), Skipper> probabilisticBranch;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::AssignmentStatement>(), Skipper> assignmentStatement;
|
|
qi::rule<Iterator, storm::expressions::Variable(), Skipper> declaration;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::ObserveStatement>(), Skipper> observeStatement;
|
|
qi::rule<Iterator, storm::expressions::Expression(), Skipper> expression;
|
|
qi::rule<Iterator, storm::pgcl::BooleanExpression(), Skipper> booleanCondition;
|
|
qi::rule<Iterator, storm::pgcl::UniformExpression(), Skipper> uniformExpression;
|
|
qi::rule<Iterator, std::string(), Skipper> variableName;
|
|
qi::rule<Iterator, std::string(), Skipper> programName;
|
|
|
|
qi::rule<Iterator, std::vector<std::shared_ptr<storm::pgcl::VariableDeclaration>>(), Skipper> variableDeclarations;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::VariableDeclaration>(), Skipper> integerDeclaration;
|
|
qi::rule<Iterator, std::shared_ptr<storm::pgcl::VariableDeclaration>(), Skipper> booleanDeclaration;
|
|
qi::rule<Iterator, storm::expressions::Variable(), Skipper> doubleDeclaration;
|
|
|
|
// An error handler function.
|
|
phoenix::function<SpiritErrorHandler> handler;
|
|
|
|
/// Denotes the invalid identifiers, which are later passed to the expression parser.
|
|
struct keywordsStruct : qi::symbols<char, uint_fast64_t> {
|
|
keywordsStruct() {
|
|
add
|
|
("while", 1)
|
|
("if", 2)
|
|
("observe", 3)
|
|
("int", 4)
|
|
("bool", 5)
|
|
("function", 6);
|
|
}
|
|
};
|
|
|
|
/// Initializes the invalid identifier struct.
|
|
keywordsStruct invalidIdentifiers;
|
|
/// Is used to store the identifiers of the PGCL program that are found while parsing.
|
|
qi::symbols<char, storm::expressions::Expression> identifiers_;
|
|
|
|
/// Functor used for annotating entities with line number information.
|
|
class PositionAnnotation {
|
|
public:
|
|
typedef void result_type;
|
|
|
|
PositionAnnotation(Iterator first) : first(first) {
|
|
// Intentionally left empty.
|
|
}
|
|
|
|
template<typename Entity, typename First, typename Last>
|
|
result_type operator()(Entity& entity, First f, Last l) const {
|
|
entity.setLineNumber(get_line(f));
|
|
}
|
|
private:
|
|
std::string filename;
|
|
Iterator const first;
|
|
};
|
|
|
|
/// A function used for annotating the entities with their position.
|
|
phoenix::function<PositionAnnotation> annotate;
|
|
|
|
/// Manages the expressions and their parsing externally.
|
|
std::shared_ptr<storm::expressions::ExpressionManager> expressionManager;
|
|
storm::parser::ExpressionParser expressionParser;
|
|
|
|
/// Stores a mapping from location numbers to statements.
|
|
std::vector<std::shared_ptr<storm::pgcl::Statement> > locationToStatement;
|
|
|
|
/// Saves whether a loop statements was created.
|
|
bool loopCreated = false;
|
|
/// Saves whether a nondet statements was created.
|
|
bool nondetCreated = false;
|
|
/// Saves whether a observe statement was created.
|
|
bool observeCreated = false;
|
|
|
|
/// Stores the unique identifier of the currently parsed statement, starting at 1.
|
|
std::size_t currentLocationNumber = 1;
|
|
|
|
/// Sets the expression parser to a mode where it actually generates valid expressions.
|
|
void enableExpressions();
|
|
|
|
// Constructors for the single program parts. They just wrap the statement constructors and throw exceptions in case something unexpected was parsed.
|
|
storm::pgcl::PgclProgram createProgram(std::string const& programName, boost::optional<std::vector<storm::expressions::Variable> > parameters, std::vector<std::shared_ptr<storm::pgcl::VariableDeclaration>> const& variableDeclarations, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& statements);
|
|
storm::expressions::Variable declareDoubleVariable(std::string const& variableName);
|
|
std::shared_ptr<storm::pgcl::AssignmentStatement> createAssignmentStatement(std::string const& variableName, boost::variant<storm::expressions::Expression, storm::pgcl::UniformExpression> const& assignedExpression);
|
|
std::shared_ptr<storm::pgcl::VariableDeclaration> createIntegerDeclarationStatement(std::string const& variableName, storm::expressions::Expression const& assignedExpression);
|
|
std::shared_ptr<storm::pgcl::VariableDeclaration> createBooleanDeclarationStatement(std::string const& variableName, storm::expressions::Expression const& assignedExpression);
|
|
std::shared_ptr<storm::pgcl::ObserveStatement> createObserveStatement(storm::pgcl::BooleanExpression const& condition);
|
|
std::shared_ptr<storm::pgcl::IfStatement> createIfElseStatement(storm::pgcl::BooleanExpression const& condition, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& if_body, boost::optional<std::vector<std::shared_ptr<storm::pgcl::Statement> > > const& else_body);
|
|
std::shared_ptr<storm::pgcl::LoopStatement> createLoopStatement(storm::pgcl::BooleanExpression const& condition, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& body);
|
|
std::shared_ptr<storm::pgcl::NondeterministicBranch> createNondeterministicBranch(std::vector<std::shared_ptr<storm::pgcl::Statement> > const& left, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& right);
|
|
std::shared_ptr<storm::pgcl::ProbabilisticBranch> createProbabilisticBranch(storm::expressions::Expression const& probability, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& left, std::vector<std::shared_ptr<storm::pgcl::Statement> > const& right);
|
|
storm::pgcl::BooleanExpression createBooleanExpression(storm::expressions::Expression const& expression);
|
|
storm::pgcl::UniformExpression createUniformExpression(int const& begin, int const& end);
|
|
};
|
|
} // namespace parser
|
|
} // namespace storm
|
|
|
|
|