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
Alternative parsers do not roll back changes made to the outer attribute
because of a failed alternative. If you need to enforce that only the
succeeded alternative changes the outer attribute please utilize the
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. See
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]);