4 #ifndef LEXY_DSL_LIST_HPP_INCLUDED
5 #define LEXY_DSL_LIST_HPP_INCLUDED
14 template <
typename Item,
typename Sep>
17 template <
typename Context,
typename Reader,
typename Sink>
23 [[maybe_unused]]
auto sep_begin = reader.position();
24 if constexpr (!std::is_void_v<Sep>)
27 if (!
sep.try_parse(context.control_block, reader))
34 if (!
sep.template finish<lexy::sink_parser>(context, reader, sink))
37 [[maybe_unused]]
auto sep_end = reader.position();
40 if constexpr (lexy::is_branch_rule<Item>)
44 if (!item.try_parse(context.control_block, reader))
49 if constexpr (!std::is_void_v<Sep>)
50 Sep::report_trailing_error(context, reader, sep_begin, sep_end);
55 if (!item.template finish<lexy::sink_parser>(context, reader, sink))
69 template <
typename NextParser>
72 template <
typename Context,
typename Reader,
typename... Args>
76 auto sink = context.value_callback().sink();
83 if (!
_loop(context, reader, sink))
92 template <
typename Reader>
97 template <
typename ControlBlock>
98 constexpr
bool try_parse(
const ControlBlock* cb,
const Reader& reader)
101 return item.try_parse(cb, reader);
104 template <
typename Context>
107 return item.cancel(context);
110 template <
typename NextParser,
typename Context,
typename... Args>
114 auto sink = context.value_callback().sink();
117 if (!
item.template finish<lexy::sink_parser>(context, reader, sink))
121 if (!
_loop(context, reader, sink))
132 template <
typename Item>
135 static_assert(lexy::is_branch_rule<Item>,
136 "list() without a separator requires a branch condition");
141 template <
typename Item,
typename Sep,
typename Tag>
148 template <
typename Item,
typename Sep>
151 static_assert(lexy::is_branch_rule<Item>,
152 "list() without a trailing separator requires a branch condition");
156 template <
typename Item,
typename Sep>
159 static_assert(lexy::_detail::error<Item, Sep>,
160 "list() does not support `dsl::ignore_trailing_sep()`");
167 template <
typename Term,
typename Item,
typename Sep,
typename Recover>
187 template <
typename TermParser,
typename Context,
typename Reader,
typename Sink>
189 Reader& reader, Sink& sink)
191 auto state = initial_state;
193 [[maybe_unused]]
auto sep_pos = reader.position();
199 if (term.try_parse(context.control_block, reader))
202 term.cancel(context);
209 if constexpr (!std::is_void_v<Sep>)
211 sep_pos = reader.position();
220 else if (sep_pos == reader.position())
225 if constexpr (lexy::is_branch_rule<Item>)
228 if (item.try_parse(context.control_block, reader)
229 && item.template finish<lexy::sink_parser>(context, reader, sink))
238 item.cancel(context);
270 if constexpr (!std::is_void_v<Sep>)
274 if (term.try_parse(context.control_block, reader))
278 Sep::report_trailing_error(context, reader, sep_pos, reader.position());
305 auto recovery_begin = reader.position();
310 if constexpr (!std::is_void_v<Sep>)
312 sep_pos = reader.position();
315 if (
sep.try_parse(context.control_block, reader))
317 auto recovery_end = reader.position();
322 if (
sep.template finish<lexy::sink_parser>(context, reader, sink))
346 else if constexpr (lexy::is_branch_rule<Item>)
349 if (item.try_parse(context.control_block, reader))
351 auto recovery_end = reader.position();
356 if (item.template finish<lexy::sink_parser>(context, reader, sink))
371 item.cancel(context);
377 if (term.try_parse(context.control_block, reader))
380 auto recovery_end = reader.position();
388 term.cancel(context);
393 using limit_rule = decltype(Recover{}.get_limit());
398 auto recovery_end = reader.position();
416 template <
typename NextParser>
419 template <
typename Context,
typename Reader,
typename... Args>
423 auto sink = context.value_callback().sink();
434 if constexpr (std::is_same_v<
typename decltype(sink)::return_type,
void>)
437 return term.template finish<NextParser>(context, reader,
LEXY_FWD(args)...);
441 return term.template finish<NextParser>(context, reader,
LEXY_FWD(args)...,
449 #endif // LEXY_DSL_LIST_HPP_INCLUDED