byte.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_DSL_BYTE_HPP_INCLUDED
5 #define LEXY_DSL_BYTE_HPP_INCLUDED
6 
7 #include <cstdint>
9 #include <lexy/dsl/base.hpp>
10 #include <lexy/dsl/char_class.hpp>
11 #include <lexy/dsl/token.hpp>
12 
13 //=== byte ===//
14 namespace lexyd
15 {
16 template <std::size_t N, typename Predicate>
17 struct _b : token_base<_b<N, Predicate>>
18 {
19  static_assert(N > 0);
20 
21  static constexpr bool _match(lexy::byte_encoding::int_type cur)
22  {
23  if (cur == lexy::byte_encoding::eof())
24  return false;
25 
26  if constexpr (!std::is_void_v<Predicate>)
27  {
28  constexpr auto predicate = Predicate{};
29  return predicate(static_cast<lexy::byte_encoding::char_type>(cur));
30  }
31  else
32  {
33  return true;
34  }
35  }
36 
37  template <typename Reader, typename Indices = lexy::_detail::make_index_sequence<N>>
38  struct tp;
39 
40  template <typename Reader, std::size_t... Idx>
41  struct tp<Reader, lexy::_detail::index_sequence<Idx...>>
42  {
43  static_assert(lexy::is_byte_encoding<typename Reader::encoding>);
44  typename Reader::marker end;
45 
46  constexpr explicit tp(const Reader& reader) : end(reader.current()) {}
47 
48  constexpr bool try_parse(Reader reader)
49  {
50  // Bump N times.
51  auto result
52  = ((_match(reader.peek()) ? (reader.bump(), true) : ((void)Idx, false)) && ...);
53  end = reader.current();
54  return result;
55  }
56 
57  template <typename Context>
58  constexpr void report_error(Context& context, const Reader&)
59  {
60  constexpr auto name
61  = std::is_void_v<Predicate> ? "byte" : lexy::_detail::type_name<Predicate>();
62  auto err = lexy::error<Reader, lexy::expected_char_class>(end.position(), name);
63  context.on(_ev::error{}, err);
64  }
65  };
66 
67  //=== dsl ===//
68  template <typename P>
69  constexpr auto if_() const
70  {
71  static_assert(std::is_void_v<Predicate>);
72  return _b<N, P>{};
73  }
74 
75  template <unsigned char Low, unsigned char High>
76  constexpr auto range() const
77  {
78  struct predicate
79  {
80  static LEXY_CONSTEVAL auto name()
81  {
82  return "byte.range";
83  }
84 
85  constexpr bool operator()(unsigned char byte) const
86  {
87  return Low <= byte && byte <= High;
88  }
89  };
90 
91  return if_<predicate>();
92  }
93 
94  template <unsigned char... Bytes>
95  constexpr auto set() const
96  {
97  struct predicate
98  {
99  static LEXY_CONSTEVAL auto name()
100  {
101  return "byte.set";
102  }
103 
104  constexpr bool operator()(unsigned char byte) const
105  {
106  return ((byte == Bytes) || ...);
107  }
108  };
109 
110  return if_<predicate>();
111  }
112 
113  constexpr auto ascii() const
114  {
115  struct predicate
116  {
117  static LEXY_CONSTEVAL auto name()
118  {
119  return "byte.ASCII";
120  }
121 
122  constexpr bool operator()(unsigned char byte) const
123  {
124  return byte <= 0x7F;
125  }
126  };
127 
128  return if_<predicate>();
129  }
130 };
131 
133 constexpr auto byte = _b<1, void>{};
134 
136 template <std::size_t N>
137 constexpr auto bytes = _b<N, void>{};
138 } // namespace lexyd
139 
140 namespace lexy
141 {
142 template <std::size_t N>
143 constexpr auto token_kind_of<lexy::dsl::_b<N, void>> = lexy::any_token_kind;
144 } // namespace lexy
145 
146 //=== padding bytes ===//
147 namespace lexyd
148 {
149 template <std::size_t N, unsigned char Padding = 0>
150 struct _pb : branch_base
151 {
152  template <typename Context, typename Reader, typename Iterator>
153  static constexpr void _validate(Context& context, const Reader&, Iterator begin, Iterator end)
154  {
155  constexpr unsigned char str[] = {Padding, 0};
156  for (auto iter = begin; iter != end; ++iter)
157  {
158  if (*iter != Padding)
159  {
160  auto err = lexy::error<Reader, lexy::expected_literal>(iter, str, 0, 1);
161  context.on(_ev::error{}, err);
162  }
163  }
164  }
165 
166  template <typename Reader>
167  struct bp
168  {
169  static_assert(lexy::is_byte_encoding<typename Reader::encoding>);
170  typename Reader::marker end;
171 
172  constexpr auto try_parse(const void*, const Reader& reader)
173  {
174  lexy::token_parser_for<_b<N, void>, Reader> parser(reader);
175  auto result = parser.try_parse(reader);
176  end = parser.end;
177  return result;
178  }
179 
180  template <typename Context>
181  constexpr void cancel(Context&)
182  {}
183 
184  template <typename NextParser, typename Context, typename... Args>
185  LEXY_PARSER_FUNC auto finish(Context& context, Reader& reader, Args&&... args)
186  {
187  auto begin = reader.position();
188  context.on(_ev::token{}, lexy::any_token_kind, begin, end.position());
189  reader.reset(end);
190 
191  _validate(context, reader, begin, end.position());
193  LEXY_FWD(args)...);
194  }
195  };
196 
197  template <typename NextParser>
198  struct p
199  {
200  template <typename Context, typename Reader, typename... Args>
201  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
202  {
203  static_assert(lexy::is_byte_encoding<typename Reader::encoding>);
204  auto begin = reader.position();
205  if (!_b<N, void>::token_parse(context, reader))
206  return false;
207  auto end = reader.position();
208 
209  _validate(context, reader, begin, end);
211  LEXY_FWD(args)...);
212  }
213  };
214 };
215 
218 template <std::size_t N, unsigned char Padding = 0>
219 constexpr auto padding_bytes = _pb<N, Padding>{};
220 } // namespace lexyd
221 
222 //=== bint ===//
223 namespace lexy::_detail
224 {
226 {
229 
230 #if LEXY_IS_LITTLE_ENDIAN
232 #else
234 #endif
235 };
236 
237 template <std::size_t N>
238 auto _bint()
239 {
240  if constexpr (N == 1)
241  return std::uint_least8_t(0);
242  else if constexpr (N == 2)
243  return std::uint_least16_t(0);
244  else if constexpr (N == 4)
245  return std::uint_least32_t(0);
246  else if constexpr (N == 8)
247  return std::uint_least64_t(0);
248  else
249  {
250  static_assert(N == 1, "invalid byte integer size");
251  return 0;
252  }
253 }
254 
255 template <std::size_t N>
256 using bint = decltype(_bint<N>());
257 } // namespace lexy::_detail
258 
259 namespace lexy
260 {
262 {
263  static LEXY_CONSTEVAL auto name()
264  {
265  return "mismatched byte count";
266  }
267 };
268 } // namespace lexy
269 
270 namespace lexyd
271 {
272 template <std::size_t N, int Endianness, typename Rule = void>
274 {
276 
277  template <typename NextParser, typename Indices = lexy::_detail::make_index_sequence<N>>
278  struct _pc;
279 
280  template <typename NextParser, std::size_t... Idx>
281  struct _pc<NextParser, lexy::_detail::index_sequence<Idx...>>
282  {
283  template <typename Context, typename Reader, typename... Args>
284  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader,
285  typename Reader::iterator begin,
286  typename Reader::iterator end, Args&&... args)
287  {
289  {
291  context.on(_ev::error{}, err);
292  return false;
293  }
294 
295  lexy::_detail::bint<N> result = 0;
296  if constexpr (N == 1)
297  {
298  // For a single byte, endianness doesn't matter.
299  result = static_cast<unsigned char>(*begin);
300  }
301  else if constexpr (Endianness == lexy::_detail::bint_big)
302  {
303  // In big endian, the first byte is shifted the most,
304  // so read in order.
305  ((result = static_cast<decltype(result)>(result << 8),
306  result = static_cast<decltype(result)>(result | *begin++), (void)Idx),
307  ...);
308  }
309  else
310  {
311  // In little endian, we need to reverse the order,
312  // so copy into a buffer to do that.
313  unsigned char buffer[N] = {((void)Idx, *begin++)...};
314  ((result = static_cast<decltype(result)>(result << 8),
315  result = static_cast<decltype(result)>(result | buffer[N - Idx - 1])),
316  ...);
317  }
318 
320  LEXY_FWD(args)..., result);
321  }
322  };
323 
324  template <typename Reader>
325  struct bp
326  {
327  static_assert(lexy::is_byte_encoding<typename Reader::encoding>);
328  typename Reader::marker end;
329 
330  constexpr auto try_parse(const void*, const Reader& reader)
331  {
333  auto result = parser.try_parse(reader);
334  end = parser.end;
335  return result;
336  }
337 
338  template <typename Context>
339  constexpr void cancel(Context&)
340  {}
341 
342  template <typename NextParser, typename Context, typename... Args>
343  LEXY_PARSER_FUNC auto finish(Context& context, Reader& reader, Args&&... args)
344  {
345  auto begin = reader.position();
346  context.on(_ev::token{}, _rule{}, begin, end.position());
347  reader.reset(end);
348 
349  return _pc<NextParser>::parse(context, reader, begin, end.position(),
350  LEXY_FWD(args)...);
351  }
352  };
353 
354  template <typename NextParser>
355  struct p
356  {
357  template <typename Context, typename Reader, typename... Args>
358  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
359  {
360  static_assert(lexy::is_byte_encoding<typename Reader::encoding>);
361  auto begin = reader.position();
362  if (!_rule::token_parse(context, reader))
363  return false;
364  auto end = reader.position();
365  return _pc<NextParser>::parse(context, reader, begin, end, LEXY_FWD(args)...);
366  }
367  };
368 
369  //=== dsl ===//
371  template <typename Token>
372  constexpr auto operator()(Token) const
373  {
374  static_assert(lexy::is_token_rule<Token>);
375  static_assert(std::is_void_v<Rule>);
377  }
378 };
379 
381 inline constexpr auto bint8 = _bint<1, lexy::_detail::bint_native>{};
382 
387 
392 
397 } // namespace lexyd
398 
399 #endif // LEXY_DSL_BYTE_HPP_INCLUDED
lexyd::_b
Definition: byte.hpp:17
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:98
lexy::any_token_kind
@ any_token_kind
Definition: grammar.hpp:88
lexy::_detail::index_sequence
integer_sequence< std::size_t, Indices... > index_sequence
Definition: integer_sequence.hpp:17
lexy::_detail::bint_big
@ bint_big
Definition: byte.hpp:228
lexyd::branch_base
Definition: grammar.hpp:20
lexyd::bytes
constexpr auto bytes
Matches N arbitrary bytes.
Definition: byte.hpp:137
lexyd::_b::if_
constexpr auto if_() const
Definition: byte.hpp:69
lexy::byte_encoding::int_type
int int_type
Definition: encoding.hpp:183
token.hpp
lexyd::padding_bytes
constexpr auto padding_bytes
Definition: byte.hpp:219
lexyd::_pb::bp
Definition: byte.hpp:167
lexyd::little_bint16
constexpr auto little_bint16
Definition: byte.hpp:385
lexyd::_bint::bp::end
Reader::marker end
Definition: byte.hpp:327
lexyd::little_bint32
constexpr auto little_bint32
Definition: byte.hpp:390
lexyd::_bint::bp
Definition: byte.hpp:325
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexyd::big_bint64
constexpr auto big_bint64
Definition: byte.hpp:396
lexy::_detail::type_or
std::conditional_t< std::is_void_v< T >, Fallback, T > type_or
Definition: config.hpp:64
lexy::byte_encoding::char_type
unsigned char char_type
Definition: encoding.hpp:182
lexyd::_b::_match
static constexpr bool _match(lexy::byte_encoding::int_type cur)
Definition: byte.hpp:21
lexy::_detail::bint
decltype(_bint< N >()) bint
Definition: byte.hpp:256
lexyd::_bint
Definition: byte.hpp:273
lexy
Definition: any_ref.hpp:12
lexyd::_b::range
constexpr auto range() const
Definition: byte.hpp:76
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
char_class.hpp
lexy::_detail::bint_endianness
bint_endianness
Definition: byte.hpp:225
detail::void
j template void())
Definition: json.hpp:4893
lexy::_detail::_bint
auto _bint()
Definition: byte.hpp:238
lexy::error
Generic failure.
Definition: error.hpp:14
lexyd::bint8
constexpr auto bint8
Matches one byte and converts it into an 8-bit integer.
Definition: byte.hpp:381
lexyd::_pb::bp::try_parse
constexpr auto try_parse(const void *, const Reader &reader)
Definition: byte.hpp:172
lexyd::_pb::bp::end
Reader::marker end
Definition: byte.hpp:169
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
lexyd::_b::tp< Reader, lexy::_detail::index_sequence< Idx... > >::tp
constexpr tp(const Reader &reader)
Definition: byte.hpp:46
lexyd::_pb::_validate
static constexpr void _validate(Context &context, const Reader &, Iterator begin, Iterator end)
Definition: byte.hpp:153
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_bint::bp::try_parse
constexpr auto try_parse(const void *, const Reader &reader)
Definition: byte.hpp:330
lexy::buffer
buffer(const CharT *, const CharT *) -> buffer< deduce_encoding< CharT >>
lexyd::_bint::p
Definition: byte.hpp:355
lexyd::_bint::_pc
Definition: byte.hpp:278
lexyd::token_base
Definition: dsl/token.hpp:42
lexyd::little_bint64
constexpr auto little_bint64
Definition: byte.hpp:395
lexyd::bint16
constexpr auto bint16
Matches two bytes and converts it into an 16-bit integer.
Definition: byte.hpp:384
lexyd::_b::tp< Reader, lexy::_detail::index_sequence< Idx... > >::try_parse
constexpr bool try_parse(Reader reader)
Definition: byte.hpp:48
lexy::_detail::automatic_ws_parser::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: whitespace.hpp:178
lexyd::_bint::bp::finish
LEXY_PARSER_FUNC auto finish(Context &context, Reader &reader, Args &&... args)
Definition: byte.hpp:343
lexyd::big_bint32
constexpr auto big_bint32
Definition: byte.hpp:391
lexyd::_bint::bp::cancel
constexpr void cancel(Context &)
Definition: byte.hpp:339
lexy::_detail::range_size
constexpr std::size_t range_size(Iterator begin, Sentinel end)
Definition: iterator.hpp:22
lexyd::_pb::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: byte.hpp:201
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:108
integer_sequence.hpp
lexyd::big_bint16
constexpr auto big_bint16
Definition: byte.hpp:386
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::byte_encoding::eof
static LEXY_CONSTEVAL int_type eof()
Definition: encoding.hpp:191
lexyd::_bint::_rule
lexy::_detail::type_or< Rule, _b< N, void > > _rule
Definition: byte.hpp:275
lexyd::bint32
constexpr auto bint32
Matches four bytes and converts it into an 32-bit integer.
Definition: byte.hpp:389
lexyd::_pb::p
Definition: byte.hpp:198
base.hpp
lexy::_detail
Definition: any_ref.hpp:12
lexyd::_b::tp< Reader, lexy::_detail::index_sequence< Idx... > >::end
Reader::marker end
Definition: byte.hpp:43
lexyd::_pb::bp::cancel
constexpr void cancel(Context &)
Definition: byte.hpp:181
lexy::_detail::bint_native
@ bint_native
Definition: byte.hpp:233
lexyd::_bint::_pc< NextParser, lexy::_detail::index_sequence< Idx... > >::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, typename Reader::iterator begin, typename Reader::iterator end, Args &&... args)
Definition: byte.hpp:284
lexy::parse_events::token
Definition: dsl/base.hpp:57
lexyd::_b::tp< Reader, lexy::_detail::index_sequence< Idx... > >::report_error
constexpr void report_error(Context &context, const Reader &)
Definition: byte.hpp:58
lexyd::_b::ascii
constexpr auto ascii() const
Definition: byte.hpp:113
lexyd::_bint::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: byte.hpp:358
lexy::mismatched_byte_count::name
static LEXY_CONSTEVAL auto name()
Definition: byte.hpp:263
lexy::_detail::bint_little
@ bint_little
Definition: byte.hpp:227
lexyd::_b::set
constexpr auto set() const
Definition: byte.hpp:95
lexyd::_b::tp
Definition: byte.hpp:38
lexy::token_parser_for
typename TokenRule::template tp< Reader > token_parser_for
Definition: dsl/base.hpp:242
lexyd
Definition: trace.hpp:22
lexy::mismatched_byte_count
Definition: byte.hpp:261
lexyd::_bint::operator()
constexpr auto operator()(Token) const
Matches a specific token rule instead of arbitrary bytes.
Definition: byte.hpp:372
lexyd::bint64
constexpr auto bint64
Matches eight bytes and converts it into an 64-bit integer.
Definition: byte.hpp:394
lexyd::_pb::bp::finish
LEXY_PARSER_FUNC auto finish(Context &context, Reader &reader, Args &&... args)
Definition: byte.hpp:185
lexyd::_pb
Definition: byte.hpp:150


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