repeat.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DSL_REPEAT_HPP_INCLUDED
5 #define LEXY_DSL_REPEAT_HPP_INCLUDED
6 
7 #include <lexy/dsl/base.hpp>
8 #include <lexy/dsl/branch.hpp>
9 #include <lexy/dsl/parse_as.hpp>
10 #include <lexy/lexeme.hpp>
11 
12 namespace lexyd
13 {
14 template <typename Item, typename Sep>
15 struct _rep_impl
16 {
17  // Sink can either be present or not;
18  // we only use variadic arguments to get rid of code duplication.
19  template <typename Context, typename Reader, typename... Sink>
20  static constexpr bool loop(Context& context, Reader& reader, std::size_t count, Sink&... sink)
21  {
22  using sink_parser
23  = std::conditional_t<sizeof...(Sink) == 0, lexy::pattern_parser<>, lexy::sink_parser>;
24 
25  if (count == 0)
26  return true;
27 
28  using item_parser = lexy::parser_for<Item, sink_parser>;
29  if (!item_parser::parse(context, reader, sink...))
30  return false;
31 
32  for (std::size_t i = 1; i != count; ++i)
33  {
35  if (!sep_parser::parse(context, reader, sink...))
36  return false;
37 
38  if (!item_parser::parse(context, reader, sink...))
39  return false;
40  }
41 
43  return trailing_parser::parse(context, reader, sink...);
44  }
45 };
46 template <typename Item>
47 struct _rep_impl<Item, void>
48 {
49  // Sink can either be present or not;
50  // we only use variadic arguments to get rid of code duplication.
51  template <typename Context, typename Reader, typename... Sink>
52  static constexpr bool loop(Context& context, Reader& reader, std::size_t count, Sink&... sink)
53  {
54  using sink_parser
55  = std::conditional_t<sizeof...(Sink) == 0, lexy::pattern_parser<>, lexy::sink_parser>;
56 
57  if (count == 0)
58  return true;
59 
60  using item_parser = lexy::parser_for<Item, sink_parser>;
61  if (!item_parser::parse(context, reader, sink...))
62  return false;
63 
64  for (std::size_t i = 1; i != count; ++i)
65  {
66  if (!item_parser::parse(context, reader, sink...))
67  return false;
68  }
69 
70  return true;
71  }
72 };
73 
74 template <typename Item, typename Sep>
75 struct _repd : rule_base // repeat, discard
76 {
77  template <typename NextParser>
78  struct p
79  {
80  template <typename Context, typename Reader, typename... Args>
81  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, std::size_t count,
82  Args&&... args)
83  {
84  if (!_rep_impl<Item, Sep>::loop(context, reader, count))
85  return false;
86 
87  return NextParser::parse(context, reader, LEXY_FWD(args)...);
88  }
89  };
90 };
91 template <typename Item, typename Sep>
92 struct _repl : rule_base // repeat, list
93 {
94  template <typename NextParser>
95  struct p
96  {
97  template <typename Context, typename Reader, typename... Args>
98  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, std::size_t count,
99  Args&&... args)
100  {
101  auto sink = context.value_callback().sink();
102  if (!_rep_impl<Item, Sep>::loop(context, reader, count, sink))
103  return false;
104 
105  return lexy::sink_finish_parser<NextParser>::parse(context, reader, sink,
106  LEXY_FWD(args)...);
107  }
108  };
109 };
110 template <typename Item, typename Sep>
111 struct _repc : rule_base // repeat, capture
112 {
113  template <typename NextParser>
114  struct p
115  {
116  template <typename Context, typename Reader, typename... Args>
117  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, std::size_t count,
118  Args&&... args)
119  {
120  auto begin = reader.position();
121  if (!_rep_impl<Item, Sep>::loop(context, reader, count))
122  return false;
123 
124  return NextParser::parse(context, reader, LEXY_FWD(args)...,
125  lexy::lexeme(reader, begin));
126  }
127  };
128 };
129 
130 template <typename Count, typename Loop>
131 struct _rep : decltype(_maybe_branch(_pas<std::size_t, Count, true>{}, Loop{}))
132 {};
133 
134 template <typename Count>
135 struct _rep_dsl
136 {
137  template <typename Item>
138  constexpr auto operator()(Item) const
139  {
141  }
142  template <typename Item, typename Sep>
143  constexpr auto operator()(Item, Sep) const
144  {
145  static_assert(lexy::is_separator<Sep>);
147  }
148 
149  template <typename Item>
150  constexpr auto list(Item) const
151  {
153  }
154  template <typename Item, typename Sep>
155  constexpr auto list(Item, Sep) const
156  {
157  static_assert(lexy::is_separator<Sep>);
159  }
160 
161  template <typename Item>
162  constexpr auto capture(Item) const
163  {
165  }
166  template <typename Item, typename Sep>
167  constexpr auto capture(Item, Sep) const
168  {
169  static_assert(lexy::is_separator<Sep>);
171  }
172 };
173 
175 template <typename Count>
176 constexpr auto repeat(Count)
177 {
178  return _rep_dsl<Count>{};
179 }
180 } // namespace lexyd
181 
182 #endif // LEXY_DSL_REPEAT_HPP_INCLUDED
183 
lexyd::_repc::p
Definition: repeat.hpp:114
lexyd::_repd::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, std::size_t count, Args &&... args)
Definition: repeat.hpp:81
lexyd::_rep_dsl::operator()
constexpr auto operator()(Item) const
Definition: repeat.hpp:138
lexyd::_repl::p
Definition: repeat.hpp:95
lexyd::_rep_dsl::list
constexpr auto list(Item, Sep) const
Definition: repeat.hpp:155
lexyd::_rep_impl
Definition: repeat.hpp:15
lexyd::_repc::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, std::size_t count, Args &&... args)
Definition: repeat.hpp:117
lexyd::_repd
Definition: repeat.hpp:75
lexyd::_rep_dsl::capture
constexpr auto capture(Item) const
Definition: repeat.hpp:162
lexyd::_rep_dsl
Definition: repeat.hpp:135
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:22
lexyd::_rep_dsl::capture
constexpr auto capture(Item, Sep) const
Definition: repeat.hpp:167
detail::void
j template void())
Definition: json.hpp:4893
lexyd::_repl::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, std::size_t count, Args &&... args)
Definition: repeat.hpp:98
lexyd::_repd::p
Definition: repeat.hpp:78
lexyd::_rep_impl< Item, void >::loop
static constexpr bool loop(Context &context, Reader &reader, std::size_t count, Sink &... sink)
Definition: repeat.hpp:52
lexy::count
constexpr auto count
Sink that counts all arguments.
Definition: fold.hpp:88
lexyd::_repl
Definition: repeat.hpp:92
lexy::parse
constexpr auto parse(const Input &input, const ErrorCallback &callback)
Parses the production into a value, invoking the callback on error.
Definition: parse.hpp:171
lexeme.hpp
lexyd::_rep_dsl::operator()
constexpr auto operator()(Item, Sep) const
Definition: repeat.hpp:143
lexy::sink_parser
A parser that forwards all arguments to a sink, which is the first argument.
Definition: dsl/base.hpp:172
lexyd::rule_base
Definition: grammar.hpp:17
lexyd::_rep_impl::loop
static constexpr bool loop(Context &context, Reader &reader, std::size_t count, Sink &... sink)
Definition: repeat.hpp:20
parse_as.hpp
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:95
lexyd::_rep
Definition: repeat.hpp:131
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexyd::_rep_dsl::list
constexpr auto list(Item) const
Definition: repeat.hpp:150
base.hpp
lexyd::repeat
constexpr auto repeat(Count)
Parses a rule n times, where n is the value produced by Count.
Definition: repeat.hpp:176
lexy::pattern_parser
A parser that does not support any arguments.
Definition: dsl/base.hpp:159
lexy::lexeme
Definition: lexeme.hpp:16
lexy::sink_finish_parser::parse
static LEXY_PARSER_FUNC auto parse(Context &context, Reader &reader, Sink &sink, Args &&... args)
Definition: dsl/base.hpp:189
lexy::parser_for
typename Rule::template p< NextParser > parser_for
Definition: dsl/base.hpp:100
lexyd
Definition: trace.hpp:22
lexyd::_repc
Definition: repeat.hpp:111
branch.hpp


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08