Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah Boost Spirit boleh digunakan untuk menghuraikan ungkapan Boolean dengan keutamaan pengendali?

Bagaimanakah Boost Spirit boleh digunakan untuk menghuraikan ungkapan Boolean dengan keutamaan pengendali?

Linda Hamilton
Linda Hamiltonasal
2024-12-21 22:33:40836semak imbas

How can Boost Spirit be used to parse Boolean expressions with operator precedence?

Penghuraian Ungkapan Boolean

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).

Tingkatkan Semangat Implementation

Boost Spirit boleh digunakan untuk mencipta penghurai turunan rekursif berdasarkan templat ungkapan. Berikut ialah pelaksanaannya:

Jenis Data Abstrak

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;

Peraturan Tatabahasa

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

Beroperasi pada Pokok Sintaks

Untuk melintasi dan mencetak sintaks pokok:

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

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

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

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

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

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

Ujian Output

Penghuraikan dengan betul mengendalikan peraturan keutamaan dan output:

result: ((a &amp; b) ^ ((c &amp; d) | (a &amp; b)))
result: ((a &amp; b) ^ ((c &amp; d) | (a &amp; b)))
result: (a &amp; b)
result: (a | b)
result: (a ^ b)
result: (!a)
result: ((!a) &amp; b)
result: (!(a &amp; b))
result: ((a | b) | c)

Kod Penuh dan Contoh Langsung (Coliru)

[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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn