ホームページ >バックエンド開発 >C++ >Boost.Spirit を使用して C でブール式を解析し、演算子の優先順位を考慮してツリー構造を作成するにはどうすればよいでしょうか?

Boost.Spirit を使用して C でブール式を解析し、演算子の優先順位を考慮してツリー構造を作成するにはどうすればよいでしょうか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-25 19:36:13564ブラウズ

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

C でのブール式の解析

はじめに

私たちは、演算子の優先順位規則を尊重して、ブール式をツリー構造に変換するパーサーを作成することを目指しています。 (そうではない、そして、xor、または).

トークン化

まず、式内のさまざまなトークンに一致する正規表現を定義します:

  • 変数: 1 つ以上のアルファベットの並び文字
  • 演算子: "and"、"or"、"xor"、"not"
  • 括弧: "(" および ") "
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_("()[]");

文法ルール

次に、トークンを組み合わせる文法ルールを定義します。

  • 式: 括弧で囲まれた式、変数、または「not」のいずれかで始まり、その後に「not」が続きます。式
  • サブ式: 優先規則に従います(not、and、xor、or)
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_;

解析

式を解析するには、入力全体との一致を試みる boost::spiritphrase_parse 関数を使用します。文法規則に反する文字列。

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

を構築しています。 Tree

式が解析されると、ツリー構造を構築できます。以下に実装例を示します:

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

使用例

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

出力:

(
a
and
b
)
xor
(
c
and
d
)

以上がBoost.Spirit を使用して C でブール式を解析し、演算子の優先順位を考慮してツリー構造を作成するにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。