validate.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_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 Tag>
200  constexpr void on(_vh& handler, parse_events::error, const error<Reader, Tag>& error)
201  {
202  handler._cb.generic(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
203  }
204  constexpr void on(_vh& handler, parse_events::error, const error<Reader, void>& error)
205  {
206  handler._cb.generic(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
207  }
208  constexpr void on(_vh& handler, parse_events::error,
210  {
211  handler._cb.literal(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
212  }
213  constexpr void on(_vh& handler, parse_events::error,
215  {
216  handler._cb.keyword(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
217  }
218  constexpr void on(_vh& handler, parse_events::error,
220  {
221  handler._cb.char_class(handler._cb.sink, get_info(), handler._cb.input, _begin, error);
222  }
223 
224  template <typename Event, typename... Args>
225  constexpr auto on(_vh&, Event, const Args&...)
226  {
227  return 0; // operation_chain_start must return something
228  }
229 
230  constexpr iterator production_begin() const
231  {
232  return _begin;
233  }
234 
235  constexpr production_info get_info() const
236  {
237  auto cur = this;
238  while (cur->_info.is_transparent && cur->_prev != nullptr)
239  cur = cur->_prev;
240  return cur->_info;
241  }
242 
243  private:
246  event_handler* _prev = nullptr;
247  };
248 
249  template <typename Production, typename State>
251 
252  template <typename Result>
253  constexpr auto get_result(bool rule_parse_result) &&
254  {
256  return Result(rule_parse_result, LEXY_MOV(_cb.sink->template get<sink_t>()).finish());
257  }
258 
259 private:
261  event_handler* _top = nullptr;
262 };
263 
264 template <typename State, typename Input, typename ErrorCallback>
266 {
267  const ErrorCallback* _callback;
268  State* _state = nullptr;
269 
271  using state = State;
272  using input = Input;
273 
274  template <typename>
276 
277  constexpr explicit validate_action(const ErrorCallback& callback) : _callback(&callback) {}
278  template <typename U = State>
279  constexpr explicit validate_action(U& state, const ErrorCallback& callback)
281  {}
282 
283  template <typename Production>
284  constexpr auto operator()(Production, const Input& input) const
285  {
286  _detail::any_holder input_holder(&input);
288  auto reader = input.reader();
289  return lexy::do_action<Production, result_type>(handler(input_holder, sink), _state,
290  reader);
291  }
292 };
293 
294 template <typename Production, typename Input, typename ErrorCallback>
295 constexpr auto validate(const Input& input, const ErrorCallback& callback)
297 {
298  return validate_action<void, Input, ErrorCallback>(callback)(Production{}, input);
299 }
300 
301 template <typename Production, typename Input, typename State, typename ErrorCallback>
302 constexpr auto validate(const Input& input, State& state, const ErrorCallback& callback)
304 {
305  return validate_action<State, Input, ErrorCallback>(state, callback)(Production{}, input);
306 }
307 template <typename Production, typename Input, typename State, typename ErrorCallback>
308 constexpr auto validate(const Input& input, const State& state, const ErrorCallback& callback)
310 {
311  return validate_action<const State, Input, ErrorCallback>(state, callback)(Production{}, input);
312 }
313 } // namespace lexy
314 
315 #endif // LEXY_ACTION_VALIDATE_HPP_INCLUDED
316 
lexy::validate_result::error_callback
ErrorCallback error_callback
Definition: validate.hpp:50
lexy::validate_action::state
State state
Definition: validate.hpp:271
LEXY_MOV
#define LEXY_MOV(...)
Definition: config.hpp:21
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:21
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:489
lexy::_validate_callbacks::input
_detail::any_cref input
Definition: validate.hpp:126
lexy::error< Reader, expected_literal >
Definition: error.hpp:77
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::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< Reader, Tag > &error)
Definition: validate.hpp:200
lexy::validate_action::_state
State * _state
Definition: validate.hpp:268
lexy::_vh
Definition: validate.hpp:167
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:22
lexy::_vh::event_handler::on
constexpr auto on(_vh &, Event, const Args &...)
Definition: validate.hpp:225
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:244
lexy::error_context
Contains information about the context of an error, production is type-erased.
Definition: error.hpp:198
lexy
Definition: any_ref.hpp:12
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< Reader, void > &error)
Definition: validate.hpp:204
lexy::_vh::event_handler::get_info
constexpr production_info get_info() const
Definition: validate.hpp:235
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:270
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:21
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:230
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< Reader, expected_literal > &error)
Definition: validate.hpp:208
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:253
lexy::error< Reader, expected_keyword >
Definition: error.hpp:122
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:55
lexy::validate_action::validate_action
constexpr validate_action(U &state, const ErrorCallback &callback)
Definition: validate.hpp:279
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::error< Reader, expected_char_class >
Definition: error.hpp:165
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:277
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::production_finish, iterator)
Definition: validate.hpp:190
lexy::validate
constexpr auto validate(const Input &input, const ErrorCallback &callback) -> validate_result< ErrorCallback >
Definition: validate.hpp:295
lexy::parse_events::production_start
Definition: dsl/base.hpp:17
lexy::validate_action::input
Input input
Definition: validate.hpp:272
lexy::validate_action
Definition: validate.hpp:265
lexy::validate_result::_status_success
@ _status_success
Definition: validate.hpp:110
lexy::_vh::_top
event_handler * _top
Definition: validate.hpp:261
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::error, const error< Reader, expected_char_class > &error)
Definition: validate.hpp:218
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:267
lexy::_validate_callbacks::sink
_detail::any_ref sink
Definition: validate.hpp:125
lexy::_detail::void_value_callback
Definition: action/base.hpp:246
lexy::parse_events::production_cancel
Definition: dsl/base.hpp:25
lexy::_vh::event_handler::_prev
event_handler * _prev
Definition: validate.hpp:246
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::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:245
container.hpp
lexy::_vh::event_handler::on
constexpr void on(_vh &handler, parse_events::error, const error< Reader, expected_keyword > &error)
Definition: validate.hpp:213
lexy::production_info
Definition: grammar.hpp:178
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:24
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:284
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:260


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