operator.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_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::iterator pos;
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.position();
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 TagType, typename Literal, typename... R>
100 struct _op : branch_base
101 {
102  using op_tag_type = TagType;
104 
105  template <typename NextParser, typename Context, typename Reader, typename... Args>
106  LEXY_PARSER_FUNC static bool op_finish(Context& context, Reader& reader,
108  Args&&... args)
109  {
110  context.on(_ev::token{}, typename Literal::token_type{}, op.pos, reader.position());
111 
112  using continuation
113  = lexy::whitespace_parser<Context, lexy::parser_for<_seq_impl<R...>, NextParser>>;
114  if constexpr (std::is_void_v<TagType>)
115  return continuation::parse(context, reader, LEXY_FWD(args)...);
116  else if constexpr (lexy::_detail::is_detected<_detect_op_tag_ctor, op_tag_type, Reader>)
117  return continuation::parse(context, reader, LEXY_FWD(args)...,
118  op_tag_type(reader.position()));
119  else
120  return continuation::parse(context, reader, LEXY_FWD(args)..., op_tag_type{});
121  }
122 
123  template <typename Reader>
124  struct bp
125  {
127 
128  template <typename ControlBlock>
129  constexpr auto try_parse(const ControlBlock* cb, const Reader& reader)
130  {
131  return impl.try_parse(cb, reader);
132  }
133 
134  template <typename Context>
135  constexpr void cancel(Context& context)
136  {
137  impl.cancel(context);
138  }
139 
140  template <typename NextParser, typename Context, typename... Args>
141  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
142  {
143  using continuation = lexy::parser_for<_seq_impl<R...>, NextParser>;
144 
145  if constexpr (std::is_void_v<TagType>)
146  return impl.template finish<continuation>(context, reader, LEXY_FWD(args)...);
147  else if constexpr (lexy::_detail::is_detected<_detect_op_tag_ctor, op_tag_type, Reader>)
148  return impl.template finish<continuation>(context, reader, LEXY_FWD(args)...,
149  op_tag_type(reader.position()));
150  else
151  return impl.template finish<continuation>(context, reader, LEXY_FWD(args)...,
152  op_tag_type{});
153  }
154  };
155 
156  template <typename NextParser>
157  struct p
158  {
159  template <typename Context, typename Reader, typename... Args>
160  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
161  {
162  [[maybe_unused]] auto pos = reader.position();
163 
164  using continuation
165  = lexy::parser_for<Literal, lexy::parser_for<_seq_impl<R...>, NextParser>>;
166  if constexpr (std::is_void_v<TagType>)
167  return continuation::parse(context, reader, LEXY_FWD(args)...);
168  else if constexpr (lexy::_detail::is_detected<_detect_op_tag_ctor, op_tag_type, Reader>)
169  return continuation::parse(context, reader, LEXY_FWD(args)..., op_tag_type(pos));
170  else
171  return continuation::parse(context, reader, LEXY_FWD(args)..., op_tag_type{});
172  }
173  };
174 };
175 
176 template <typename Literal>
177 constexpr auto op(Literal)
178 {
179  static_assert(lexy::is_literal_rule<Literal>);
180  return _op<lexy::_op<Literal>, Literal>{};
181 }
182 template <typename Literal, typename... R>
183 constexpr auto op(_br<Literal, R...>)
184 {
185  static_assert(lexy::is_literal_rule<Literal>,
186  "condition in the operator must be a literal rule");
187  return _op<lexy::_op<Literal>, Literal, R...>{};
188 }
189 
190 template <typename Tag, typename Literal>
191 constexpr auto op(Literal)
192 {
193  static_assert(lexy::is_literal_rule<Literal>);
194  return _op<Tag, Literal>{};
195 }
196 template <typename Tag, typename Literal, typename... R>
197 constexpr auto op(_br<Literal, R...>)
198 {
199  static_assert(lexy::is_literal_rule<Literal>,
200  "condition in the operator must be a literal rule");
201  return _op<Tag, Literal, R...>{};
202 }
203 
204 template <auto Tag, typename Literal>
205 constexpr auto op(Literal)
206 {
207  static_assert(lexy::is_literal_rule<Literal>);
208  return _op<lexy::_opv<LEXY_DECAY_DECLTYPE(Tag), Tag>, Literal>{};
209 }
210 template <auto Tag, typename Literal, typename... R>
211 constexpr auto op(_br<Literal, R...>)
212 {
213  static_assert(lexy::is_literal_rule<Literal>,
214  "condition in the operator must be a literal rule");
215  return _op<lexy::_opv<LEXY_DECAY_DECLTYPE(Tag), Tag>, Literal, R...>{};
216 }
217 } // namespace lexyd
218 
219 //=== op choice ===//
220 namespace lexyd
221 {
222 template <typename... Ops>
224 {
225  using op_literals = decltype((typename Ops::op_literals{} + ...));
226 
227  template <typename NextParser, typename Context, typename Reader, typename... Args>
228  LEXY_PARSER_FUNC static bool op_finish(Context& context, Reader& reader,
230  Args&&... args)
231  {
232  auto result = false;
233 
234  auto cur_idx = std::size_t(0);
235  (void)((cur_idx == op.idx
236  ? (result = Ops::template op_finish<NextParser>(context, reader, op,
237  LEXY_FWD(args)...),
238  true)
239  : (++cur_idx, false))
240  || ...);
241 
242  return result;
243  }
244 
245  template <typename Reader>
246  struct bp
247  {
249  typename Reader::iterator end;
250 
251  constexpr auto try_parse(const void*, Reader reader)
252  {
253  op = lexy::_detail::parse_operator<op_literals>(reader);
254  end = reader.position();
255  return op.idx < op_literals::size;
256  }
257 
258  template <typename Context>
259  constexpr void cancel(Context&)
260  {}
261 
262  template <typename NextParser, typename Context, typename... Args>
263  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
264  {
265  reader.set_position(end);
266  return op_finish<NextParser>(context, reader, op, LEXY_FWD(args)...);
267  }
268  };
269 
270  template <typename NextParser>
271  struct p
272  {
273  template <typename Context, typename Reader, typename... Args>
274  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
275  {
276  bp<Reader> impl{};
277  if (!impl.try_parse(context.control_block, reader))
278  {
279  auto err = lexy::error<Reader, lexy::expected_literal_set>(impl.op.pos);
280  context.on(_ev::error{}, err);
281  return false;
282  }
283  else
284  {
285  return impl.template finish<NextParser>(context, reader, LEXY_FWD(args)...);
286  }
287  }
288  };
289 };
290 
291 template <typename T1, typename L1, typename... R1, typename T2, typename L2, typename... R2>
293 {
294  return _opc<decltype(lhs), decltype(rhs)>{};
295 }
296 template <typename... Ops, typename T2, typename L2, typename... R2>
298 {
299  return _opc<Ops..., decltype(rhs)>{};
300 }
301 template <typename T1, typename L1, typename... R1, typename... Ops>
303 {
304  return _opc<decltype(lhs), Ops...>{};
305 }
306 template <typename... O1, typename... O2>
308 {
309  return _opc<O1..., O2...>{};
310 }
311 } // namespace lexyd
312 
313 #endif // LEXY_DSL_OPERATOR_HPP_INCLUDED
314 
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:274
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:90
lexyd::_seq_impl
Definition: operator.hpp:17
lexyd::branch_base
Definition: grammar.hpp:20
lexyd::_opc::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: operator.hpp:263
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:106
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:160
lexyd::_op::op_tag_type
TagType op_tag_type
Definition: operator.hpp:102
lexy::branch_parser_for
typename BranchRule::template bp< Reader > branch_parser_for
Definition: dsl/base.hpp:103
lexy::_detail::parsed_operator::pos
Reader::iterator pos
Definition: operator.hpp:78
lexyd::_opc::bp::cancel
constexpr void cancel(Context &)
Definition: operator.hpp:259
lexy::_detail::lit_trie_for
decltype(make_empty_trie< Encoding, Literals... >()) lit_trie_for
Definition: literal.hpp:211
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:423
lexyd::_opc
Definition: operator.hpp:223
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:22
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:135
lexyd::_opc::bp::op
lexy::_detail::parsed_operator< Reader > op
Definition: operator.hpp:248
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:271
lexy::parse_events::error
Definition: dsl/base.hpp:55
lexyd::_br
Definition: branch.hpp:13
lexyd::_op::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: operator.hpp:141
lexyd::_op
Definition: operator.hpp:100
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:228
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:251
lexy::_detail::op_lit_list
Definition: operator.hpp:48
LEXY_DECAY_DECLTYPE
#define LEXY_DECAY_DECLTYPE(...)
Definition: config.hpp:26
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:129
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:95
lexy::op
typename LEXY_DECAY_DECLTYPE(Operator)::op_tag_type op
Definition: operator.hpp:41
lexyd::_op::bp
Definition: operator.hpp:124
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::whitespace_parser
Definition: dsl/base.hpp:216
base.hpp
lexy::_detail
Definition: any_ref.hpp:12
lexy::parse_events::token
Definition: dsl/base.hpp:44
lexy::_detail::lit_trie_matcher
Definition: literal.hpp:239
lexy::parser_for
typename Rule::template p< NextParser > parser_for
Definition: dsl/base.hpp:100
lexyd::_opc::op_literals
decltype((typename Ops::op_literals{}+...)) op_literals
Definition: operator.hpp:225
lexyd::_op::bp::impl
lexy::branch_parser_for< Literal, Reader > impl
Definition: operator.hpp:126
LEXY_DECLVAL
#define LEXY_DECLVAL(...)
Definition: config.hpp:24
lexyd::_opc::bp::end
Reader::iterator end
Definition: operator.hpp:249
lexy::_detail::make_empty_trie
LEXY_CONSTEVAL auto make_empty_trie()
Definition: literal.hpp:198
lexyd::_opc::bp
Definition: operator.hpp:246
lexyd
Definition: trace.hpp:22
lexyd::op
constexpr auto op(Literal)
Definition: operator.hpp:177
lexyd::_op::p
Definition: operator.hpp:157


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