validate.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2024 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_ACTION_VALIDATE_HPP_INCLUDED
5 #define LEXY_ACTION_VALIDATE_HPP_INCLUDED
6 
9 #include <lexy/action/base.hpp>
10 #include <lexy/callback/base.hpp>
12 #include <lexy/callback/noop.hpp>
13 #include <lexy/error.hpp>
14 
15 namespace lexy
16 {
17 // Convert the callback into an appropriate sink.
18 template <typename Callback>
19 constexpr auto _get_error_sink(const Callback& callback)
20 {
21  if constexpr (std::is_same_v<Callback, lexy::_noop>)
22  {
23  // We collect noop instead, which counts the errors.
24  return lexy::collect(callback).sink();
25  }
26  else if constexpr (lexy::is_sink<Callback>)
27  {
28  // It already is a sink.
29  return callback.sink();
30  }
31  else
32  {
33  static_assert(
34  std::is_void_v<typename Callback::return_type>,
35  "need to use `lexy::collect()` to create an error callback that can handle multiple errors");
36 
37  // We need to collect the errors.
38  return lexy::collect(callback).sink();
39  }
40 }
41 template <typename Callback>
42 using _error_sink_t = decltype(_get_error_sink(LEXY_DECLVAL(Callback)));
43 
44 template <typename ErrorCallback>
46 {
48 
49 public:
50  using error_callback = ErrorCallback;
51  using error_type = typename _sink_t::return_type;
52  static_assert(!std::is_void_v<error_type>, "ErrorCallback must not be a void returning sink");
53 
54  constexpr explicit operator bool() const noexcept
55  {
56  return is_success();
57  }
58 
59  constexpr bool is_success() const noexcept
60  {
61  return _status == _status_success;
62  }
63  constexpr bool is_error() const noexcept
64  {
65  return !is_success();
66  }
67  constexpr bool is_recovered_error() const noexcept
68  {
69  return _status == _status_recovered;
70  }
71  constexpr bool is_fatal_error() const noexcept
72  {
73  return _status == _status_fatal;
74  }
75 
76  constexpr std::size_t error_count() const noexcept
77  {
78  if constexpr (std::is_same_v<error_type, std::size_t>)
79  // void-returning callback yields the count only.
80  return _error;
81  else
82  // We assume it's some sort of container otherwise.
83  return _error.size();
84  }
85 
86  constexpr const auto& errors() const& noexcept
87  {
88  return _error;
89  }
90  constexpr auto&& errors() && noexcept
91  {
92  return LEXY_MOV(_error);
93  }
94 
95 private:
96  constexpr explicit validate_result(bool did_recover, error_type&& error)
98  {
99  if (error_count() == 0u)
101  else if (did_recover)
103  else
105  }
106 
108  enum
109  {
113  } _status;
114 
115  template <typename Reader>
116  friend class _vh;
117 };
118 } // namespace lexy
119 
120 namespace lexy
121 {
122 template <typename Reader>
124 {
127 
129  typename Reader::iterator begin, const error<Reader, void>& error);
131  typename Reader::iterator begin, const error<Reader, expected_literal>& error);
133  typename Reader::iterator begin, const error<Reader, expected_keyword>& error);
135  typename Reader::iterator begin,
137 
138  template <typename Input, typename Sink>
141  : sink(&sink), input(&input),
142  generic([](_detail::any_ref sink, production_info info, _detail::any_cref input,
143  typename Reader::iterator begin, const error<Reader, void>& error) {
144  lexy::error_context err_ctx(info, *input->template get<const Input*>(), begin);
145  sink->template get<Sink>()(err_ctx, LEXY_FWD(error));
146  }),
148  typename Reader::iterator begin, const error<Reader, expected_literal>& error) {
149  lexy::error_context err_ctx(info, *input->template get<const Input*>(), begin);
150  sink->template get<Sink>()(err_ctx, LEXY_FWD(error));
151  }),
152  keyword([](_detail::any_ref sink, production_info info, _detail::any_cref input,
153  typename Reader::iterator begin, const error<Reader, expected_keyword>& error) {
154  lexy::error_context err_ctx(info, *input->template get<const Input*>(), begin);
155  sink->template get<Sink>()(err_ctx, LEXY_FWD(error));
156  }),
157  char_class([](_detail::any_ref sink, production_info info, _detail::any_cref input,
158  typename Reader::iterator begin,
159  const error<Reader, expected_char_class>& error) {
160  lexy::error_context err_ctx(info, *input->template get<const Input*>(), begin);
161  sink->template get<Sink>()(err_ctx, LEXY_FWD(error));
162  })
163  {}
164 };
165 
166 template <typename Reader>
167 class _vh
168 {
169 public:
170  template <typename Input, typename Sink>
171  constexpr explicit _vh(const _detail::any_holder<const Input*>& input,
173  : _cb(input, sink)
174  {}
175 
177  {
178  using iterator = typename Reader::iterator;
179 
180  public:
181  constexpr event_handler(production_info info) : _begin(), _info(info) {}
182 
183  constexpr void on(_vh& handler, parse_events::production_start, iterator pos)
184  {
185  _begin = pos;
186 
187  _prev = handler._top;
188  handler._top = this;
189  }
190  constexpr void on(_vh& handler, parse_events::production_finish, iterator)
191  {
192  handler._top = _prev;
193  }
194  constexpr void on(_vh& handler, parse_events::production_cancel, iterator)
195  {
196  handler._top = _prev;
197  }
198 
199  template <typename R, typename Tag>
200  constexpr void on(_vh& handler, parse_events::error, const error<R, Tag>& error)
201  {
202  handler._cb.generic(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
203  }
204  template <typename R>
205  constexpr void on(_vh& handler, parse_events::error, const error<R, void>& error)
206  {
207  handler._cb.generic(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
208  }
209  template <typename R>
210  constexpr void on(_vh& handler, parse_events::error,
212  {
213  handler._cb.literal(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
214  }
215  template <typename R>
216  constexpr void on(_vh& handler, parse_events::error,
218  {
219  handler._cb.keyword(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
220  }
221  template <typename R>
222  constexpr void on(_vh& handler, parse_events::error,
224  {
225  handler._cb.char_class(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
226  }
227 
228  template <typename Event, typename... Args>
229  constexpr auto on(_vh&, Event, const Args&...)
230  {
231  return 0; // operation_chain_start must return something
232  }
233 
234  constexpr iterator production_begin() const
235  {
236  return _begin;
237  }
238 
239  constexpr production_info get_info() const
240  {
241  auto cur = this;
242  while (cur->_info.is_transparent && cur->_prev != nullptr)
243  cur = cur->_prev;
244  return cur->_info;
245  }
246 
247  private:
250  event_handler* _prev = nullptr;
251  };
252 
253  template <typename Production, typename State>
255 
256  template <typename Result>
257  constexpr auto get_result(bool rule_parse_result) &&
258  {
260  return Result(rule_parse_result, LEXY_MOV(_cb.sink->template get<sink_t>()).finish());
261  }
262 
263 private:
265  event_handler* _top = nullptr;
266 };
267 
268 template <typename State, typename Input, typename ErrorCallback>
270 {
271  const ErrorCallback* _callback;
272  State* _state = nullptr;
273 
275  using state = State;
276  using input = Input;
277 
278  template <typename>
280 
281  constexpr explicit validate_action(const ErrorCallback& callback) : _callback(&callback) {}
282  template <typename U = State>
283  constexpr explicit validate_action(U& state, const ErrorCallback& callback)
285  {}
286 
287  template <typename Production>
288  constexpr auto operator()(Production, const Input& input) const
289  {
290  _detail::any_holder input_holder(&input);
292  auto reader = input.reader();
293  return lexy::do_action<Production, result_type>(handler(input_holder, sink), _state,
294  reader);
295  }
296 };
297 
298 template <typename Production, typename Input, typename ErrorCallback>
299 constexpr auto validate(const Input& input, const ErrorCallback& callback)
301 {
302  return validate_action<void, Input, ErrorCallback>(callback)(Production{}, input);
303 }
304 
305 template <typename Production, typename Input, typename State, typename ErrorCallback>
306 constexpr auto validate(const Input& input, State& state, const ErrorCallback& callback)
308 {
309  return validate_action<State, Input, ErrorCallback>(state, callback)(Production{}, input);
310 }
311 template <typename Production, typename Input, typename State, typename ErrorCallback>
312 constexpr auto validate(const Input& input, const State& state, const ErrorCallback& callback)
314 {
315  return validate_action<const State, Input, ErrorCallback>(state, callback)(Production{}, input);
316 }
317 } // namespace lexy
318 
319 #endif // LEXY_ACTION_VALIDATE_HPP_INCLUDED
320 
lexy::validate_result::error_callback
ErrorCallback error_callback
Definition: validate.hpp:50
lexy::validate_action::state
State state
Definition: validate.hpp:275
LEXY_MOV
#define LEXY_MOV(...)
Definition: config.hpp:29
lexy::validate_result::_status
enum lexy::validate_result::@4 _status
lexy::_validate_callbacks::_validate_callbacks
constexpr _validate_callbacks(const _detail::any_holder< const Input * > &input, _detail::any_holder< Sink > &sink)
Definition: validate.hpp:139
lexy::parse_events::production_finish
Definition: dsl/base.hpp:34
lexy::validate_result::_sink_t
_error_sink_t< ErrorCallback > _sink_t
Definition: validate.hpp:47
base.hpp
lexy::collect
constexpr auto collect(Callback &&callback)
Definition: container.hpp:491
lexy::_validate_callbacks::input
_detail::any_cref input
Definition: validate.hpp:126
lexy::error< Reader, expected_literal >
Definition: error.hpp:91
noop.hpp
lexy::_validate_callbacks
Definition: validate.hpp:123
lexy::_validate_callbacks::keyword
void(* keyword)(_detail::any_ref sink, production_info info, _detail::any_cref input, typename Reader::iterator begin, const error< Reader, expected_keyword > &error)
Definition: validate.hpp:132
lexy::validate_action::_state
State * _state
Definition: validate.hpp:272
lexy::_vh
Definition: validate.hpp:167
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexy::_vh::event_handler::on
constexpr auto on(_vh &, Event, const Args &...)
Definition: validate.hpp:229
any_ref.hpp
lexy::_vh::event_handler::event_handler
constexpr event_handler(production_info info)
Definition: validate.hpp:181
lexy::validate_result
Definition: validate.hpp:45
lexy::_detail::any_ref
any_base * any_ref
Definition: any_ref.hpp:43
lexy::_vh::event_handler::_begin
iterator _begin
Definition: validate.hpp:248
lexy::error_context
Contains information about the context of an error, production is type-erased.
Definition: error.hpp:233
lexy
Definition: any_ref.hpp:12
lexy::_vh::event_handler::get_info
constexpr production_info get_info() const
Definition: validate.hpp:239
lexy::_error_sink_t
decltype(_get_error_sink(LEXY_DECLVAL(Callback))) _error_sink_t
Definition: validate.hpp:42
detail::void
j template void())
Definition: json.hpp:4893
lexy::validate_result::is_fatal_error
constexpr bool is_fatal_error() const noexcept
Definition: validate.hpp:71
lexy::_callback
Definition: adapter.hpp:12
lexy::validate_action::handler
_vh< lexy::input_reader< Input > > handler
Definition: validate.hpp:274
lexy::_detail::any_cref
const any_base * any_cref
Definition: any_ref.hpp:44
lexy::callback
constexpr auto callback(Fns &&... fns)
Creates a callback.
Definition: adapter.hpp:48
lexy::error
Generic failure.
Definition: error.hpp:14
lexy::validate_result::error_count
constexpr std::size_t error_count() const noexcept
Definition: validate.hpp:76
lexy::_vh::event_handler::production_begin
constexpr iterator production_begin() const
Definition: validate.hpp:234
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< R, expected_keyword > &error)
Definition: validate.hpp:216
lexy::_get_error_sink
constexpr auto _get_error_sink(const Callback &callback)
Definition: validate.hpp:19
lexy::error< Reader, void >
Type erased generic failure.
Definition: error.hpp:18
lexy::_vh::get_result
constexpr auto get_result(bool rule_parse_result) &&
Definition: validate.hpp:257
lexy::error< Reader, expected_keyword >
Definition: error.hpp:143
lexy::_vh::_vh
constexpr _vh(const _detail::any_holder< const Input * > &input, _detail::any_holder< Sink > &sink)
Definition: validate.hpp:171
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexy::validate_action::validate_action
constexpr validate_action(U &state, const ErrorCallback &callback)
Definition: validate.hpp:283
lexy::validate_result::is_success
constexpr bool is_success() const noexcept
Definition: validate.hpp:59
lexy::_detail::any_base
Definition: any_ref.hpp:18
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< R, expected_literal > &error)
Definition: validate.hpp:210
lexy::error< Reader, expected_char_class >
Definition: error.hpp:193
lexy::validate_result::errors
constexpr const auto & errors() const &noexcept
Definition: validate.hpp:86
lexy::validate_action::validate_action
constexpr validate_action(const ErrorCallback &callback)
Definition: validate.hpp:281
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< R, Tag > &error)
Definition: validate.hpp:200
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::production_finish, iterator)
Definition: validate.hpp:190
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< R, void > &error)
Definition: validate.hpp:205
lexy::validate
constexpr auto validate(const Input &input, const ErrorCallback &callback) -> validate_result< ErrorCallback >
Definition: validate.hpp:299
lexy::parse_events::production_start
Definition: dsl/base.hpp:30
lexy::validate_action::input
Input input
Definition: validate.hpp:276
lexy::validate_action
Definition: validate.hpp:269
lexy::validate_result::_status_success
@ _status_success
Definition: validate.hpp:110
lexy::_vh::_top
event_handler * _top
Definition: validate.hpp:265
lexy::validate_result::_status_recovered
@ _status_recovered
Definition: validate.hpp:111
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::validate_result::is_error
constexpr bool is_error() const noexcept
Definition: validate.hpp:63
lexy::validate_result::validate_result
constexpr validate_result(bool did_recover, error_type &&error)
Definition: validate.hpp:96
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::production_cancel, iterator)
Definition: validate.hpp:194
lexy::validate_action::_callback
const ErrorCallback * _callback
Definition: validate.hpp:271
lexy::_validate_callbacks::sink
_detail::any_ref sink
Definition: validate.hpp:125
lexy::_detail::void_value_callback
Definition: action/base.hpp:253
lexy::parse_events::production_cancel
Definition: dsl/base.hpp:38
lexy::_vh::event_handler::_prev
event_handler * _prev
Definition: validate.hpp:250
lexy::_validate_callbacks::literal
void(* literal)(_detail::any_ref sink, production_info info, _detail::any_cref input, typename Reader::iterator begin, const error< Reader, expected_literal > &error)
Definition: validate.hpp:130
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< R, expected_char_class > &error)
Definition: validate.hpp:222
lexy::validate_result::is_recovered_error
constexpr bool is_recovered_error() const noexcept
Definition: validate.hpp:67
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::production_start, iterator pos)
Definition: validate.hpp:183
lexy::_vh::event_handler::_info
production_info _info
Definition: validate.hpp:249
container.hpp
lexy::production_info
Definition: grammar.hpp:192
BT::Result
Expected< std::monostate > Result
Definition: basic_types.h:333
lexy::_vh::event_handler::iterator
typename Reader::iterator iterator
Definition: validate.hpp:178
base.hpp
lexy::_validate_callbacks::generic
void(* generic)(_detail::any_ref sink, production_info info, _detail::any_cref input, typename Reader::iterator begin, const error< Reader, void > &error)
Definition: validate.hpp:128
lexy::_validate_callbacks::char_class
void(* char_class)(_detail::any_ref sink, production_info info, _detail::any_cref input, typename Reader::iterator begin, const error< Reader, expected_char_class > &error)
Definition: validate.hpp:134
LEXY_DECLVAL
#define LEXY_DECLVAL(...)
Definition: config.hpp:32
lexy::validate_result::error_type
typename _sink_t::return_type error_type
Definition: validate.hpp:51
lexy::_vh::event_handler
Definition: validate.hpp:176
lexy::validate_action::operator()
constexpr auto operator()(Production, const Input &input) const
Definition: validate.hpp:288
lexy::_detail::any_holder< const Input * >
lexy::validate_result::errors
constexpr auto && errors() &&noexcept
Definition: validate.hpp:90
lazy_init.hpp
lexy::validate_result::_error
error_type _error
Definition: validate.hpp:107
lexy::validate_result::_status_fatal
@ _status_fatal
Definition: validate.hpp:112
error.hpp
lexy::_vh::_cb
_validate_callbacks< Reader > _cb
Definition: validate.hpp:264


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Dec 13 2024 03:19:17