The alternative operator,
matches one of two or more operands (
b, ... etc.):
a | b | ...
Alternative operands are tried one by one on a first-match-wins basis starting from the leftmost operand. After a successfully matched alternative is found, the parser concludes its search, essentially short-circuiting the search for other potentially viable candidates. This short-circuiting implicitly gives the highest priority to the leftmost alternative.
Short-circuiting is done in the same manner as C or C++'s logical expressions;
if (x < 3 || y
< 2) where, if
2 test is not done at all. In addition
to providing an implicit priority rule for alternatives which is necessary,
given its non-deterministic nature, short-circuiting improves the execution
time. If the order of your alternatives is logically irrelevant, strive
to put the (expected) most common choice first for maximum efficiency.
// forwards to <boost/spirit/home/qi/operator/alternative.hpp> #include <boost/spirit/include/qi_alternative.hpp>
Also, see Include Structure.
Semantics of an expression is defined only where it differs from, or
is not defined in
a: A, b: B --> (a | b): variant<A, B> a: A, b: Unused --> (a | b): optional<A> a: A, b: B, c: Unused --> (a | b | c): optional<variant<A, B> > a: Unused, b: B --> (a | b): optional<B> a: Unused, b: Unused --> (a | b): Unused a: A, b: A --> (a | b): A
The overall complexity of the alternative parser is defined by the sum of the complexities of its elements. The complexity of the alternative parser itself is O(N), where N is the number of alternatives.
The test harness for the example(s) below is presented in the Basics Examples section.
Some using declarations:
using boost::spirit::ascii::string; using boost::spirit::qi::int_; using boost::spirit::qi::_1; using boost::variant;
test_parser("Hello", string("Hello") | int_); test_parser("123", string("Hello") | int_);
Extracting the attribute variant (using Boost.Variant):
variant<std::string, int> attr; test_parser_attr("Hello", string("Hello") | int_, attr);
This should print
Note: There are better ways to extract the value from the variant.
visitation. This code is solely for demonstration.
if (boost::get<int>(&attr)) std::cout << boost::get<int>(attr) << std::endl; else std::cout << boost::get<std::string>(attr) << std::endl;
Extracting the attributes using Semantic Actions with Phoenix
(this should print
test_parser("123", (string("Hello") | int_)[std::cout << _1 << std::endl]);