Heim >Backend-Entwicklung >C++ >Wie können wir boolesche Ausdrücke in C mit Boost.Spirit analysieren, um eine Baumstruktur zu erstellen und dabei die Priorität der Operatoren zu berücksichtigen?

Wie können wir boolesche Ausdrücke in C mit Boost.Spirit analysieren, um eine Baumstruktur zu erstellen und dabei die Priorität der Operatoren zu berücksichtigen?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-25 19:36:13607Durchsuche

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

Boolesche Ausdrücke in C analysieren

Einführung

Unser Ziel ist es, einen Parser zu erstellen, der einen booleschen Ausdruck in eine Baumstruktur umwandelt und dabei die Prioritätsregeln für Operatoren berücksichtigt (nicht, und, xor, oder).

Tokenisierung

Zu Beginn definieren wir reguläre Ausdrücke, die mit verschiedenen Token im Ausdruck übereinstimmen:

  • Variablen: Folgen eines oder mehrerer alphabetischer Zeichen
  • Operatoren: „und“, „oder“, „xor“, „nicht“
  • Klammern: „(“ und „)“
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_("()[]");

Grammatikregeln

Dann definieren wir zu kombinierende Grammatikregeln Tokens:

  • Ausdruck: Beginnt entweder mit einem Ausdruck in Klammern, einer Variablen oder „nicht“, gefolgt von einem Ausdruck
  • Unterausdruck: Folgt den Vorrangregeln (nicht, und, xor, oder)
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_;

Parsen

Um den Ausdruck zu parsen, verwenden wir eine boost::spirit Phrase_parse-Funktion, die versucht, die gesamte Eingabezeichenfolge mit den Grammatikregeln abzugleichen.

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

Den Baum erstellen

Sobald der Ausdruck analysiert ist, können wir es tun Konstruieren Sie die Baumstruktur. Hier ist eine Beispielimplementierung:

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

Beispielverwendung

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

Ausgabe:

(
a
and
b
)
xor
(
c
and
d
)

Das obige ist der detaillierte Inhalt vonWie können wir boolesche Ausdrücke in C mit Boost.Spirit analysieren, um eine Baumstruktur zu erstellen und dabei die Priorität der Operatoren zu berücksichtigen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn