Header lexy/dsl/loop.hpp
Rules that loop.
Rule lexy::dsl::loop
lexy/dsl/loop.hpp
namespace lexy::dsl
{
constexpr rule auto loop(rule auto rule);
}
loop
is a rule that matches rule
repeatedly.
- Requires
rule
does not produce any values.- Parsing
Parses
rule
repeatedly until it either fails orbreak_
is parsed.- Errors
All errors raised by
rule
. It then fails ifrule
has 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.hpp
namespace lexy::dsl
{
constexpr branch-rule auto break_;
}
break_
is a rule that exits from a loop
.
- Requires
It is used inside a
loop
rule.- (Branch) Parsing
Matches everything without consuming anything. Exits the loop.
- Errors
None.
- Values
None.
Rule lexy::dsl::while_
lexy/dsl/loop.hpp
namespace 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.hpp
namespace 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.hpp
namespace 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. |