Please advise about boost spirit alternative operator.
test_parser() is posted on the official website.
test_parser("Hello", string("Hell") | string("Hello"));
Output
fail
I think that string(“Hell”) is fail ,then next step
try
string(“Hello”) is OK
1
The documentation example is different: https://www.boost.org/doc/libs/1_86_0/libs/spirit/doc/html/spirit/qi/reference/operator/alternative.html#spirit.qi.reference.operator.alternative.example
test_parser("Hello", string("Hello") | int_);
test_parser("123", string("Hello") | int_);
In short, a | b
ONLY EVER parses b
IFF a
fails. The reason for this is that a PEG (Parser Expression Grammar) parses left-to-right greedy. This is documented here: https://www.boost.org/doc/libs/1_86_0/libs/spirit/doc/html/spirit/abstracts/parsing_expression_grammar.html (Note the link to Difference
parsers).
So in your example string("Hello")
will never match, because it would always have matched string("Hell")
first. Re-ordering them helps:
test_parser("Hello", qi::string("Hell") | qi::string("Hello"));
test_parser("Hello", qi::string("Hello") | qi::string("Hell"));
Prints
Matched: Hell
Matched: Hello
You can also consider qi::symbols
which will automatically trie elements in such an order that the longest possible match is found:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
template <typename Expr> void test_parser(std::string_view input, Expr const& parser) {
std::string result;
if (qi::parse(input.begin(), input.end(), parser, result)) {
std::cout << "Matched: " << result << std::endl;
} else {
std::cout << "Failed to match" << std::endl;
}
}
int main() {
test_parser("Hello", qi::string("Hell") | qi::string("Hello"));
test_parser("Hello", qi::string("Hello") | qi::string("Hell"));
std::cout << "nUsing symbols" << std::endl;
qi::symbols<char, std::string> sym;
sym.add("Hello", "Hello");
sym.add("World", "World");
sym.add("Hell", "Hell");
sym.add("Wor", "Wor");
test_parser("Hell", sym);
test_parser("Hello", sym);
test_parser("World", sym);
test_parser("Wor", sym);
test_parser("Worst", sym);
}
Printing
Matched: Hell
Matched: Hello
Using symbols
Matched: Hell
Matched: Hello
Matched: World
Matched: Wor
Matched: Wor
0