Header lexy/dsl/choice.hpp
Rule lexy::dsl::operator|
lexy/dsl/choice.hpp
namespace lexy
{
struct exhausted_choice {};
}
namespace lexy::dsl
{
struct choice {}; // models rule, and sometimes branch-rule
constexpr choice operator|(branch-rule auto lhs, branch-rule auto rhs);
constexpr choice operator|(choice lhs, branch-rule auto rhs);
constexpr choice operator|(branch-rule auto lhs, choice rhs);
constexpr choice operator|(choice lhs, choice rhs);
}
operator|
(choice) is a rule that parses one of the specified branch rules.
- Parsing
Tries to parse
lhs
, then tries to parserhs
.- Branch parsing
It is a branch rule if neither
lhs
norrhs
are unconditional branches (e.g.lexy::dsl::else_
). Tries to parselhs
, then tries to parserhs
. Backtracks instead of failing for an exhausted choice.- Errors
lexy::exhausted_choice
: if neitherlhs
norrhs
could be parsed, at the starting reader position. The rule then fails.All errors raised by
lhs
orrhs
during branch parsing. The rule then fails if they have failed.
- Values
All values produced by the selected branch.
operator|
can be chained:
a | (b | c)
is equivalent to a | lexy::dsl::else_ >> (b | c)
, and likewise for the other cases.
Example 1. Parse a greeting
Example 2. Raise a different error if no greeting matches
Example 3. Do something differently if no greeting matches
Example 4. Branches can be arbitrarily complex
constexpr auto id = dsl::identifier(dsl::ascii::alpha);
constexpr auto kw_function = LEXY_KEYWORD("function", id);
constexpr auto kw_type = LEXY_KEYWORD("type", id);
struct function_decl
{
static constexpr auto rule = [] {
auto arguments = dsl::parenthesized(LEXY_LIT("..."));
auto body = dsl::curly_bracketed(LEXY_LIT("..."));
return kw_function >> id + arguments + body;
}();
};
struct type_decl
{
static constexpr auto rule //
= kw_type >> id + dsl::lit_c<'='> + id + dsl::semicolon;
};
struct production
{
static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = dsl::p<function_decl> | dsl::p<type_decl>;
};
Example 5. Only the branch condition is checked
Tip | Use lexy::dsl::operator>> to turn a rule into a branch by giving it a condition.
Use lexy::dsl::peek or lexy::dsl::lookahead as conditions if there is no simple token rule to check the beginning of the branch. |
Note | If one of the branches is always taken (e.g. because it uses lexy::dsl::else_ ), the lexy::exhausted_choice error is never raised. |