operator.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_OPERATOR_HPP_INCLUDED
5 #define LEXY_DSL_OPERATOR_HPP_INCLUDED
6 
8 #include <lexy/dsl/base.hpp>
9 #include <lexy/dsl/literal.hpp>
10 #include <lexy/dsl/token.hpp>
11 
12 namespace lexyd
13 {
14 template <typename Condition, typename... R>
15 struct _br;
16 template <typename... R>
17 struct _seq_impl;
18 } // namespace lexyd
19 
20 //=== tag type ===//
21 namespace lexy
22 {
23 template <typename Literal>
24 struct _op
25 {};
26 // GCC is buggy with auto parameters.
27 template <typename T, T Value>
28 struct _opv
29 {
30  constexpr operator LEXY_DECAY_DECLTYPE(Value)() const
31  {
32  return Value;
33  }
34 };
35 
36 #if LEXY_HAS_NTTP
37 template <auto Operator>
38 #else
39 template <const auto& Operator>
40 #endif
41 using op = typename LEXY_DECAY_DECLTYPE(Operator)::op_tag_type;
42 } // namespace lexy
43 
44 //=== op rule ===//
45 namespace lexy::_detail
46 {
47 template <typename... Literals>
49 {
50  static constexpr auto size = sizeof...(Literals);
51 
52  template <typename Encoding>
54  {
55  auto result = make_empty_trie<Encoding, Literals...>();
56 
57  auto value = std::size_t(0);
58  auto char_class = std::size_t(0);
59  ((result.node_value[Literals::lit_insert(result, 0, char_class)] = value++,
60  char_class += Literals::lit_char_classes.size),
61  ...);
62 
63  return result;
64  }
65  template <typename Encoding>
66  static constexpr lit_trie_for<Encoding, Literals...> trie = _build_trie<Encoding>();
67 
68  template <typename... T>
69  constexpr auto operator+(op_lit_list<T...>) const
70  {
71  return op_lit_list<Literals..., T...>{};
72  }
73 };
74 
75 template <typename Reader>
77 {
78  typename Reader::marker cur;
79  std::size_t idx;
80 };
81 
82 template <typename OpList, typename Reader>
83 constexpr auto parse_operator(Reader& reader)
84 {
85  using encoding = typename Reader::encoding;
87 
88  auto begin = reader.current();
89  auto op = op_matcher::try_match(reader);
91 }
92 } // namespace lexy::_detail
93 
94 namespace lexyd
95 {
96 template <typename Tag, typename Reader>
97 using _detect_op_tag_ctor = decltype(Tag(LEXY_DECLVAL(Reader).position()));
98 
99 template <typename Tag, typename Reader, typename Context>
101  = decltype(Tag(*LEXY_DECLVAL(Context).control_block->parse_state,
102  LEXY_DECLVAL(Reader).position()));
103 
104 template <typename TagType, typename Literal, typename... R>
105 struct _op : branch_base
106 {
107  using op_tag_type = TagType;
109 
110  template <typename NextParser, typename Context, typename Reader, typename... Args>
111  LEXY_PARSER_FUNC static bool op_finish(Context& context, Reader& reader,
113  Args&&... args)
114  {
115  context.on(_ev::token{}, typename Literal::token_type{}, op.cur.position(),
116  reader.position());
117 
118  using continuation
119  = lexy::whitespace_parser<Context, lexy::parser_for<_seq_impl<R...>, NextParser>>;
120  if constexpr (std::is_void_v<TagType>)
121  return continuation::parse(context, reader, LEXY_FWD(args)...);
123  Reader, Context>)
124  return continuation::parse(context, reader, LEXY_FWD(args)...,
125  op_tag_type(*context.control_block->parse_state, op.pos));
126  else if constexpr (lexy::_detail::is_detected<_detect_op_tag_ctor, op_tag_type, Reader>)
127  return continuation::parse(context, reader, LEXY_FWD(args)...,
128  op_tag_type(op.cur.position()));
129  else
130  return continuation::parse(context, reader, LEXY_FWD(args)..., op_tag_type{});
131  }
132 
133  template <typename Reader>
134  struct bp
135  {
137 
138  template <typename ControlBlock>
139  constexpr auto try_parse(const ControlBlock* cb, const Reader& reader)
140  {
141  return impl.try_parse(cb, reader);
142  }
143 
144  template <typename Context>
145  constexpr void cancel(Context& context)
146  {
147  impl.cancel(context);
148  }
149 
150  template <typename NextParser, typename Context, typename... Args>
151  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
152  {
153  using continuation = lexy::parser_for<_seq_impl<R...>, NextParser>;
154 
155  if constexpr (std::is_void_v<TagType>)
156  return impl.template finish<continuation>(context, reader, LEXY_FWD(args)...);
158  op_tag_type, Reader, Context>)
159  return impl
160  .template finish<continuation>(context, reader, LEXY_FWD(args)...,
161  op_tag_type(*context.control_block->parse_state,
162  reader.position()));
163  else if constexpr (lexy::_detail::is_detected<_detect_op_tag_ctor, op_tag_type, Reader>)
164  return impl.template finish<continuation>(context, reader, LEXY_FWD(args)...,
165  op_tag_type(reader.position()));
166  else
167  return impl.template finish<continuation>(context, reader, LEXY_FWD(args)...,
168  op_tag_type{});
169  }
170  };
171 
172  template <typename NextParser>
173  struct p
174  {
175  template <typename Context, typename Reader, typename... Args>
176  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
177  {
178  [[maybe_unused]] auto pos = reader.position();
179 
180  using continuation
181  = lexy::parser_for<Literal, lexy::parser_for<_seq_impl<R...>, NextParser>>;
182  if constexpr (std::is_void_v<TagType>)
183  return continuation::parse(context, reader, LEXY_FWD(args)...);
185  op_tag_type, Reader, Context>)
186  return continuation::parse(context, reader, LEXY_FWD(args)...,
187  op_tag_type(*context.control_block->parse_state, pos));
188  else if constexpr (lexy::_detail::is_detected<_detect_op_tag_ctor, op_tag_type, Reader>)
189  return continuation::parse(context, reader, LEXY_FWD(args)..., op_tag_type(pos));
190  else
191  return continuation::parse(context, reader, LEXY_FWD(args)..., op_tag_type{});
192  }
193  };
194 };
195 
196 template <typename Literal>
197 constexpr auto op(Literal)
198 {
199  static_assert(lexy::is_literal_rule<Literal>);
200  return _op<lexy::_op<Literal>, Literal>{};
201 }
202 template <typename Literal, typename... R>
203 constexpr auto op(_br<Literal, R...>)
204 {
205  static_assert(lexy::is_literal_rule<Literal>,
206  "condition in the operator must be a literal rule");
207  return _op<lexy::_op<Literal>, Literal, R...>{};
208 }
209 
210 template <typename Tag, typename Literal>
211 constexpr auto op(Literal)
212 {
213  static_assert(lexy::is_literal_rule<Literal>);
214  return _op<Tag, Literal>{};
215 }
216 template <typename Tag, typename Literal, typename... R>
217 constexpr auto op(_br<Literal, R...>)
218 {
219  static_assert(lexy::is_literal_rule<Literal>,
220  "condition in the operator must be a literal rule");
221  return _op<Tag, Literal, R...>{};
222 }
223 
224 template <auto Tag, typename Literal>
225 constexpr auto op(Literal)
226 {
227  static_assert(lexy::is_literal_rule<Literal>);
228  return _op<lexy::_opv<LEXY_DECAY_DECLTYPE(Tag), Tag>, Literal>{};
229 }
230 template <auto Tag, typename Literal, typename... R>
231 constexpr auto op(_br<Literal, R...>)
232 {
233  static_assert(lexy::is_literal_rule<Literal>,
234  "condition in the operator must be a literal rule");
235  return _op<lexy::_opv<LEXY_DECAY_DECLTYPE(Tag), Tag>, Literal, R...>{};
236 }
237 } // namespace lexyd
238 
239 //=== op choice ===//
240 namespace lexyd
241 {
242 template <typename... Ops>
244 {
245  using op_literals = decltype((typename Ops::op_literals{} + ...));
246 
247  template <typename NextParser, typename Context, typename Reader, typename... Args>
248  LEXY_PARSER_FUNC static bool op_finish(Context& context, Reader& reader,
250  Args&&... args)
251  {
252  auto result = false;
253 
254  auto cur_idx = std::size_t(0);
255  (void)((cur_idx == op.idx
256  ? (result = Ops::template op_finish<NextParser>(context, reader, op,
257  LEXY_FWD(args)...),
258  true)
259  : (++cur_idx, false))
260  || ...);
261 
262  return result;
263  }
264 
265  template <typename Reader>
266  struct bp
267  {
269  typename Reader::marker end;
270 
271  constexpr auto try_parse(const void*, Reader reader)
272  {
273  op = lexy::_detail::parse_operator<op_literals>(reader);
274  end = reader.current();
275  return op.idx < op_literals::size;
276  }
277 
278  template <typename Context>
279  constexpr void cancel(Context&)
280  {}
281 
282  template <typename NextParser, typename Context, typename... Args>
283  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
284  {
285  reader.reset(end);
286  return op_finish<NextParser>(context, reader, op, LEXY_FWD(args)...);
287  }
288  };
289 
290  template <typename NextParser>
291  struct p
292  {
293  template <typename Context, typename Reader, typename... Args>
294  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
295  {
296  bp<Reader> impl{};
297  if (!impl.try_parse(context.control_block, reader))
298  {
299  auto err = lexy::error<Reader, lexy::expected_literal_set>(impl.op.cur.position());
300  context.on(_ev::error{}, err);
301  return false;
302  }
303  else
304  {
305  return impl.template finish<NextParser>(context, reader, LEXY_FWD(args)...);
306  }
307  }
308  };
309 };
310 
311 template <typename T1, typename L1, typename... R1, typename T2, typename L2, typename... R2>
313 {
314  return _opc<decltype(lhs), decltype(rhs)>{};
315 }
316 template <typename... Ops, typename T2, typename L2, typename... R2>
318 {
319  return _opc<Ops..., decltype(rhs)>{};
320 }
321 template <typename T1, typename L1, typename... R1, typename... Ops>
323 {
324  return _opc<decltype(lhs), Ops...>{};
325 }
326 template <typename... O1, typename... O2>
328 {
329  return _opc<O1..., O2...>{};
330 }
331 } // namespace lexyd
332 
333 #endif // LEXY_DSL_OPERATOR_HPP_INCLUDED
lexy::_detail::op_lit_list::operator+
constexpr auto operator+(op_lit_list< T... >) const
Definition: operator.hpp:69
cx::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: wildcards.hpp:636
lexyd::position
constexpr auto position
Produces an iterator to the current reader position without parsing anything.
Definition: position.hpp:79
detect.hpp
lexyd::_opc::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: operator.hpp:294
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:98
lexyd::_seq_impl
Definition: operator.hpp:17
lexyd::branch_base
Definition: grammar.hpp:20
lexy::_detail::is_detected
constexpr bool is_detected
Definition: detect.hpp:28
lexyd::_opc::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: operator.hpp:283
token.hpp
literal.hpp
lexyd::_op::op_finish
static LEXY_PARSER_FUNC bool op_finish(Context &context, Reader &reader, lexy::_detail::parsed_operator< Reader > op, Args &&... args)
Definition: operator.hpp:111
lexy::_detail::parse_operator
constexpr auto parse_operator(Reader &reader)
Definition: operator.hpp:83
lexyd::_op::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: operator.hpp:176
lexyd::_op::op_tag_type
TagType op_tag_type
Definition: operator.hpp:107
lexy::branch_parser_for
typename BranchRule::template bp< Reader > branch_parser_for
Definition: dsl/base.hpp:116
lexyd::_opc::bp::cancel
constexpr void cancel(Context &)
Definition: operator.hpp:279
lexy::_detail::lit_trie_for
decltype(make_empty_trie< Encoding, Literals... >()) lit_trie_for
Definition: literal.hpp:212
lexy::_detail::op_lit_list::_build_trie
static LEXY_CONSTEVAL auto _build_trie()
Definition: operator.hpp:53
lexyd::operator/
constexpr auto operator/(R1 r1, R2 r2) -> _calt< decltype(_make_char_class(r1)), decltype(_make_char_class(r2))>
Definition: char_class.hpp:424
lexyd::_opc
Definition: operator.hpp:243
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexy::_detail::parsed_operator::idx
std::size_t idx
Definition: operator.hpp:79
lexy::_opv
Definition: operator.hpp:28
lexy
Definition: any_ref.hpp:12
lexyd::_op::bp::cancel
constexpr void cancel(Context &context)
Definition: operator.hpp:145
lexyd::_opc::bp::op
lexy::_detail::parsed_operator< Reader > op
Definition: operator.hpp:268
lexy::_op
Definition: operator.hpp:24
detail::void
j template void())
Definition: json.hpp:4893
lexyd::_detect_op_tag_ctor
decltype(Tag(LEXY_DECLVAL(Reader).position())) _detect_op_tag_ctor
Definition: operator.hpp:97
lexy::error
Generic failure.
Definition: error.hpp:14
lexy::_detail::op_lit_list::size
static constexpr auto size
Definition: operator.hpp:50
lexy::_detail::parsed_operator
Definition: operator.hpp:76
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::_opc::p
Definition: operator.hpp:291
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_br
Definition: branch.hpp:13
lexyd::_op::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: operator.hpp:151
lexyd::_op
Definition: operator.hpp:105
lexyd::_opc::op_finish
static LEXY_PARSER_FUNC bool op_finish(Context &context, Reader &reader, lexy::_detail::parsed_operator< Reader > op, Args &&... args)
Definition: operator.hpp:248
lexyd::_opc::bp::end
Reader::marker end
Definition: operator.hpp:269
lexy::_detail::op_lit_list::trie
static constexpr lit_trie_for< Encoding, Literals... > trie
Definition: operator.hpp:66
lexyd::_opc::bp::try_parse
constexpr auto try_parse(const void *, Reader reader)
Definition: operator.hpp:271
lexy::_detail::op_lit_list
Definition: operator.hpp:48
LEXY_DECAY_DECLTYPE
#define LEXY_DECAY_DECLTYPE(...)
Definition: config.hpp:34
lexy::_opv::Value
constexpr operator LEXY_DECAY_DECLTYPE() Value() const
Definition: operator.hpp:30
lexyd::_op::bp::try_parse
constexpr auto try_parse(const ControlBlock *cb, const Reader &reader)
Definition: operator.hpp:139
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:108
lexy::op
typename LEXY_DECAY_DECLTYPE(Operator)::op_tag_type op
Definition: operator.hpp:41
lexyd::_op::bp
Definition: operator.hpp:134
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::whitespace_parser
Definition: dsl/base.hpp:229
base.hpp
lexy::_detail
Definition: any_ref.hpp:12
lexy::parse_events::token
Definition: dsl/base.hpp:57
lexy::_detail::lit_trie_matcher
Definition: literal.hpp:240
lexy::parser_for
typename Rule::template p< NextParser > parser_for
Definition: dsl/base.hpp:113
lexyd::_opc::op_literals
decltype((typename Ops::op_literals{}+...)) op_literals
Definition: operator.hpp:245
lexyd::_op::bp::impl
lexy::branch_parser_for< Literal, Reader > impl
Definition: operator.hpp:136
lexyd::_detect_op_tag_ctor_with_state
decltype(Tag(*LEXY_DECLVAL(Context).control_block->parse_state, LEXY_DECLVAL(Reader).position())) _detect_op_tag_ctor_with_state
Definition: operator.hpp:102
LEXY_DECLVAL
#define LEXY_DECLVAL(...)
Definition: config.hpp:32
lexy::_detail::make_empty_trie
LEXY_CONSTEVAL auto make_empty_trie()
Definition: literal.hpp:199
lexyd::_opc::bp
Definition: operator.hpp:266
lexyd
Definition: trace.hpp:22
lexyd::op
constexpr auto op(Literal)
Definition: operator.hpp:197
lexyd::_op::p
Definition: operator.hpp:173
lexy::_detail::parsed_operator::cur
Reader::marker cur
Definition: operator.hpp:78


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