Header lexy/dsl/loop.hpp
Rules that loop.
Rule lexy::dsl::loop
lexy/dsl/loop.hppnamespace lexy::dsl
{
constexpr rule auto loop(rule auto rule);
}loop is a rule that matches rule repeatedly.
- Requires
ruledoes not produce any values.- Parsing
Parses
rulerepeatedly until it either fails orbreak_is parsed.- Errors
All errors raised by
rule. It then fails ifrulehas failed.- Values
None.
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
// Note: a real implementation couldn't use loop().
// If the decls produce values, list() has to be used instead.
= dsl::loop(dsl::p<function_decl> | dsl::p<type_decl> | dsl::break_);
};Tip | Use lexy::dsl::while_ if there is a simple exit condition,
lexy::dsl::list if the rule should produce values. |
Warning | You must not use lexy::dsl::return_ to exit from a loop. |
Branch rule lexy::dsl::break_
lexy/dsl/loop.hppnamespace lexy::dsl
{
constexpr branch-rule auto break_;
}break_ is a rule that exits from a loop.
- Requires
It is used inside a
looprule.- (Branch) Parsing
Matches everything without consuming anything. Exits the loop.
- Errors
None.
- Values
None.
Rule lexy::dsl::while_
lexy/dsl/loop.hppnamespace lexy::dsl
{
constexpr rule auto while_(branch-rule auto rule)
{
return loop(rule | break_);
}
}while_ is a rule that parses the branch rule rule as often as possible.
It is entirely equivalent to loop(rule | break_).
It can only fail, if rule can fail after it decided to select the branch.
It can accept the empty string if rule backtracks on the first iteration.
Tip | Use lexy::dsl::opt and lexy::dsl::list if rule produces values. |
Warning | If rule does not consume any characters, while_ will loop forever. |
Caution | If whitespace skipping is enabled, while_ will skip whitespace after every token of rule. |
Rule lexy::dsl::while_one
lexy/dsl/loop.hppnamespace lexy::dsl
{
constexpr branch-rule auto while_one(branch-rule auto rule)
{
return rule >> while_(rule);
}
}while_one is a rule that parses rule repeatedly, but at least once.
It is entirely equivalent to rule >> while_(rule).
Tip | Use lexy::dsl::list if rule produces values. |
Caution | If whitespace skipping is enabled, while_one will skip whitespace after every token of rule.
Consider lexy::dsl::identifier, which does not do that. |
Rule lexy::dsl::do_while
lexy/dsl/loop.hppnamespace lexy::dsl
{
constexpr rule auto do_while(rule auto then, branch-rule auto condition)
{
return then + while_(condition >> then);
}
constexpr branch-rule auto do_while(branch-rule auto then,
branch-rule auto condition)
{
return then >> while_(condition >> then);
}
}do_while is a rule that parses then while condition matches, but checks condition after then.
It is entirely equivalent to then + while_(condition >> then) if then is not a branch,
and then >> while_(condition >> then) otherwise.
Tip | Use lexy::dsl::list if then produces values with condition as separator. |