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
Freigeben: 2024-12-25 19:36:13
Original
610 Leute haben es durchsucht

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_("()[]");
Nach dem Login kopieren

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_;
Nach dem Login kopieren

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;
}
Nach dem Login kopieren

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);
        }
    }
}
Nach dem Login kopieren

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;
}
Nach dem Login kopieren

Ausgabe:

(
a
and
b
)
xor
(
c
and
d
)
Nach dem Login kopieren

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!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage