Diberi ungkapan Boolean dalam bentuk: "a dan b xor (c dan d atau a dan b);", matlamatnya adalah untuk menghuraikannya ke dalam pokok, mematuhi peraturan keutamaan (bukan, dan, xor, atau).
Boost Spirit boleh digunakan untuk mencipta penghurai turunan rekursif berdasarkan templat ungkapan. Berikut ialah pelaksanaannya:
struct op_or {}; // tag struct op_and {}; // tag struct op_xor {}; // tag struct op_not {}; // tag typedef std::string var; template <typename tag> struct binop; template <typename tag> struct unop; typedef boost::variant<var, boost::recursive_wrapper<unop <op_not> >, boost::recursive_wrapper<binop<op_and> >, boost::recursive_wrapper<binop<op_xor> >, boost::recursive_wrapper<binop<op_or> > > expr;
template <typename It, typename Skipper = qi::space_type> struct parser : qi::grammar<It, expr(), Skipper> { parser() : parser::base_type(expr_) { using namespace qi; expr_ = or_.alias(); not_ = ("not" > simple ) [ _val = phx::construct<unop <op_not>>(_1) ] | simple [ _val = _1 ]; #ifdef RIGHT_ASSOCIATIVE or_ = (xor_ >> "or" >> or_ ) [ _val = phx::construct<binop<op_or >>(_1, _2) ] | xor_ [ _val = _1 ]; xor_ = (and_ >> "xor" >> xor_) [ _val = phx::construct<binop<op_xor>>(_1, _2) ] | and_ [ _val = _1 ]; and_ = (not_ >> "and" >> and_) [ _val = phx::construct<binop<op_and>>(_1, _2) ] | not_ [ _val = _1 ]; #else or_ = xor_ [ _val = _1 ] >> *("or" >> xor_ [ _val = phx::construct<binop<op_or>> (_val, _1) ]); xor_ = and_ [ _val = _1 ] >> *("xor" >> and_ [ _val = phx::construct<binop<op_xor>>(_val, _1) ]); and_ = not_ [ _val = _1 ] >> *("and" >> not_ [ _val = phx::construct<binop<op_and>>(_val, _1) ]); #endif simple = (('(' > expr_ > ')') | var_); var_ = qi::lexeme[ +alpha ]; } private: qi::rule<It, var() , Skipper> var_; qi::rule<It, expr(), Skipper> not_, and_, xor_, or_, simple, expr_; };
Untuk melintasi dan mencetak sintaks pokok:
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; }
Penghuraikan dengan betul mengendalikan peraturan keutamaan dan output:
result: ((a & b) ^ ((c & d) | (a & b))) result: ((a & b) ^ ((c & d) | (a & b))) result: (a & b) result: (a | b) result: (a ^ b) result: (!a) result: ((!a) & b) result: (!(a & b)) result: ((a | b) | c)
[Klik di sini untuk mencuba dan melihat kod penuh pada Coliru](https://coliru.stacked-crooked.com/a/a795dea9a310e79bb12db3fe86fa61cf)
Atas ialah kandungan terperinci Bagaimanakah Boost Spirit boleh digunakan untuk menghuraikan ungkapan Boolean dengan keutamaan pengendali?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!