Rumah > pembangunan bahagian belakang > C++ > Bagaimanakah kita boleh menghuraikan ungkapan Boolean dalam C menggunakan Boost.Spirit untuk mencipta struktur pokok, menghormati keutamaan pengendali?

Bagaimanakah kita boleh menghuraikan ungkapan Boolean dalam C menggunakan Boost.Spirit untuk mencipta struktur pokok, menghormati keutamaan pengendali?

Mary-Kate Olsen
Lepaskan: 2024-12-25 19:36:13
asal
610 orang telah melayarinya

How can we parse Boolean expressions in C   using Boost.Spirit to create a tree structure, respecting operator precedence?

Menghuraikan Ungkapan Boolean dalam C

Pengenalan

Kami menyasarkan untuk mencipta penghurai yang mengubah ungkapan boolean kepada struktur pokok, menghormati peraturan keutamaan operator (bukan, dan, xor, atau).

Tokenisasi

Untuk bermula, kami akan mentakrifkan ungkapan biasa untuk memadankan token yang berbeza dalam ungkapan:

  • Pembolehubah: Urutan satu atau lebih aksara abjad
  • Pengendali: "dan", "atau", "xor", "bukan"
  • Kurungan: "(" dan ")"
using namespace boost::spirit::qi;
typedef std::string var;
qi::rule<std::string::const_iterator, var(), qi::space_type> var_ = qi::lexeme[+alpha];
qi::rule<std::string::const_iterator, std::string(), qi::space_type> operator_ = 
    keywords("and" | "or" | "xor" | "not");
qi::rule<std::string::const_iterator, char(), qi::space_type> parenthesis_ = qi::char_("()[]");
Salin selepas log masuk

Peraturan Tatabahasa

Kemudian, kami mentakrifkan peraturan tatabahasa untuk digabungkan token:

  • Ungkapan: Bermula dengan sama ada ungkapan dalam kurungan, pembolehubah atau "tidak" diikuti dengan ungkapan
  • Sub-ungkapan: Ikut peraturan keutamaan (bukan, dan, xor, atau)
qi::rule<std::string::const_iterator, expr(), qi::space_type> expression_ = (
    '(' >> expression_ >> ')'
) | var_ | operator_ >> expression_;

qi::rule<std::string::const_iterator, expr(), qi::space_type> sub_expression_ = 
    expression_ >> *operator_ >> expression_;
Salin selepas log masuk

Menghuraikan

Untuk menghuraikan ungkapan, kami menggunakan fungsi boost::spirit phrase_parse, yang cuba memadankan keseluruhan rentetan input dengan peraturan tatabahasa.

std::string input = "(a and b) xor (c and d)";
auto it = input.begin();
auto end = input.end();
expr parsed_expression;

bool success = phrase_parse(it, end, expression_, qi::space, parsed_expression);

if (success && it == end) {
    std::cout << "Parse successful!" << std::endl;
} else {
    std::cerr << "Parse failed!" << std::endl;
}
Salin selepas log masuk

Membina Pokok

Setelah ungkapan dihuraikan, kita boleh membina pokok itu struktur. Berikut ialah contoh pelaksanaan:

typedef std::vector<expr> expr_set;
expr_set nodes;

void create_node(const expr& sub_expr) {
    if (sub_expr.is<std::string>()) {
        nodes.push_back(sub_expr.get<std::string>());
    } else {
        nodes.push_back(expr_set{sub_expr.get<expr_set>()});
    }
}

void build_tree(const expr& root) {
    if (root.is<std::string>()) {
        nodes.push_back(root.get<std::string>());
    } else {
        expr_set sub_expressions = root.get<expr_set>();
        for (const auto& sub_expr : sub_expressions) {
            create_node(sub_expr);
        }
    }
}
Salin selepas log masuk

Contoh Penggunaan

input = "(a and b) xor (c and d)";
it = input.begin();
end = input.end();

if (phrase_parse(it, end, expression_, qi::space, parsed_expression)) {
    std::cout << "Parse successful!" << std::endl;
    build_tree(parsed_expression);
} else {
    std::cerr << "Parse failed!" << std::endl;
}

for (const auto& node : nodes) {
    std::cout << node << std::endl;
}
Salin selepas log masuk

Output:

(
a
and
b
)
xor
(
c
and
d
)
Salin selepas log masuk

Atas ialah kandungan terperinci Bagaimanakah kita boleh menghuraikan ungkapan Boolean dalam C menggunakan Boost.Spirit untuk mencipta struktur pokok, menghormati keutamaan pengendali?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan