Header lexy/dsl/flags.hpp

Parse an optional flag or multiple ones.

Rule lexy::dsl::flag

lexy/dsl/flags.hpp
namespace lexy::dsl
{
    template <auto If, auto Else = decltype(If){}>
    constexpr rule auto flag(branch-rule auto branch);

    constexpr rule auto flag(branch-rule auto branch)
    {
        return flag<true, false>(branch);
    }
}

flag is a rule that tries to parse a branch rule and produces If, otherwise Else.

Parsing

Tries to parse branch. If that backtracks, succeeds without consuming anything.

Errors

All errors raised by branch during branch parsing. The rule then fails if branch has failed.

Values

If branch was parsed, If followed by all values produced by it. Otherwise, Else.

Note
Use lexy::dsl::opt  if you only want a value if branch did not match.

Rule lexy::dsl::flags

lexy/dsl/flags.hpp
namespace lexy
{
    struct duplicate_flag {};
}

namespace lexy::dsl
{
    struct flag-rule // models rule
    {
        template <typename Tag>
        static constexpr rule auto error;
    };

    constexpr rule auto flags(symbol-rule flag_rule);

    template <auto Default>
    constexpr rule auto flags(symbol-rule flag_rule);
}

flags is a rule that parses a combination of enum flags in any order.

Requires

flag_rule is a lexy::dsl::symbol  rule that maps strings to enum values, which do not have common bits set. Default is of the same enum type.

Parsing

Repeatedly matches and consumes flag_rule until it does not match anymore.

Errors

lexy::duplicate_flag: if a flag has already been parsed; its range covers the duplicate flag. This is determined by checking whether the bit set by a flag has already been set in the result (result & flag) != 0. The tag can be overridden by .error.

Values

Default | …​ | flags where Default is the specified value or else a default-constructed enum, and flags are all the flags parsed.

Example 1. Parse cv qualifiers
enum class cv_qualifier
{
    none      = 0,
    const_    = 1 << 1,
    volatile_ = 1 << 2,
};

struct production
{
    static constexpr auto whitespace = dsl::ascii::space;

    // Map cv-qualifiers to their value.
    static constexpr auto cv = lexy::symbol_table<cv_qualifier> //
                                   .map<LEXY_SYMBOL("const")>(cv_qualifier::const_)
                                   .map<LEXY_SYMBOL("volatile")>(cv_qualifier::volatile_);

    // Parse any combination of cv qualifiers.
    static constexpr auto rule = dsl::flags(dsl::symbol<cv>(dsl::identifier(dsl::ascii::alpha)));

    static constexpr auto value = lexy::forward<cv_qualifier>;
};
Note
The enum type does not need to overload bitwise operators; the code operators on its underlying integer type and casts back at the end.
Note
It is equivalent to lexy::dsl::partial_combination  with a sink that performs a bitwise or.

See also