diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ca1571..1a7c5c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,9 +14,11 @@ project( VERSION 0.1 LANGUAGES CXX) +find_package(yaml-cpp) + add_executable(main ${SRCS} main.cpp ) -target_link_libraries(main pthread) +target_link_libraries(main pthread yaml-cpp) diff --git a/main.cpp b/main.cpp index 19d3c25..1eaa0c7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,13 +1,14 @@ #include "util/OptionParser.h" #include "util/MinigridGrammar.h" #include "util/Grid.h" -#include "util/ConfigGrammar.h" +#include "util/ConfigYaml.h" #include #include #include #include + std::vector parseCommaSeparatedString(std::string const& str) { std::vector result; std::stringstream stream(str); @@ -20,6 +21,7 @@ std::vector parseCommaSeparatedString(std::string const& str) { return result; } + struct printer { typedef boost::spirit::utf8_string string; @@ -104,7 +106,7 @@ int main(int argc, char* argv[]) { std::fstream file {outputFilename->value(0), file.trunc | file.out}; std::fstream infile {inputFilename->value(0), infile.in}; - std::string line, content, background, rewards, config; + std::string line, content, background, rewards; std::cout << "\n"; bool parsingBackground = false; bool parsingStateRewards = false; @@ -129,15 +131,6 @@ int main(int argc, char* argv[]) { } std::cout << "\n"; - - if (configFilename->is_set()) { - std::fstream configFile {configFilename->value(0), configFile.in}; - while (std::getline(configFile, line) && !line.empty()) { - std::cout << "Configuration:\t" << line << "\n"; - config += line + "\n"; - } - } - pos_iterator_t contentFirst(content.begin()); pos_iterator_t contentIter = contentFirst; pos_iterator_t contentLast(content.end()); @@ -146,11 +139,7 @@ int main(int argc, char* argv[]) { pos_iterator_t backgroundIter = backgroundFirst; pos_iterator_t backgroundLast(background.end()); MinigridParser backgroundParser(backgroundFirst); - pos_iterator_t configFirst(config.begin()); - pos_iterator_t configIter = configFirst; - pos_iterator_t configLast(config.end()); - ConfigParser configParser(configFirst); - + cells contentCells; cells backgroundCells; std::vector configurations; @@ -161,7 +150,8 @@ int main(int argc, char* argv[]) { ok &= phrase_parse(backgroundIter, backgroundLast, backgroundParser, qi::space, backgroundCells); // TODO } if (configFilename->is_set()) { - ok &= phrase_parse(configIter, configLast, configParser, qi::space, configurations); + YamlConfigParser parser(configFilename->value(0)); + configurations = parser.parseConfiguration(); } for (auto& config : configurations) { diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index f5884fe..877fde4 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -5,4 +5,5 @@ list(APPEND SRCS ${CMAKE_CURRENT_LIST_DIR}/PrismModulesPrinter.cpp ${CMAKE_CURRENT_LIST_DIR}/popl.hpp ${CMAKE_CURRENT_LIST_DIR}/OptionParser.cpp + ${CMAKE_CURRENT_LIST_DIR}/ConfigYaml.cpp ) diff --git a/util/ConfigGrammar.h b/util/ConfigGrammar.h deleted file mode 100644 index 71aa54d..0000000 --- a/util/ConfigGrammar.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include "cell.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace qi = boost::spirit::qi; -namespace phoenix = boost::phoenix; - -typedef std::vector 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(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 - struct ConfigParser : qi::grammar> -{ - 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 configType_; - - - qi::rule expressions_; - qi::rule expression_; - qi::rule row_; - qi::rule> config_; -}; diff --git a/util/ConfigYaml.cpp b/util/ConfigYaml.cpp new file mode 100644 index 0000000..4e5d6ef --- /dev/null +++ b/util/ConfigYaml.cpp @@ -0,0 +1,150 @@ +#include "ConfigYaml.h" +#include + +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::encode(const Module& rhs) { + YAML::Node node; + + node.push_back(rhs.module_); + node.push_back(rhs.actions_); + + return node; +} + +bool YAML::convert::decode(const YAML::Node& node, Module& rhs) { + if (!node.Type() == NodeType::Map) { + return false; + } + rhs.actions_ = node["actions"].as>(); + rhs.module_ = node["module"].as(); + return true; +} + +YAML::Node YAML::convert::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::decode(const YAML::Node& node, Action& rhs) { + if (!node.Type() == NodeType::Map) { + return false; + } + + rhs.action_ = node["action"].as(); + rhs.guard_ = node["guard"].as(); + rhs.update_ = node["update"].as(); + + if (node["overwrite"]) { + rhs.overwrite_ = node["overwrite"].as(); + } + + return true; +} + + +YAML::Node YAML::convert