Header lexy/dsl/list.hpp
Rule lexy::dsl::list
lexy/dsl/list.hpp
namespace 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
separator
sep
islexy::dsl::trailing_sep
,item
is abranch-rule
; i.e. the second overload must not be called.- Parsing
It first parses
item
once. Then there are four cases to consider:First overload, no separator. Then it repeatedly tries to parse
rule
. It finishes whenrule
backtracks.Second overload,
lexy::dsl::sep
. Then it repeatedly tries to parsesep
. If that backtracks, it is finished. Otherwise, it parsesitem
and 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
item
is a branch rule, are also a branch rules. They try to parse the initialitem
and backtrack if that backtracks. Otherwise, they continues with normal parsing.- Errors
All errors raised by (branch) parsing
item
orsep
. 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
item
andsep
are forwarded to it; there are separate calls for every iteration and foritem
andsep
. The value of the finished sink is produced as the only value of thelist
rule.
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> . |