Thomas Knoll
1 year ago
8 changed files with 278 additions and 108 deletions
-
4CMakeLists.txt
-
22main.cpp
-
1util/CMakeLists.txt
-
88util/ConfigGrammar.h
-
150util/ConfigYaml.cpp
-
115util/ConfigYaml.h
-
2util/Grid.h
-
2util/PrismModulesPrinter.h
@ -1,88 +0,0 @@ |
|||||
#pragma once |
|
||||
|
|
||||
#include "cell.h" |
|
||||
|
|
||||
#include <vector> |
|
||||
|
|
||||
#include <boost/tokenizer.hpp> |
|
||||
#include <boost/fusion/adapted/struct.hpp> |
|
||||
#include <boost/spirit/include/qi.hpp> |
|
||||
#include <boost/spirit/include/phoenix.hpp> |
|
||||
#include <boost/spirit/include/phoenix_operator.hpp> |
|
||||
#include <boost/variant/recursive_wrapper.hpp> |
|
||||
#include <boost/spirit/include/support_line_pos_iterator.hpp> |
|
||||
|
|
||||
namespace qi = boost::spirit::qi; |
|
||||
namespace phoenix = boost::phoenix; |
|
||||
|
|
||||
typedef std::vector<std::string> expressions; |
|
||||
|
|
||||
enum class ConfigType : char { |
|
||||
Label = 'L', |
|
||||
Formula = 'F', |
|
||||
}; |
|
||||
|
|
||||
struct Configuration |
|
||||
{ |
|
||||
expressions expressions_; |
|
||||
std::string derivation_; |
|
||||
ConfigType type_ {ConfigType::Label}; |
|
||||
|
|
||||
Configuration() = default; |
|
||||
Configuration(expressions expressions, std::string derivation, ConfigType type) : expressions_(expressions), derivation_(derivation), type_(type) {} |
|
||||
~Configuration() = default; |
|
||||
Configuration(const Configuration&) = default; |
|
||||
|
|
||||
friend std::ostream& operator << (std::ostream& os, const Configuration& config) { |
|
||||
os << "Configuration with Type: " << static_cast<char>(config.type_) << std::endl; |
|
||||
|
|
||||
for (auto& expression : config.expressions_) { |
|
||||
os << "\tExpression=" << expression << std::endl; |
|
||||
} |
|
||||
|
|
||||
return os << "\tDerviation=" << config.derivation_; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
|
|
||||
BOOST_FUSION_ADAPT_STRUCT( |
|
||||
Configuration, |
|
||||
(ConfigType, type_) |
|
||||
(expressions, expressions_) |
|
||||
(std::string, derivation_) |
|
||||
) |
|
||||
|
|
||||
|
|
||||
template <typename It> |
|
||||
struct ConfigParser : qi::grammar<It, std::vector<Configuration>> |
|
||||
{ |
|
||||
ConfigParser(It first) : ConfigParser::base_type(config_) |
|
||||
{ |
|
||||
using namespace qi; |
|
||||
//F:(AgentCannotMoveSouth & AgentCannotMoveNorth) | (AgentCannotMoveEast & AgentCannotMoveWest) ;AgentCannotTurn |
|
||||
configType_.add |
|
||||
("L", ConfigType::Label) |
|
||||
("F", ConfigType::Formula); |
|
||||
|
|
||||
expression_ = -qi::char_('!') > + char_("a-zA-Z_0-9"); |
|
||||
expressions_ = (expression_ % ','); |
|
||||
row_ = (configType_ > ':' > expressions_ > ';' > expression_); |
|
||||
// row_ = (expressions_ > ';' > expression_); |
|
||||
config_ = (row_ % "\n"); |
|
||||
|
|
||||
BOOST_SPIRIT_DEBUG_NODE(configType_); |
|
||||
BOOST_SPIRIT_DEBUG_NODE(expression_); |
|
||||
BOOST_SPIRIT_DEBUG_NODE(expressions_); |
|
||||
BOOST_SPIRIT_DEBUG_NODE(config_); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
|
|
||||
qi::symbols<char, ConfigType> configType_; |
|
||||
|
|
||||
|
|
||||
qi::rule<It, expressions()> expressions_; |
|
||||
qi::rule<It, std::string()> expression_; |
|
||||
qi::rule<It, Configuration()> row_; |
|
||||
qi::rule<It, std::vector<Configuration>> config_; |
|
||||
}; |
|
@ -0,0 +1,150 @@ |
|||||
|
#include "ConfigYaml.h"
|
||||
|
#include <iostream>
|
||||
|
|
||||
|
std::ostream& operator <<(std::ostream &os, const Label& label) { |
||||
|
os << "\"" << label.label_ << "\"" << "=" << label.text_; |
||||
|
return os; |
||||
|
} |
||||
|
|
||||
|
std::ostream& operator << (std::ostream &os, const Formula& formula) { |
||||
|
os << formula.formula_ << "=" << formula.content_; |
||||
|
return os; |
||||
|
} |
||||
|
|
||||
|
std::ostream& operator << (std::ostream& os, const Action& action) { |
||||
|
os << action.action_; |
||||
|
return os; |
||||
|
} |
||||
|
|
||||
|
std::ostream& operator << (std::ostream& os, const Module& module) { |
||||
|
os << "Module: " << module.module_ << std::endl; |
||||
|
for (auto& action : module.actions_) { |
||||
|
os << action << std::endl; |
||||
|
} |
||||
|
return os; |
||||
|
} |
||||
|
|
||||
|
YAML::Node YAML::convert<Module>::encode(const Module& rhs) { |
||||
|
YAML::Node node; |
||||
|
|
||||
|
node.push_back(rhs.module_); |
||||
|
node.push_back(rhs.actions_); |
||||
|
|
||||
|
return node; |
||||
|
} |
||||
|
|
||||
|
bool YAML::convert<Module>::decode(const YAML::Node& node, Module& rhs) { |
||||
|
if (!node.Type() == NodeType::Map) { |
||||
|
return false; |
||||
|
} |
||||
|
rhs.actions_ = node["actions"].as<std::vector<Action>>(); |
||||
|
rhs.module_ = node["module"].as<std::string>(); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
YAML::Node YAML::convert<Action>::encode(const Action& rhs) { |
||||
|
YAML::Node node; |
||||
|
|
||||
|
node.push_back(rhs.action_); |
||||
|
node.push_back(rhs.guard_); |
||||
|
node.push_back(rhs.overwrite_); |
||||
|
node.push_back(rhs.update_); |
||||
|
|
||||
|
return node; |
||||
|
} |
||||
|
|
||||
|
bool YAML::convert<Action>::decode(const YAML::Node& node, Action& rhs) { |
||||
|
if (!node.Type() == NodeType::Map) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
rhs.action_ = node["action"].as<std::string>(); |
||||
|
rhs.guard_ = node["guard"].as<std::string>(); |
||||
|
rhs.update_ = node["update"].as<std::string>(); |
||||
|
|
||||
|
if (node["overwrite"]) { |
||||
|
rhs.overwrite_ = node["overwrite"].as<bool>(); |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
YAML::Node YAML::convert<Label>::encode(const Label& rhs) { |
||||
|
YAML::Node node; |
||||
|
|
||||
|
node.push_back(rhs.label_); |
||||
|
node.push_back(rhs.text_); |
||||
|
|
||||
|
return node; |
||||
|
} |
||||
|
|
||||
|
bool YAML::convert<Label>::decode(const YAML::Node& node, Label& rhs) { |
||||
|
if (!node.Type() == NodeType::Map) { |
||||
|
return false; |
||||
|
} |
||||
|
rhs.label_ = node["label"].as<std::string>(); |
||||
|
rhs.text_ = node["text"].as<std::string>(); |
||||
|
|
||||
|
if (node["overwrite"]) { |
||||
|
rhs.overwrite_ = node["overwrite"].as<bool>(); |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
YAML::Node YAML::convert<Formula>::encode(const Formula& rhs) { |
||||
|
YAML::Node node; |
||||
|
|
||||
|
node.push_back(rhs.content_); |
||||
|
node.push_back(rhs.formula_); |
||||
|
node.push_back(rhs.overwrite_); |
||||
|
|
||||
|
return node; |
||||
|
} |
||||
|
|
||||
|
bool YAML::convert<Formula>::decode(const YAML::Node& node, Formula& rhs) { |
||||
|
if (!node.Type() == NodeType::Map) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
rhs.formula_ = node["formula"].as<std::string>(); |
||||
|
rhs.content_ = node["content"].as<std::string>(); |
||||
|
|
||||
|
if(node["overwrite"]) { |
||||
|
rhs.overwrite_ = node["overwrite"].as<bool>(); |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
std::vector<Configuration> YamlConfigParser::parseConfiguration() { |
||||
|
std::vector<Configuration> configuration; |
||||
|
|
||||
|
try { |
||||
|
YAML::Node config = YAML::LoadFile(file_); |
||||
|
|
||||
|
const std::vector<Label> labels = config["labels"].as<std::vector<Label>>(); |
||||
|
const std::vector<Formula> formulas = config["formulas"].as<std::vector<Formula>>(); |
||||
|
const std::vector<Module> modules = config["modules"].as<std::vector<Module>>(); |
||||
|
|
||||
|
for (auto& label : labels) { |
||||
|
configuration.push_back({label.text_, label.label_, ConfigType::Label, label.overwrite_}); |
||||
|
} |
||||
|
for (auto& formula : formulas) { |
||||
|
configuration.push_back({formula.content_, formula.formula_ , ConfigType::Formula, formula.overwrite_}); |
||||
|
} |
||||
|
for (auto& module : modules) { |
||||
|
std::cout << module << std::endl; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
catch(const std::exception& e) { |
||||
|
std::cout << "Exception '" << typeid(e).name() << "' caught:" << std::endl; |
||||
|
std::cout << "\t" << e.what() << std::endl; |
||||
|
std::cout << "while parsing configuration " << file_ << std::endl; |
||||
|
} |
||||
|
|
||||
|
return configuration; |
||||
|
} |
@ -0,0 +1,115 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <vector> |
||||
|
#include <ostream> |
||||
|
|
||||
|
#include "yaml-cpp/yaml.h" |
||||
|
|
||||
|
typedef std::string expressions; |
||||
|
|
||||
|
enum class ConfigType : char { |
||||
|
Label = 'L', |
||||
|
Formula = 'F', |
||||
|
Module = 'M' |
||||
|
}; |
||||
|
|
||||
|
struct Configuration |
||||
|
{ |
||||
|
expressions expressions_; |
||||
|
std::string derivation_; |
||||
|
ConfigType type_ {ConfigType::Label}; |
||||
|
bool overwrite_; |
||||
|
|
||||
|
Configuration() = default; |
||||
|
Configuration(std::string expression, std::string derivation, ConfigType type, bool overwrite = false) : expressions_(expression), derivation_(derivation), type_(type), overwrite_(overwrite) {} |
||||
|
~Configuration() = default; |
||||
|
Configuration(const Configuration&) = default; |
||||
|
|
||||
|
friend std::ostream& operator << (std::ostream& os, const Configuration& config) { |
||||
|
os << "Configuration with Type: " << static_cast<char>(config.type_) << std::endl; |
||||
|
os << "\tExpression=" << config.expressions_ << std::endl; |
||||
|
return os << "\tDerviation=" << config.derivation_; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
|
||||
|
struct Label { |
||||
|
private: |
||||
|
|
||||
|
public: |
||||
|
std::string text_; |
||||
|
std::string label_; |
||||
|
bool overwrite_; |
||||
|
|
||||
|
friend std::ostream& operator <<(std::ostream &os, const Label& label); |
||||
|
}; |
||||
|
|
||||
|
struct Formula { |
||||
|
private: |
||||
|
|
||||
|
public: |
||||
|
std::string formula_; |
||||
|
std::string content_; |
||||
|
bool overwrite_; |
||||
|
|
||||
|
friend std::ostream& operator << (std::ostream &os, const Formula& formula); |
||||
|
}; |
||||
|
|
||||
|
struct Action { |
||||
|
public: |
||||
|
std::string action_; |
||||
|
std::string guard_; |
||||
|
std::string update_; |
||||
|
bool overwrite_; |
||||
|
|
||||
|
friend std::ostream& operator << (std::ostream& os, const Action& action); |
||||
|
}; |
||||
|
|
||||
|
struct Module { |
||||
|
public: |
||||
|
|
||||
|
std::vector<Action> actions_; |
||||
|
std::string module_; |
||||
|
|
||||
|
friend std::ostream& operator << (std::ostream& os, const Module& module); |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
template<> |
||||
|
struct YAML::convert<Module> { |
||||
|
static YAML::Node encode(const Module& rhs); |
||||
|
static bool decode(const YAML::Node& node, Module& rhs); |
||||
|
}; |
||||
|
|
||||
|
template<> |
||||
|
struct YAML::convert<Action> { |
||||
|
static YAML::Node encode(const Action& rhs); |
||||
|
static bool decode(const YAML::Node& node, Action& rhs); |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
template<> |
||||
|
struct YAML::convert<Label> { |
||||
|
static YAML::Node encode(const Label& rhs); |
||||
|
static bool decode(const YAML::Node& node, Label& rhs); |
||||
|
}; |
||||
|
|
||||
|
template<> |
||||
|
struct YAML::convert<Formula> { |
||||
|
static YAML::Node encode(const Formula& rhs); |
||||
|
static bool decode(const YAML::Node& node, Formula& rhs); |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
struct YamlConfigParser { |
||||
|
public: |
||||
|
YamlConfigParser(std::string file) : file_(file) {} |
||||
|
YamlConfigParser(const YamlConfigParser&) = delete; |
||||
|
~YamlConfigParser() = default; |
||||
|
|
||||
|
std::vector<Configuration> parseConfiguration(); |
||||
|
private: |
||||
|
|
||||
|
std::string file_; |
||||
|
}; |
Write
Preview
Loading…
Cancel
Save
Reference in new issue