Header lexy/dsl/list.hpp
Rule lexy::dsl::list
lexy/dsl/list.hppnamespace lexy::dsl
{
constexpr branch-rule auto list(branch-rule auto item);
constexpr rule auto list(rule auto item,
separator auto sep);
constexpr branch-rule auto list(rule auto item,
separator auto sep);
}list is a rule that parses a non-empty list of item, optionally separated by sep.
- Requires
If the
separatorsepislexy::dsl::trailing_sep,itemis abranch-rule; i.e. the second overload must not be called.- Parsing
It first parses
itemonce. Then there are four cases to consider:First overload, no separator. Then it repeatedly tries to parse
rule. It finishes whenrulebacktracks.Second overload,
lexy::dsl::sep. Then it repeatedly tries to parsesep. If that backtracks, it is finished. Otherwise, it parsesitemand repeats.Third overload,
lexy::dsl::sep. Then it repeatedly tries to parsesep. If that backtracks, it is finished. Otherwise, it tries to parseitem. If that backtracks, it has an unexpected trailing separator. Otherwise, it repeats.Third overload,
lexy::dsl::trailing_sep. Then it repeatedly tries to parsesep. If that backtracks, it is finished. Otherwise, it tries to parseitem. If that backtracks, it has an allowed trailing separator and finishes. Otherwise, it repeats.
- Branch parsing
The first and third overloads where
itemis a branch rule, are also a branch rules. They try to parse the initialitemand backtrack if that backtracks. Otherwise, they continues with normal parsing.- Errors
All errors raised by (branch) parsing
itemorsep. It then fails if they failed.lexy::unexpected_trailing_separator: in case 2, at the position of the trailing separator. It then recovers by simply consuming the separator and continues.
- Values
It creates a sink of the current context. All values produced by
itemandsepare forwarded to it; there are separate calls for every iteration and foritemandsep. The value of the finished sink is produced as the only value of thelistrule.
struct production
{
static constexpr auto rule = [] {
auto item = dsl::capture(dsl::ascii::alpha);
return dsl::list(item);
}();
// Same as `lexy::as_string`.
static constexpr auto value
= lexy::fold_inplace<std::string>("", [](std::string& result, auto lexeme) {
result.append(lexeme.begin(), lexeme.end());
});
};Note | lexy::dsl::list(item) matches the same input as lexy::dsl::while_one(item);
lexy::dsl::list(item, sep) (case 2) matches the same input as lexy::dsl::do_while(item, sep). |
Tip | If your list is always followed by a certain token or surrounded in parenthesis,
you can use lexy::dsl::terminator and lexy::dsl::brackets,
which do not require a branch rule as arguments. |
Tip | Use lexy::dsl::opt(lexy::dsl::list(…)) to parse a list that might be empty;
this requires a branch condition. |
Tip | Use lexy::as_list for the callback to create e.g. a std::vector<T>. |