How can I change the code source to display the result?
I could not convert to boost spirit x3
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted.hpp>
namespace x3 = boost::spirit::x3;
namespace client { namespace ast {
struct op_or {};
struct op_and {};
struct op_xor {};
struct op_not {};
template <typename tag> struct combination_op;
template <typename tag> struct unop;
typedef std::string var;
typedef boost::variant<
var,
boost::recursive_wrapper<unop<op_not>>,
boost::recursive_wrapper<combination_op<op_and>>,
boost::recursive_wrapper<combination_op<op_xor>>,
boost::recursive_wrapper<combination_op<op_or>>
>expr;
template <typename tag> struct combination_op {
typedef std::vector<expr> operands_t;
combination_op() = default;
combination_op(operands_t const& operands) : operands(operands) {}
operands_t operands;
};
template <typename tag> struct unop {
unop() = default;
unop(const expr& o) : operand(o) {}
expr operand;
};
}}
BOOST_FUSION_ADAPT_STRUCT(client::ast::combination_op<client::ast::op_and>, operands)
BOOST_FUSION_ADAPT_STRUCT(client::ast::combination_op<client::ast::op_xor>, operands)
BOOST_FUSION_ADAPT_STRUCT(client::ast::combination_op<client::ast::op_or>, operands)
BOOST_FUSION_ADAPT_STRUCT(client::ast::unop<client::ast::op_not>, operand)
namespace client { namespace parser {
x3::rule<class var, ast::var> var{ "var" };
x3::rule<class not, ast::unop<ast::op_not>> not{ "not" };
x3::rule<class and, ast::combination_op<ast::op_and>> and{ "and" };
x3::rule<class xor, ast::combination_op<ast::op_xor>> xor{ "xor" };
x3::rule<class or, ast::combination_op<ast::op_or >> or{ "or" };
x3::rule<class expr, ast::expr> expr { "expr" };
auto const expr_def = xor | and | or | not | var;
auto const expr_list = *expr;
auto const or_def = x3::no_case["or"] >> '(' >> expr_list >> ')';
auto const xor_def = x3::no_case["xor"] >> '(' >> expr_list >> ')';
auto const and_def = x3::no_case["and"] >> '(' >> expr_list >> ')';
auto const not_def = x3::no_case["not"] >> expr;
auto const var_def = x3::lexeme[+x3::alpha];
BOOST_SPIRIT_DEFINE(var,not,and,xor,or,expr);
}}
namespace client { namespace ast {
struct printer :boost::static_visitor<void> {
printer() {}
void operator()(const var& v) const{ }
void operator()(const combination_op<op_and>& b) const { recurse(b); }
void operator()(const combination_op<op_xor>& b) const { recurse(b); }
void operator()(const combination_op<op_or>& b) const { recurse(b); }
void operator()(const unop<op_not>& u) const { recurse(u.operand); }
template<typename T>
void recurse(T const& v) const {
//boost::apply_visitor(*this, v);
}
};
}}
int main() {
std::string storage = "a or (b and c)";
client::ast::expr result;
typedef std::string::const_iterator iterator_t;
iterator_t iter = storage.begin(), end = storage.end();
using x3::ascii::space;
bool ok = phrase_parse(iter, end, client::parser::expr, space, result);
if (ok && iter == end) {
boost::apply_visitor(client::ast::printer(), result);
}
return 0;
}