Header lexy/dsl/lookahead.hpp

Branch rule lexy::dsl::lookahead

lexy/dsl/lookahead.hpp
namespace lexy
{
    struct lookahead_failure {};
}

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

    constexpr lookahead lookahead(auto needle, auto end);
}

lookahead is a branch rule that checks if needle is found before end.

Requires

needle and end are literal rules or lexy::dsl::literal_set.

Parsing

If it can match needle before end is matched or before EOF is reached, the branch is taken without having consumed any input. Otherwise, it raises an error.

Branch parsing

Same as parsing, but backtracks instead of raising an error.

Errors

A generic error with the specified Tag or lexy::lookahead_failure at the position where it started to match the lookahead rule. It then recovers without consuming additional input.

Values

None.

Example 1. Look for an = sign before deciding on a branch
struct flag
{
    std::optional<std::string> key;
    std::string                value;
};

struct production
{
    struct flag_key
    {
        static constexpr auto rule  = dsl::identifier(dsl::ascii::alpha);
        static constexpr auto value = lexy::as_string<std::string>;
    };

    struct flag_value
    {
        static constexpr auto rule  = dsl::identifier(dsl::ascii::alnum);
        static constexpr auto value = lexy::as_string<std::string>;
    };

    static constexpr auto whitespace = dsl::ascii::blank; // no newline

    static constexpr auto rule = [] {
        // key = value
        auto key_value = dsl::p<flag_key> + dsl::lit_c<'='> + dsl::p<flag_value>;
        // no key, just value
        auto value = dsl::nullopt + dsl::p<flag_value>;

        // We have a key if we're having an equal sign before the newline.
        auto key_condition = dsl::lookahead(dsl::lit_c<'='>, dsl::newline);
        return (key_condition >> key_value | dsl::else_ >> value) + dsl::eol;
    }();

    static constexpr auto value = lexy::construct<flag>;
};
Note
Automatic whitespace skipping is disabled while parsing needle or end.
Caution
This rule requires backtracking, which can slow down parsing.
Tip
Use lexy::dsl::peek if you want to check that needle matches at the current position.

See also