#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_; };