Header lexy/dsl/combination.hpp

The combination and partial_combination rules.

Rule lexy::dsl::combination

lexy/dsl/combination.hpp
namespace lexy
{
    struct combination_duplicate {};
}

namespace lexy::dsl
{
    struct combination-dsl // models rule
    {
        template <typename Tag>
        static constexpr rule auto missing_error;

        template <typename Tag>
        static constexpr rule auto duplicate_error;
    };

    constexpr combination-dsl combination(branch-rule auto ... branches);
}

combination is a rule that parses all of the specified branch rules, but in arbitrary order.

Parsing

Parses the choice (branches | …​) a total of sizeof…​(branches) times in sequence.

Errors
  • lexy::exhausted_choice: if one iteration of the choice does not match; at the starting position of the iteration. The rule then fails. This error tag can be changed by specifying a different Tag using .missing_error.

  • lexy::combination_duplicate: if one iteration parses a branch rule that has already been selected in a previous iteration; at the starting position of the later iteration. The rule then recovers without consuming additional input, but the values produced by the duplicate are not forwarded to the sink, and the duplicated iteration does not count towards the total number of repetitions. This error tag can be changed by specifying a different Tag using .duplicate_error.

  • All other errors raised by the choice (branches | …​), i.e. the errors raised by the individual rules during branch parsing. The rule then fails if they have failed.

Values

It creates a sink of the current context. All values produced by the selected branch in an iteration are forwarded to the sink. The value of the finished sink is produced as only value of the combination rule.

Example 1. Parse a, b, c in some order
struct production
{
    static constexpr auto rule
        = dsl::combination(dsl::lit_c<'a'>, dsl::lit_c<'b'>, dsl::lit_c<'c'>);
};
Warning
The branches are always tried in the same order and branches already taken are not removed in future iterations. If an earlier branch always matches the same as a later branch, the later branch is not taken and the rule cannot succeed.
Tip
Use lexy::dsl::member together with lexy::as_aggregate as the sink.

Rule lexy::dsl::partial_combination

lexy/dsl/combination.hpp
namespace lexy::dsl
{
    struct partial-combination-dsl // models rule
    {
        template <typename Tag>
        static constexpr rule auto duplicate_error;
    };

    constexpr auto partial_combination(branch-rule auto ... branches)
      -> partial-combination-dsl;
}

partial_combination is a rule that parses a subset of the specified branch rules, but in arbitrary order.

Parsing

Parses the choice (branches | …​) a total of sizeof…​(branches) times in sequence. If the choice would fail with a lexy::exhausted_choice error, this error is not reported. Instead the rule succeeds early without consuming additional input.

Errors
  • lexy::combination_duplicate: if one iteration parses a branch rule that has already been selected in a previous iteration; at the starting position of the later iteration. The rule then recovers without consuming additional input, but the values produced by the duplicate are not forwarded to the sink, and the duplicated iteration does not count towards the total number of repetitions. This error tag can be changed by specifying a different Tag using .duplicate_error.

  • All other errors raised by the choice (branches | …​), i.e. the errors raised by the individual rules during branch parsing. The rule then fails if they have failed.

Values

It creates a sink of the current context. All values produced by the selected branch in an iteration are forwarded to the sink. The value of the finished sink is produced as only value of the combination rule.

Example 2. Parse a subset of a, b, c in some order
struct production
{
    static constexpr auto rule
        = dsl::partial_combination(dsl::lit_c<'a'>, dsl::lit_c<'b'>, dsl::lit_c<'c'>);
};
Note
partial_combination can match the empty string.

See also