gpt4 book ai didi

c++ - 如何从此示例更改代码

转载 作者:行者123 更新时间:2023-12-02 10:56:39 24 4
gpt4 key购买 nike

如何更改代码source以显示结果?

我无法转换以提升精神x3

Live Code

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

最佳答案

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); }

您认为这些功能做什么?如果查看链接的示例,则会看到具体的实现:

Originally, here:
struct printer : boost::static_visitor<void>
{
printer(std::ostream& os) : _os(os) {}
std::ostream& _os;

//
void operator()(const var& v) const { _os << v; }

void operator()(const binop<op_and>& b) const { print(" & ", b.oper1, b.oper2); }
void operator()(const binop<op_or >& b) const { print(" | ", b.oper1, b.oper2); }
void operator()(const binop<op_xor>& b) const { print(" ^ ", b.oper1, b.oper2); }

void print(const std::string& op, const expr& l, const expr& r) const
{
_os << "(";
boost::apply_visitor(*this, l);
_os << op;
boost::apply_visitor(*this, r);
_os << ")";
}

void operator()(const unop<op_not>& u) const
{
_os << "(";
_os << "!";
boost::apply_visitor(*this, u.oper1);
_os << ")";
}
};

std::ostream& operator<<(std::ostream& os, const expr& e)
{ boost::apply_visitor(printer(os), e); return os; }

因此,您期望编写如下内容:
struct printer {
using result_type = void;
std::ostream& _os;

static auto name(op_and /*unused*/) { return "AND"; }
static auto name(op_not /*unused*/) { return "NOT"; }
static auto name(op_or /*unused*/) { return "OR"; }
static auto name(op_xor /*unused*/) { return "XOR"; }

void operator()(const var& v) const { _os << v; }
template <typename Op>
void operator()(const unop<Op>& u) const {
_os << "(" << name(Op{}) << " ";
operator()(u.operand);
_os << ")";
}
template <typename Op>
void operator()(const combination_op<Op>& b) const {
_os << "(";
bool first = true;
for (auto& e : b.operands) {
if (!std::exchange(first, false)) {
_os << " " << name(Op{}) << " ";

}

operator()(e);
}
_os << ")";
}

void operator()(expr const& v) const {
boost::apply_visitor(*this, v);
}
};

哪个打印( Live On Coliru)
"or(a and(b c))" -> (a OR (b AND c))

如果您想要输出类似于您解析的内容:
    template <typename Op> void operator()(const unop<Op>& u) const {
operator()(combination_op<Op>{{u.operand}});
}
template <typename Op> void operator()(const combination_op<Op>& b) const {
_os << name(Op{}) << "(";
for (auto& e : b.operands) {
_os << " ";
operator()(e);
}
_os << ")";
}

列印( Live On Coliru):
"or(a and(b c))" -> OR( a AND( b c))

As you can see, I that implementation highlights that the "function call" syntax doesn't essentially require difference between unary and binary operators



完整 list

第一种变化:
// #define BOOST_SPIRIT_X3_DEBUG
#include <boost/fusion/adapted.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <string>
#include <iostream>
#include <iomanip>
#include <vector>
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 {
using result_type = void;
std::ostream& _os;

static auto name(op_and /*unused*/) { return "AND"; }
static auto name(op_not /*unused*/) { return "NOT"; }
static auto name(op_or /*unused*/) { return "OR"; }
static auto name(op_xor /*unused*/) { return "XOR"; }

void operator()(const var& v) const { _os << v; }
template <typename Op>
void operator()(const unop<Op>& u) const {
_os << "(" << name(Op{}) << " ";
operator()(u.operand);
_os << ")";
}
template <typename Op>
void operator()(const combination_op<Op>& b) const {
_os << "(";
bool first = true;
for (auto& e : b.operands) {
if (!std::exchange(first, false)) {
_os << " " << name(Op{}) << " ";

}

operator()(e);
}
_os << ")";
}

void operator()(expr const& v) const {
boost::apply_visitor(*this, v);
}
};
} }

int main() {
std::string storage = "or(a and(b 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) {
client::ast::printer print{std::cout};
std::cout << std::quoted(storage) << " -> ";
print(result);
std::cout << "\n";
} else {
std::cout << "Failed\n";
}
if (iter != end) {
std::cout << "Remaining: " << std::quoted(std::string(iter, end)) << "\n";
}
}

关于c++ - 如何从此示例更改代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61639325/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com