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).
Zu Beginn definieren wir reguläre Ausdrücke, die mit verschiedenen Token im Ausdruck übereinstimmen:
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_("()[]");
Dann definieren wir zu kombinierende Grammatikregeln Tokens:
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_;
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; }
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); } } }
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!