...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The alternative operator, a
| b
,
matches one of two or more operands (a
,
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;
e.g. if (x < 3 || y
< 2)
where, if x
< 3
,
the y <
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.
Notation
a
, b
A Parser
Semantics of an expression is defined only where it differs from, or
is not defined in NaryParser
.
Expression |
Semantics |
---|---|
|
Match |
See Compound Attribute Notation.
Expression |
Attribute |
---|---|
|
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
|
Note | |
---|---|
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
directive |
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.
Note | |
---|---|
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;
Simple usage:
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 "Hello"
.
Note: There are better ways to extract the value from the variant. See
Boost.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 123
):
test_parser("123", (string("Hello") | int_)[std::cout << _1 << std::endl]);