context_counter.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_CONTEXT_COUNTER_HPP_INCLUDED
5 #define LEXY_DSL_CONTEXT_COUNTER_HPP_INCLUDED
6 
8 #include <lexy/action/base.hpp>
9 #include <lexy/dsl/base.hpp>
10 #include <lexy/dsl/error.hpp>
11 
12 namespace lexy
13 {
15 {
16  static LEXY_CONSTEVAL auto name()
17  {
18  return "unequal counts";
19  }
20 };
21 } // namespace lexy
22 
23 namespace lexyd
24 {
25 template <typename Id>
27 
28 template <typename Id, int InitialValue>
30 {
31  template <typename NextParser>
32  struct p
33  {
34  template <typename Context, typename Reader, typename... Args>
35  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
36  {
37  _ctx_counter<Id> var(InitialValue);
38  var.link(context);
39  auto result = NextParser::parse(context, reader, LEXY_FWD(args)...);
40  var.unlink(context);
41  return result;
42  }
43  };
44 };
45 
46 template <typename Id, int Delta>
48 {
49  template <typename NextParser>
50  struct p
51  {
52  template <typename Context, typename Reader, typename... Args>
53  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
54  {
55  _ctx_counter<Id>::get(context.control_block) += Delta;
56  return NextParser::parse(context, reader, LEXY_FWD(args)...);
57  }
58  };
59 };
60 
61 template <typename Id, typename Rule, int Sign>
62 struct _ctx_cpush : _copy_base<Rule>
63 {
64  template <typename NextParser>
65  struct _pc
66  {
67  template <typename Context, typename Reader, typename... Args>
68  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader,
69  typename Reader::iterator begin, Args&&... args)
70  {
71  auto end = reader.position();
72  auto length = lexy::_detail::range_size(begin, end);
73 
74  _ctx_counter<Id>::get(context.control_block) += int(length) * Sign;
75 
76  return NextParser::parse(context, reader, LEXY_FWD(args)...);
77  }
78  };
79 
80  template <typename Reader>
81  struct bp
82  {
84 
85  template <typename ControlBlock>
86  constexpr auto try_parse(const ControlBlock* cb, const Reader& reader)
87  {
88  return rule.try_parse(cb, reader);
89  }
90 
91  template <typename Context>
92  constexpr void cancel(Context& context)
93  {
94  rule.cancel(context);
95  }
96 
97  template <typename NextParser, typename Context, typename... Args>
98  LEXY_PARSER_FUNC auto finish(Context& context, Reader& reader, Args&&... args)
99  {
100  // Forward to the rule, but remember the current reader position.
101  return rule.template finish<_pc<NextParser>>(context, reader, reader.position(),
102  LEXY_FWD(args)...);
103  }
104  };
105 
106  template <typename NextParser>
107  struct p
108  {
109  template <typename Context, typename Reader, typename... Args>
110  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
111  {
112  // Forward to the rule, but remember the current reader position.
114  return parser::parse(context, reader, reader.position(), LEXY_FWD(args)...);
115  }
116  };
117 };
118 
119 template <typename Id, int Value>
121 {
122  template <typename Reader>
123  struct bp
124  {
125  template <typename ControlBlock>
126  constexpr bool try_parse(const ControlBlock* cb, const Reader&)
127  {
128  return _ctx_counter<Id>::get(cb) == Value;
129  }
130 
131  template <typename Context>
132  constexpr void cancel(Context&)
133  {}
134 
135  template <typename NextParser, typename Context, typename... Args>
136  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
137  {
138  return NextParser::parse(context, reader, LEXY_FWD(args)...);
139  }
140  };
141 
142  template <typename NextParser>
143  using p = NextParser;
144 };
145 
146 template <typename Id>
148 {
149  template <typename NextParser>
150  struct p
151  {
152  template <typename Context, typename Reader, typename... Args>
153  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
154  {
155  return NextParser::parse(context, reader, LEXY_FWD(args)...,
156  _ctx_counter<Id>::get(context.control_block));
157  }
158  };
159 };
160 
161 template <typename... Ids>
162 struct _ctx_ceq;
163 template <typename H, typename... T>
164 struct _ctx_ceq<H, T...> : branch_base
165 {
166  template <typename Reader>
167  struct bp
168  {
169  template <typename ControlBlock>
170  constexpr bool try_parse(const ControlBlock* cb, const Reader&)
171  {
172  auto value = _ctx_counter<H>::get(cb);
173  return ((value == _ctx_counter<T>::get(cb)) && ...);
174  }
175 
176  template <typename Context>
177  constexpr void cancel(Context&)
178  {}
179 
180  template <typename NextParser, typename Context, typename... Args>
181  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
182  {
183  return NextParser::parse(context, reader, LEXY_FWD(args)...);
184  }
185  };
186 
187  template <typename NextParser>
188  struct p
189  {
190  template <typename Context, typename Reader, typename... Args>
191  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
192  {
193  auto value = _ctx_counter<H>::get(context.control_block);
194  if (((value != _ctx_counter<T>::get(context.control_block)) || ...))
195  {
196  auto err = lexy::error<Reader, lexy::unequal_counts>(reader.position());
197  context.on(_ev::error{}, err);
198  // Trivially recover.
199  }
200 
201  return NextParser::parse(context, reader, LEXY_FWD(args)...);
202  }
203  };
204 };
205 } // namespace lexyd
206 
207 namespace lexyd
208 {
209 template <typename Id>
211 {
212  template <int InitialValue = 0>
213  constexpr auto create() const
214  {
216  }
217 
218  constexpr auto inc() const
219  {
220  return _ctx_cadd<Id, +1>{};
221  }
222  constexpr auto dec() const
223  {
224  return _ctx_cadd<Id, -1>{};
225  }
226 
227  template <typename Rule>
228  constexpr auto push(Rule) const
229  {
230  return _ctx_cpush<Id, Rule, +1>{};
231  }
232  template <typename Rule>
233  constexpr auto pop(Rule) const
234  {
235  return _ctx_cpush<Id, Rule, -1>{};
236  }
237 
238  template <int Value>
239  constexpr auto is() const
240  {
241  return _ctx_cis<Id, Value>{};
242  }
243  constexpr auto is_zero() const
244  {
245  return is<0>();
246  }
247 
248  constexpr auto value() const
249  {
250  return _ctx_cvalue<Id>{};
251  }
252 };
253 
255 template <typename Id>
257 
259 template <typename... Ids>
261 {
262  static_assert(sizeof...(Ids) > 1);
263  return _ctx_ceq<Ids...>{};
264 }
265 } // namespace lexyd
266 
267 #endif // LEXY_DSL_CONTEXT_COUNTER_HPP_INCLUDED
268 
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:98
lexyd::branch_base
Definition: grammar.hpp:20
lexyd::_ctx_cpush::bp::rule
lexy::branch_parser_for< Rule, Reader > rule
Definition: context_counter.hpp:83
error.hpp
lexyd::_ctx_cpush::_pc
Definition: context_counter.hpp:65
lexyd::_ctx_cis::bp::cancel
constexpr void cancel(Context &)
Definition: context_counter.hpp:132
lexyd::_ctx_cpush::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:110
lexyd::_ctx_cpush::bp::finish
LEXY_PARSER_FUNC auto finish(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:98
iterator.hpp
lexyd::_ctx_ccreate
Definition: context_counter.hpp:29
lexy::_detail::parse_context_var::get
static constexpr T & get(const ControlBlock *cb)
Definition: action/base.hpp:54
lexyd::_ctx_cvalue
Definition: context_counter.hpp:147
lexyd::_ctx_cpush::bp
Definition: context_counter.hpp:81
lexy::branch_parser_for
typename BranchRule::template bp< Reader > branch_parser_for
Definition: dsl/base.hpp:116
lexyd::_ctx_cpush::p
Definition: context_counter.hpp:107
lexyd::_ctx_counter_dsl::inc
constexpr auto inc() const
Definition: context_counter.hpp:218
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexyd::_ctx_ceq< H, T... >::bp::cancel
constexpr void cancel(Context &)
Definition: context_counter.hpp:177
lexyd::_ctx_ccreate::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:35
lexy
Definition: any_ref.hpp:12
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
lexyd::_ctx_ceq< H, T... >::bp::try_parse
constexpr bool try_parse(const ControlBlock *cb, const Reader &)
Definition: context_counter.hpp:170
lexy::error
Generic failure.
Definition: error.hpp:14
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::_ctx_counter_dsl::is
constexpr auto is() const
Definition: context_counter.hpp:239
lexyd::_ctx_counter_dsl::create
constexpr auto create() const
Definition: context_counter.hpp:213
lexyd::_ctx_cvalue::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:153
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_ctx_cvalue::p
Definition: context_counter.hpp:150
lexy::_detail::parse_context_var_base::link
constexpr void link(Context &context)
Definition: action/base.hpp:27
lexyd::_ctx_cpush::bp::cancel
constexpr void cancel(Context &context)
Definition: context_counter.hpp:92
lexyd::rule_base
Definition: grammar.hpp:17
lexyd::_ctx_cadd::p
Definition: context_counter.hpp:50
lexyd::_ctx_counter_dsl
Definition: context_counter.hpp:210
lexy::unequal_counts::name
static LEXY_CONSTEVAL auto name()
Definition: context_counter.hpp:16
lexyd::_ctx_counter_dsl::is_zero
constexpr auto is_zero() const
Definition: context_counter.hpp:243
lexy::_detail::range_size
constexpr std::size_t range_size(Iterator begin, Sentinel end)
Definition: iterator.hpp:22
lexyd::_ctx_cis::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:136
lexyd::_ctx_cpush
Definition: context_counter.hpp:62
lexyd::equal_counts
constexpr auto equal_counts(_ctx_counter_dsl< Ids >...)
Takes a branch only if all counters are equal.
Definition: context_counter.hpp:260
lexy::_detail::parse_context_var
Definition: action/base.hpp:43
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:108
lexyd::_ctx_counter_dsl::pop
constexpr auto pop(Rule) const
Definition: context_counter.hpp:233
lexyd::_ctx_cadd
Definition: context_counter.hpp:47
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexyd::_ctx_ceq< H, T... >::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:191
base.hpp
lexyd::_ctx_cis::p
NextParser p
Definition: context_counter.hpp:143
lexyd::_ctx_cpush::_pc::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, typename Reader::iterator begin, Args &&... args)
Definition: context_counter.hpp:68
lexyd::context_counter
constexpr auto context_counter
Declares an integer counter that is added to the parsing context.
Definition: context_counter.hpp:256
lexyd::_ctx_counter_dsl::push
constexpr auto push(Rule) const
Definition: context_counter.hpp:228
lexy::unequal_counts
Definition: context_counter.hpp:14
lexyd::_ctx_counter_dsl::dec
constexpr auto dec() const
Definition: context_counter.hpp:222
lexyd::_ctx_cpush::bp::try_parse
constexpr auto try_parse(const ControlBlock *cb, const Reader &reader)
Definition: context_counter.hpp:86
lexyd::_ctx_cadd::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:53
lexyd::_ctx_counter_dsl::value
constexpr auto value() const
Definition: context_counter.hpp:248
lexy::parser_for
typename Rule::template p< NextParser > parser_for
Definition: dsl/base.hpp:113
lexyd::_ctx_cis::bp::try_parse
constexpr bool try_parse(const ControlBlock *cb, const Reader &)
Definition: context_counter.hpp:126
base.hpp
lexyd::_ctx_ceq
Definition: context_counter.hpp:162
lexyd::_ctx_ccreate::p
Definition: context_counter.hpp:32
lexy::_detail::parse_context_var_base::unlink
constexpr void unlink(Context &context)
Definition: action/base.hpp:35
lexyd::_ctx_cis
Definition: context_counter.hpp:120
lexyd
Definition: trace.hpp:22
lexyd::_ctx_cis::bp
Definition: context_counter.hpp:123
lexyd::p
constexpr auto p
Parses the production.
Definition: production.hpp:127
lexyd::_ctx_ceq< H, T... >::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: context_counter.hpp:181
lexyd::_copy_base
decltype(_copy_base_impl< Rule >()) _copy_base
Definition: dsl/base.hpp:104


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