RetroArch
peglib.h
Go to the documentation of this file.
1 //
2 // peglib.h
3 //
4 // Copyright (c) 2015-17 Yuji Hirose. All rights reserved.
5 // MIT License
6 //
7 
8 #ifndef CPPPEGLIB_PEGLIB_H
9 #define CPPPEGLIB_PEGLIB_H
10 
11 #include <algorithm>
12 #include <cassert>
13 #include <cstring>
14 #include <functional>
15 #include <initializer_list>
16 #include <iostream>
17 #include <limits>
18 #include <map>
19 #include <memory>
20 #include <mutex>
21 #include <set>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 
26 // guard for older versions of VC++
27 #ifdef _MSC_VER
28 // VS2013 has no constexpr
29 #if (_MSC_VER == 1800)
30 #define PEGLIB_NO_CONSTEXPR_SUPPORT
31 #elif (_MSC_VER >= 1800)
32 // good to go
33 #else (_MSC_VER < 1800)
34 #error "Requires C+11 support"
35 #endif
36 #endif
37 
38 // define if the compiler doesn't support unicode characters reliably in the
39 // source code
40 //#define PEGLIB_NO_UNICODE_CHARS
41 
42 namespace peg {
43 
44 #if __clang__ == 1 && __clang_major__ == 5 && __clang_minor__ == 0 && __clang_patchlevel__ == 0
45 static void* enabler = nullptr; // workaround for Clang 5.0.0
46 #else
47 extern void* enabler;
48 #endif
49 
50 /*-----------------------------------------------------------------------------
51  * any
52  *---------------------------------------------------------------------------*/
53 
54 class any
55 {
56 public:
57  any() : content_(nullptr) {}
58 
59  any(const any& rhs) : content_(rhs.clone()) {}
60 
61  any(any&& rhs) : content_(rhs.content_) {
62  rhs.content_ = nullptr;
63  }
64 
65  template <typename T>
66  any(const T& value) : content_(new holder<T>(value)) {}
67 
68  any& operator=(const any& rhs) {
69  if (this != &rhs) {
70  if (content_) {
71  delete content_;
72  }
73  content_ = rhs.clone();
74  }
75  return *this;
76  }
77 
78  any& operator=(any&& rhs) {
79  if (this != &rhs) {
80  if (content_) {
81  delete content_;
82  }
83  content_ = rhs.content_;
84  rhs.content_ = nullptr;
85  }
86  return *this;
87  }
88 
89  ~any() {
90  delete content_;
91  }
92 
93  bool is_undefined() const {
94  return content_ == nullptr;
95  }
96 
97  template <
98  typename T,
100  >
101  T& get() {
102  if (!content_) {
103  throw std::bad_cast();
104  }
105  auto p = dynamic_cast<holder<T>*>(content_);
106  assert(p);
107  if (!p) {
108  throw std::bad_cast();
109  }
110  return p->value_;
111  }
112 
113  template <
114  typename T,
116  >
117  T& get() {
118  return *this;
119  }
120 
121  template <
122  typename T,
124  >
125  const T& get() const {
126  assert(content_);
127  auto p = dynamic_cast<holder<T>*>(content_);
128  assert(p);
129  if (!p) {
130  throw std::bad_cast();
131  }
132  return p->value_;
133  }
134 
135  template <
136  typename T,
138  >
139  const any& get() const {
140  return *this;
141  }
142 
143 private:
144  struct placeholder {
145  virtual ~placeholder() {}
146  virtual placeholder* clone() const = 0;
147  };
148 
149  template <typename T>
150  struct holder : placeholder {
151  holder(const T& value) : value_(value) {}
152  placeholder* clone() const override {
153  return new holder(value_);
154  }
156  };
157 
158  placeholder* clone() const {
159  return content_ ? content_->clone() : nullptr;
160  }
161 
163 };
164 
165 /*-----------------------------------------------------------------------------
166  * scope_exit
167  *---------------------------------------------------------------------------*/
168 
169 // This is based on "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189".
170 
171 template <typename EF>
173 {
174  explicit scope_exit(EF&& f)
175  : exit_function(std::move(f))
176  , execute_on_destruction{true} {}
177 
179  : exit_function(std::move(rhs.exit_function))
180  , execute_on_destruction{rhs.execute_on_destruction} {
181  rhs.release();
182  }
183 
186  this->exit_function();
187  }
188  }
189 
190  void release() {
191  this->execute_on_destruction = false;
192  }
193 
194 private:
195  scope_exit(const scope_exit&) = delete;
196  void operator=(const scope_exit&) = delete;
197  scope_exit& operator=(scope_exit&&) = delete;
198 
201 };
202 
203 template <typename EF>
204 auto make_scope_exit(EF&& exit_function) -> scope_exit<EF> {
205  return scope_exit<typename std::remove_reference<EF>::type>(std::forward<EF>(exit_function));
206 }
207 
208 /*-----------------------------------------------------------------------------
209  * PEG
210  *---------------------------------------------------------------------------*/
211 
212 /*
213 * Line information utility function
214 */
215 inline std::pair<size_t, size_t> line_info(const char* start, const char* cur) {
216  auto p = start;
217  auto col_ptr = p;
218  auto no = 1;
219 
220  while (p < cur) {
221  if (*p == '\n') {
222  no++;
223  col_ptr = p + 1;
224  }
225  p++;
226  }
227 
228  auto col = p - col_ptr + 1;
229 
230  return std::make_pair(no, col);
231 }
232 
233 /*
234 * Semantic values
235 */
236 struct SemanticValues : protected std::vector<any>
237 {
238  // Input text
239  const char* path;
240  const char* ss;
241 
242  // Matched string
243  const char* c_str() const { return s_; }
244  size_t length() const { return n_; }
245 
246  std::string str() const {
247  return std::string(s_, n_);
248  }
249 
250  // Line number and column at which the matched string is
251  std::pair<size_t, size_t> line_info() const {
252  return peg::line_info(ss, s_);
253  }
254 
255  // Choice number (0 based index)
256  size_t choice() const { return choice_; }
257 
258  // Tokens
259  std::vector<std::pair<const char*, size_t>> tokens;
260 
261  std::string token(size_t id = 0) const {
262  if (!tokens.empty()) {
263  assert(id < tokens.size());
264  const auto& tok = tokens[id];
265  return std::string(tok.first, tok.second);
266  }
267  return std::string(s_, n_);
268  }
269 
270  // Transform the semantic value vector to another vector
271  template <typename T>
272  auto transform(size_t beg = 0, size_t end = static_cast<size_t>(-1)) const -> vector<T> {
273  return this->transform(beg, end, [](const any& v) { return v.get<T>(); });
274  }
275 
276  SemanticValues() : s_(nullptr), n_(0), choice_(0) {}
277 
278  using std::vector<any>::iterator;
279  using std::vector<any>::const_iterator;
281  using std::vector<any>::empty;
282  using std::vector<any>::assign;
283  using std::vector<any>::begin;
284  using std::vector<any>::end;
285  using std::vector<any>::rbegin;
286  using std::vector<any>::rend;
287  using std::vector<any>::operator[];
288  using std::vector<any>::at;
289  using std::vector<any>::resize;
290  using std::vector<any>::front;
291  using std::vector<any>::back;
292  using std::vector<any>::push_back;
293  using std::vector<any>::pop_back;
294  using std::vector<any>::insert;
295  using std::vector<any>::erase;
296  using std::vector<any>::clear;
298  using std::vector<any>::emplace;
299  using std::vector<any>::emplace_back;
300 
301 private:
302  friend class Context;
303  friend class PrioritizedChoice;
304  friend class Holder;
305 
306  const char* s_;
307  size_t n_;
308  size_t choice_;
309 
310  template <typename F>
311  auto transform(F f) const -> vector<typename std::remove_const<decltype(f(any()))>::type> {
312  vector<typename std::remove_const<decltype(f(any()))>::type> r;
313  for (const auto& v: *this) {
314  r.emplace_back(f(v));
315  }
316  return r;
317  }
318 
319  template <typename F>
320  auto transform(size_t beg, size_t end, F f) const -> vector<typename std::remove_const<decltype(f(any()))>::type> {
321  vector<typename std::remove_const<decltype(f(any()))>::type> r;
322  end = (std::min)(end, size());
323  for (size_t i = beg; i < end; i++) {
324  r.emplace_back(f((*this)[i]));
325  }
326  return r;
327  }
328 };
329 
330 /*
331  * Semantic action
332  */
333 template <
334  typename R, typename F,
336  typename... Args>
337 any call(F fn, Args&&... args) {
338  fn(std::forward<Args>(args)...);
339  return any();
340 }
341 
342 template <
343  typename R, typename F,
345  typename... Args>
346 any call(F fn, Args&&... args) {
347  return fn(std::forward<Args>(args)...);
348 }
349 
350 template <
351  typename R, typename F,
352  typename std::enable_if<
355  typename... Args>
356 any call(F fn, Args&&... args) {
357  return any(fn(std::forward<Args>(args)...));
358 }
359 
360 class Action
361 {
362 public:
363  Action() = default;
364 
365  Action(const Action& rhs) : fn_(rhs.fn_) {}
366 
368  Action(F fn) : fn_(make_adaptor(fn, &F::operator())) {}
369 
371  Action(F fn) : fn_(make_adaptor(fn, fn)) {}
372 
374  Action(F /*fn*/) {}
375 
377  void operator=(F fn) {
378  fn_ = make_adaptor(fn, &F::operator());
379  }
380 
382  void operator=(F fn) {
383  fn_ = make_adaptor(fn, fn);
384  }
385 
387  void operator=(F /*fn*/) {}
388 
389  Action& operator=(const Action& rhs) = default;
390 
391  operator bool() const {
392  return bool(fn_);
393  }
394 
395  any operator()(const SemanticValues& sv, any& dt) const {
396  return fn_(sv, dt);
397  }
398 
399 private:
400  template <typename R>
401  struct TypeAdaptor {
402  TypeAdaptor(std::function<R (const SemanticValues& sv)> fn)
403  : fn_(fn) {}
404  any operator()(const SemanticValues& sv, any& /*dt*/) {
405  return call<R>(fn_, sv);
406  }
407  std::function<R (const SemanticValues& sv)> fn_;
408  };
409 
410  template <typename R>
411  struct TypeAdaptor_c {
412  TypeAdaptor_c(std::function<R (const SemanticValues& sv, any& dt)> fn)
413  : fn_(fn) {}
414  any operator()(const SemanticValues& sv, any& dt) {
415  return call<R>(fn_, sv, dt);
416  }
417  std::function<R (const SemanticValues& sv, any& dt)> fn_;
418  };
419 
420  typedef std::function<any (const SemanticValues& sv, any& dt)> Fty;
421 
422  template<typename F, typename R>
423  Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv) const) {
424  return TypeAdaptor<R>(fn);
425  }
426 
427  template<typename F, typename R>
428  Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv)) {
429  return TypeAdaptor<R>(fn);
430  }
431 
432  template<typename F, typename R>
433  Fty make_adaptor(F fn, R (* /*mf*/)(const SemanticValues& sv)) {
434  return TypeAdaptor<R>(fn);
435  }
436 
437  template<typename F, typename R>
438  Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt) const) {
439  return TypeAdaptor_c<R>(fn);
440  }
441 
442  template<typename F, typename R>
443  Fty make_adaptor(F fn, R (F::* /*mf*/)(const SemanticValues& sv, any& dt)) {
444  return TypeAdaptor_c<R>(fn);
445  }
446 
447  template<typename F, typename R>
448  Fty make_adaptor(F fn, R(* /*mf*/)(const SemanticValues& sv, any& dt)) {
449  return TypeAdaptor_c<R>(fn);
450  }
451 
453 };
454 
455 /*
456  * Semantic predicate
457  */
458 // Note: 'parse_error' exception class should be be used in sematic action handlers to reject the rule.
459 struct parse_error {
460  parse_error() = default;
461  parse_error(const char* s) : s_(s) {}
462  const char* what() const { return s_.empty() ? nullptr : s_.c_str(); }
463 private:
465 };
466 
467 /*
468  * Match action
469  */
470 typedef std::function<void (const char* s, size_t n, size_t id, const std::string& name)> MatchAction;
471 
472 /*
473  * Result
474  */
475 inline bool success(size_t len) {
476  return len != static_cast<size_t>(-1);
477 }
478 
479 inline bool fail(size_t len) {
480  return len == static_cast<size_t>(-1);
481 }
482 
483 /*
484  * Context
485  */
486 class Ope;
487 class Context;
489 
490 typedef std::function<void (const char* name, const char* s, size_t n, const SemanticValues& sv, const Context& c, const any& dt)> Tracer;
491 
492 class Context
493 {
494 public:
495  const char* path;
496  const char* s;
497  const size_t l;
498 
499  const char* error_pos;
500  const char* message_pos;
501  std::string message; // TODO: should be `int`.
502 
503  std::vector<std::shared_ptr<SemanticValues>> value_stack;
505 
506  size_t nest_level;
507 
508  bool in_token;
509 
510  std::shared_ptr<Ope> whitespaceOpe;
512 
513  const size_t def_count;
515  std::vector<bool> cache_registered;
516  std::vector<bool> cache_success;
517 
518  std::map<std::pair<size_t, size_t>, std::tuple<size_t, any>> cache_values;
519 
520  std::function<void (const char*, const char*, size_t, const SemanticValues&, const Context&, const any&)> tracer;
521 
523  const char* a_path,
524  const char* a_s,
525  size_t a_l,
526  size_t a_def_count,
527  std::shared_ptr<Ope> a_whitespaceOpe,
528  bool a_enablePackratParsing,
529  Tracer a_tracer)
530  : path(a_path)
531  , s(a_s)
532  , l(a_l)
533  , error_pos(nullptr)
534  , message_pos(nullptr)
535  , value_stack_size(0)
536  , nest_level(0)
537  , in_token(false)
538  , whitespaceOpe(a_whitespaceOpe)
540  , def_count(a_def_count)
541  , enablePackratParsing(a_enablePackratParsing)
544  , tracer(a_tracer)
545  {
546  }
547 
548  template <typename T>
549  void packrat(const char* a_s, size_t def_id, size_t& len, any& val, T fn) {
550  if (!enablePackratParsing) {
551  fn(val);
552  return;
553  }
554 
555  auto col = a_s - s;
556  auto idx = def_count * static_cast<size_t>(col) + def_id;
557 
558  if (cache_registered[idx]) {
559  if (cache_success[idx]) {
560  auto key = std::make_pair(col, def_id);
561  std::tie(len, val) = cache_values[key];
562  return;
563  } else {
564  len = static_cast<size_t>(-1);
565  return;
566  }
567  } else {
568  fn(val);
569  cache_registered[idx] = true;
571  if (success(len)) {
572  auto key = std::make_pair(col, def_id);
573  cache_values[key] = std::make_pair(len, val);
574  }
575  return;
576  }
577  }
578 
580  assert(value_stack_size <= value_stack.size());
581  if (value_stack_size == value_stack.size()) {
582  value_stack.emplace_back(std::make_shared<SemanticValues>());
583  }
584  auto& sv = *value_stack[value_stack_size++];
585  if (!sv.empty()) {
586  sv.clear();
587  }
588  sv.path = path;
589  sv.ss = s;
590  sv.s_ = nullptr;
591  sv.n_ = 0;
592  sv.tokens.clear();
593  return sv;
594  }
595 
596  void pop() {
598  }
599 
600  void set_error_pos(const char* a_s) {
601  if (error_pos < a_s) error_pos = a_s;
602  }
603 
604  void trace(const char* name, const char* a_s, size_t n, SemanticValues& sv, any& dt) const {
605  if (tracer) tracer(name, a_s, n, sv, *this, dt);
606  }
607 };
608 
609 /*
610  * Parser operators
611  */
612 class Ope
613 {
614 public:
615  struct Visitor;
616 
617  virtual ~Ope() {}
618  virtual size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const = 0;
619  virtual void accept(Visitor& v) = 0;
620 };
621 
622 class Sequence : public Ope
623 {
624 public:
625  Sequence(const Sequence& rhs) : opes_(rhs.opes_) {}
626 
627 #if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015
628  // NOTE: Compiler Error C2797 on Visual Studio 2013
629  // "The C++ compiler in Visual Studio does not implement list
630  // initialization inside either a member initializer list or a non-static
631  // data member initializer. Before Visual Studio 2013 Update 3, this was
632  // silently converted to a function call, which could lead to bad code
633  // generation. Visual Studio 2013 Update 3 reports this as an error."
634  template <typename... Args>
635  Sequence(const Args& ...args) {
636  opes_ = std::vector<std::shared_ptr<Ope>>{ static_cast<std::shared_ptr<Ope>>(args)... };
637  }
638 #else
639  template <typename... Args>
640  Sequence(const Args& ...args) : opes_{ static_cast<std::shared_ptr<Ope>>(args)... } {}
641 #endif
642 
643  Sequence(const std::vector<std::shared_ptr<Ope>>& opes) : opes_(opes) {}
644  Sequence(std::vector<std::shared_ptr<Ope>>&& opes) : opes_(opes) {}
645 
646  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
647  c.trace("Sequence", s, n, sv, dt);
648  size_t i = 0;
649  for (const auto& ope : opes_) {
650  c.nest_level++;
651  auto se = make_scope_exit([&]() { c.nest_level--; });
652  const auto& rule = *ope;
653  auto len = rule.parse(s + i, n - i, sv, c, dt);
654  if (fail(len)) {
655  return static_cast<size_t>(-1);
656  }
657  i += len;
658  }
659  return i;
660  }
661 
662  void accept(Visitor& v) override;
663 
664  std::vector<std::shared_ptr<Ope>> opes_;
665 };
666 
667 class PrioritizedChoice : public Ope
668 {
669 public:
670 #if defined(_MSC_VER) && _MSC_VER < 1900 // Less than Visual Studio 2015
671  // NOTE: Compiler Error C2797 on Visual Studio 2013
672  // "The C++ compiler in Visual Studio does not implement list
673  // initialization inside either a member initializer list or a non-static
674  // data member initializer. Before Visual Studio 2013 Update 3, this was
675  // silently converted to a function call, which could lead to bad code
676  // generation. Visual Studio 2013 Update 3 reports this as an error."
677  template <typename... Args>
678  PrioritizedChoice(const Args& ...args) {
679  opes_ = std::vector<std::shared_ptr<Ope>>{ static_cast<std::shared_ptr<Ope>>(args)... };
680  }
681 #else
682  template <typename... Args>
683  PrioritizedChoice(const Args& ...args) : opes_{ static_cast<std::shared_ptr<Ope>>(args)... } {}
684 #endif
685 
686  PrioritizedChoice(const std::vector<std::shared_ptr<Ope>>& opes) : opes_(opes) {}
687  PrioritizedChoice(std::vector<std::shared_ptr<Ope>>&& opes) : opes_(opes) {}
688 
689  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
690  c.trace("PrioritizedChoice", s, n, sv, dt);
691  size_t id = 0;
692  for (const auto& ope : opes_) {
693  c.nest_level++;
694  auto& chldsv = c.push();
695  auto se = make_scope_exit([&]() {
696  c.nest_level--;
697  c.pop();
698  });
699  const auto& rule = *ope;
700  auto len = rule.parse(s, n, chldsv, c, dt);
701  if (success(len)) {
702  if (!chldsv.empty()) {
703  sv.insert(sv.end(), chldsv.begin(), chldsv.end());
704  }
705  sv.s_ = chldsv.c_str();
706  sv.n_ = chldsv.length();
707  sv.choice_ = id;
708  sv.tokens.insert(sv.tokens.end(), chldsv.tokens.begin(), chldsv.tokens.end());
709  return len;
710  }
711  id++;
712  }
713  return static_cast<size_t>(-1);
714  }
715 
716  void accept(Visitor& v) override;
717 
718  size_t size() const { return opes_.size(); }
719 
720  std::vector<std::shared_ptr<Ope>> opes_;
721 };
722 
723 class ZeroOrMore : public Ope
724 {
725 public:
726  ZeroOrMore(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
727 
728  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
729  c.trace("ZeroOrMore", s, n, sv, dt);
730  auto save_error_pos = c.error_pos;
731  size_t i = 0;
732  while (n - i > 0) {
733  c.nest_level++;
734  auto se = make_scope_exit([&]() { c.nest_level--; });
735  auto save_sv_size = sv.size();
736  auto save_tok_size = sv.tokens.size();
737  const auto& rule = *ope_;
738  auto len = rule.parse(s + i, n - i, sv, c, dt);
739  if (fail(len)) {
740  if (sv.size() != save_sv_size) {
741  sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
742  }
743  if (sv.tokens.size() != save_tok_size) {
744  sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
745  }
746  c.error_pos = save_error_pos;
747  break;
748  }
749  i += len;
750  }
751  return i;
752  }
753 
754  void accept(Visitor& v) override;
755 
756  std::shared_ptr<Ope> ope_;
757 };
758 
759 class OneOrMore : public Ope
760 {
761 public:
762  OneOrMore(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
763 
764  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
765  c.trace("OneOrMore", s, n, sv, dt);
766  size_t len = 0;
767  {
768  c.nest_level++;
769  auto se = make_scope_exit([&]() { c.nest_level--; });
770  const auto& rule = *ope_;
771  len = rule.parse(s, n, sv, c, dt);
772  if (fail(len)) {
773  return static_cast<size_t>(-1);
774  }
775  }
776  auto save_error_pos = c.error_pos;
777  auto i = len;
778  while (n - i > 0) {
779  c.nest_level++;
780  auto se = make_scope_exit([&]() { c.nest_level--; });
781  auto save_sv_size = sv.size();
782  auto save_tok_size = sv.tokens.size();
783  const auto& rule = *ope_;
784  len = rule.parse(s + i, n - i, sv, c, dt);
785  if (fail(len)) {
786  if (sv.size() != save_sv_size) {
787  sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
788  }
789  if (sv.tokens.size() != save_tok_size) {
790  sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
791  }
792  c.error_pos = save_error_pos;
793  break;
794  }
795  i += len;
796  }
797  return i;
798  }
799 
800  void accept(Visitor& v) override;
801 
802  std::shared_ptr<Ope> ope_;
803 };
804 
805 class Option : public Ope
806 {
807 public:
808  Option(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
809 
810  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
811  c.trace("Option", s, n, sv, dt);
812  auto save_error_pos = c.error_pos;
813  c.nest_level++;
814  auto save_sv_size = sv.size();
815  auto save_tok_size = sv.tokens.size();
816  auto se = make_scope_exit([&]() { c.nest_level--; });
817  const auto& rule = *ope_;
818  auto len = rule.parse(s, n, sv, c, dt);
819  if (success(len)) {
820  return len;
821  } else {
822  if (sv.size() != save_sv_size) {
823  sv.erase(sv.begin() + static_cast<std::ptrdiff_t>(save_sv_size));
824  }
825  if (sv.tokens.size() != save_tok_size) {
826  sv.tokens.erase(sv.tokens.begin() + static_cast<std::ptrdiff_t>(save_tok_size));
827  }
828  c.error_pos = save_error_pos;
829  return 0;
830  }
831  }
832 
833  void accept(Visitor& v) override;
834 
835  std::shared_ptr<Ope> ope_;
836 };
837 
838 class AndPredicate : public Ope
839 {
840 public:
841  AndPredicate(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
842 
843  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
844  c.trace("AndPredicate", s, n, sv, dt);
845  c.nest_level++;
846  auto& chldsv = c.push();
847  auto se = make_scope_exit([&]() {
848  c.nest_level--;
849  c.pop();
850  });
851  const auto& rule = *ope_;
852  auto len = rule.parse(s, n, chldsv, c, dt);
853  if (success(len)) {
854  return 0;
855  } else {
856  return static_cast<size_t>(-1);
857  }
858  }
859 
860  void accept(Visitor& v) override;
861 
862  std::shared_ptr<Ope> ope_;
863 };
864 
865 class NotPredicate : public Ope
866 {
867 public:
868  NotPredicate(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
869 
870  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
871  c.trace("NotPredicate", s, n, sv, dt);
872  auto save_error_pos = c.error_pos;
873  c.nest_level++;
874  auto& chldsv = c.push();
875  auto se = make_scope_exit([&]() {
876  c.nest_level--;
877  c.pop();
878  });
879  const auto& rule = *ope_;
880  auto len = rule.parse(s, n, chldsv, c, dt);
881  if (success(len)) {
882  c.set_error_pos(s);
883  return static_cast<size_t>(-1);
884  } else {
885  c.error_pos = save_error_pos;
886  return 0;
887  }
888  }
889 
890  void accept(Visitor& v) override;
891 
892  std::shared_ptr<Ope> ope_;
893 };
894 
895 class LiteralString : public Ope
896 {
897 public:
899 
900  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override;
901 
902  void accept(Visitor& v) override;
903 
905 };
906 
907 class CharacterClass : public Ope
908 {
909 public:
910  CharacterClass(const std::string& chars) : chars_(chars) {}
911 
912  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
913  c.trace("CharacterClass", s, n, sv, dt);
914  // TODO: UTF8 support
915  if (n < 1) {
916  c.set_error_pos(s);
917  return static_cast<size_t>(-1);
918  }
919  auto ch = s[0];
920  auto i = 0u;
921  while (i < chars_.size()) {
922  if (i + 2 < chars_.size() && chars_[i + 1] == '-') {
923  if (chars_[i] <= ch && ch <= chars_[i + 2]) {
924  return 1;
925  }
926  i += 3;
927  } else {
928  if (chars_[i] == ch) {
929  return 1;
930  }
931  i += 1;
932  }
933  }
934  c.set_error_pos(s);
935  return static_cast<size_t>(-1);
936  }
937 
938  void accept(Visitor& v) override;
939 
941 };
942 
943 class Character : public Ope
944 {
945 public:
946  Character(char ch) : ch_(ch) {}
947 
948  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
949  c.trace("Character", s, n, sv, dt);
950  // TODO: UTF8 support
951  if (n < 1 || s[0] != ch_) {
952  c.set_error_pos(s);
953  return static_cast<size_t>(-1);
954  }
955  return 1;
956  }
957 
958  void accept(Visitor& v) override;
959 
960  char ch_;
961 };
962 
963 class AnyCharacter : public Ope
964 {
965 public:
966  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
967  c.trace("AnyCharacter", s, n, sv, dt);
968  // TODO: UTF8 support
969  if (n < 1) {
970  c.set_error_pos(s);
971  return static_cast<size_t>(-1);
972  }
973  return 1;
974  }
975 
976  void accept(Visitor& v) override;
977 };
978 
979 class Capture : public Ope
980 {
981 public:
982  Capture(const std::shared_ptr<Ope>& ope, MatchAction ma, size_t id, const std::string& name)
983  : ope_(ope), match_action_(ma), id_(id), name_(name) {}
984 
985  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
986  const auto& rule = *ope_;
987  auto len = rule.parse(s, n, sv, c, dt);
988  if (success(len) && match_action_) {
990  }
991  return len;
992  }
993 
994  void accept(Visitor& v) override;
995 
996  std::shared_ptr<Ope> ope_;
997 
998 private:
1000  size_t id_;
1002 };
1003 
1004 class TokenBoundary : public Ope
1005 {
1006 public:
1007  TokenBoundary(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
1008 
1009  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override;
1010 
1011  void accept(Visitor& v) override;
1012 
1013  std::shared_ptr<Ope> ope_;
1014 };
1015 
1016 class Ignore : public Ope
1017 {
1018 public:
1019  Ignore(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
1020 
1021  size_t parse(const char* s, size_t n, SemanticValues& /*sv*/, Context& c, any& dt) const override {
1022  const auto& rule = *ope_;
1023  auto& chldsv = c.push();
1024  auto se = make_scope_exit([&]() {
1025  c.pop();
1026  });
1027  return rule.parse(s, n, chldsv, c, dt);
1028  }
1029 
1030  void accept(Visitor& v) override;
1031 
1032  std::shared_ptr<Ope> ope_;
1033 };
1034 
1035 typedef std::function<size_t (const char* s, size_t n, SemanticValues& sv, any& dt)> Parser;
1036 
1037 class WeakHolder : public Ope
1038 {
1039 public:
1040  WeakHolder(const std::shared_ptr<Ope>& ope) : weak_(ope) {}
1041 
1042  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
1043  auto ope = weak_.lock();
1044  assert(ope);
1045  const auto& rule = *ope;
1046  return rule.parse(s, n, sv, c, dt);
1047  }
1048 
1049  void accept(Visitor& v) override;
1050 
1051  std::weak_ptr<Ope> weak_;
1052 };
1053 
1054 class Holder : public Ope
1055 {
1056 public:
1058  : outer_(outer) {}
1059 
1060  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override;
1061 
1062  void accept(Visitor& v) override;
1063 
1064  any reduce(const SemanticValues& sv, any& dt) const;
1065 
1066  std::shared_ptr<Ope> ope_;
1068 
1069  friend class Definition;
1070 };
1071 
1072 class DefinitionReference : public Ope
1073 {
1074 public:
1076  const std::unordered_map<std::string, Definition>& grammar, const std::string& name, const char* s)
1077  : grammar_(grammar)
1078  , name_(name)
1079  , s_(s) {}
1080 
1081  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override;
1082 
1083  void accept(Visitor& v) override;
1084 
1085  std::shared_ptr<Ope> get_rule() const;
1086 
1087  const std::unordered_map<std::string, Definition>& grammar_;
1089  const char* s_;
1090 
1091 private:
1092  mutable std::once_flag init_;
1093  mutable std::shared_ptr<Ope> rule_;
1094 };
1095 
1096 class Whitespace : public Ope
1097 {
1098 public:
1099  Whitespace(const std::shared_ptr<Ope>& ope) : ope_(ope) {}
1100 
1101  size_t parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const override {
1102  if (c.in_whitespace) {
1103  return 0;
1104  }
1105  c.in_whitespace = true;
1106  auto se = make_scope_exit([&]() { c.in_whitespace = false; });
1107  const auto& rule = *ope_;
1108  return rule.parse(s, n, sv, c, dt);
1109  }
1110 
1111  void accept(Visitor& v) override;
1112 
1113  std::shared_ptr<Ope> ope_;
1114 };
1115 
1116 /*
1117  * Visitor
1118  */
1120 {
1121  virtual ~Visitor() {}
1122  virtual void visit(Sequence& /*ope*/) {}
1123  virtual void visit(PrioritizedChoice& /*ope*/) {}
1124  virtual void visit(ZeroOrMore& /*ope*/) {}
1125  virtual void visit(OneOrMore& /*ope*/) {}
1126  virtual void visit(Option& /*ope*/) {}
1127  virtual void visit(AndPredicate& /*ope*/) {}
1128  virtual void visit(NotPredicate& /*ope*/) {}
1129  virtual void visit(LiteralString& /*ope*/) {}
1130  virtual void visit(CharacterClass& /*ope*/) {}
1131  virtual void visit(Character& /*ope*/) {}
1132  virtual void visit(AnyCharacter& /*ope*/) {}
1133  virtual void visit(Capture& /*ope*/) {}
1134  virtual void visit(TokenBoundary& /*ope*/) {}
1135  virtual void visit(Ignore& /*ope*/) {}
1136  virtual void visit(WeakHolder& /*ope*/) {}
1137  virtual void visit(Holder& /*ope*/) {}
1138  virtual void visit(DefinitionReference& /*ope*/) {}
1139  virtual void visit(Whitespace& /*ope*/) {}
1140 };
1141 
1143 {
1144  using Ope::Visitor::visit;
1145 
1146  void visit(Sequence& ope) override {
1147  for (auto op: ope.opes_) {
1148  op->accept(*this);
1149  }
1150  }
1151  void visit(PrioritizedChoice& ope) override {
1152  for (auto op: ope.opes_) {
1153  op->accept(*this);
1154  }
1155  }
1156  void visit(ZeroOrMore& ope) override { ope.ope_->accept(*this); }
1157  void visit(OneOrMore& ope) override { ope.ope_->accept(*this); }
1158  void visit(Option& ope) override { ope.ope_->accept(*this); }
1159  void visit(AndPredicate& ope) override { ope.ope_->accept(*this); }
1160  void visit(NotPredicate& ope) override { ope.ope_->accept(*this); }
1161  void visit(Capture& ope) override { ope.ope_->accept(*this); }
1162  void visit(TokenBoundary& ope) override { ope.ope_->accept(*this); }
1163  void visit(Ignore& ope) override { ope.ope_->accept(*this); }
1164  void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); }
1165  void visit(Holder& ope) override;
1166  void visit(DefinitionReference& ope) override { ope.get_rule()->accept(*this); }
1167 
1168  std::unordered_map<void*, size_t> ids;
1169 };
1170 
1171 struct IsToken : public Ope::Visitor
1172 {
1174 
1175  using Ope::Visitor::visit;
1176 
1177  void visit(Sequence& ope) override {
1178  for (auto op: ope.opes_) {
1179  op->accept(*this);
1180  }
1181  }
1182  void visit(PrioritizedChoice& ope) override {
1183  for (auto op: ope.opes_) {
1184  op->accept(*this);
1185  }
1186  }
1187  void visit(ZeroOrMore& ope) override { ope.ope_->accept(*this); }
1188  void visit(OneOrMore& ope) override { ope.ope_->accept(*this); }
1189  void visit(Option& ope) override { ope.ope_->accept(*this); }
1190  void visit(Capture& ope) override { ope.ope_->accept(*this); }
1191  void visit(TokenBoundary& /*ope*/) override { has_token_boundary = true; }
1192  void visit(Ignore& ope) override { ope.ope_->accept(*this); }
1193  void visit(WeakHolder& ope) override { ope.weak_.lock()->accept(*this); }
1194  void visit(DefinitionReference& /*ope*/) override { has_rule = true; }
1195 
1196  bool is_token() const {
1197  return has_token_boundary || !has_rule;
1198  }
1199 
1201  bool has_rule;
1202 };
1203 
1204 static const char* WHITESPACE_DEFINITION_NAME = "%whitespace";
1205 
1206 /*
1207  * Definition
1208  */
1210 {
1211 public:
1212  struct Result {
1213  bool ret;
1214  size_t len;
1215  const char* error_pos;
1216  const char* message_pos;
1218  };
1219 
1223  , is_token(false)
1225  , holder_(std::make_shared<Holder>(this)) {}
1226 
1228  : name(rhs.name)
1231  , is_token(false)
1233  , holder_(rhs.holder_)
1234  {
1235  holder_->outer_ = this;
1236  }
1237 
1239  : name(std::move(rhs.name))
1243  , is_token(rhs.is_token)
1245  , holder_(std::move(rhs.holder_))
1246  {
1247  holder_->outer_ = this;
1248  }
1249 
1250  Definition(const std::shared_ptr<Ope>& ope)
1253  , is_token(false)
1255  , holder_(std::make_shared<Holder>(this))
1256  {
1257  *this <= ope;
1258  }
1259 
1260  operator std::shared_ptr<Ope>() {
1261  return std::make_shared<WeakHolder>(holder_);
1262  }
1263 
1264  Definition& operator<=(const std::shared_ptr<Ope>& ope) {
1265  IsToken isToken;
1266  ope->accept(isToken);
1267  is_token = isToken.is_token();
1269 
1270  holder_->ope_ = ope;
1271 
1272  return *this;
1273  }
1274 
1275  Result parse(const char* s, size_t n, const char* path = nullptr) const {
1276  SemanticValues sv;
1277  any dt;
1278  return parse_core(s, n, sv, dt, path);
1279  }
1280 
1281  Result parse(const char* s, const char* path = nullptr) const {
1282  auto n = strlen(s);
1283  return parse(s, n, path);
1284  }
1285 
1286  Result parse(const char* s, size_t n, any& dt, const char* path = nullptr) const {
1287  SemanticValues sv;
1288  return parse_core(s, n, sv, dt, path);
1289  }
1290 
1291  Result parse(const char* s, any& dt, const char* path = nullptr) const {
1292  auto n = strlen(s);
1293  return parse(s, n, dt, path);
1294  }
1295 
1296  template <typename T>
1297  Result parse_and_get_value(const char* s, size_t n, T& val, const char* path = nullptr) const {
1298  SemanticValues sv;
1299  any dt;
1300  auto r = parse_core(s, n, sv, dt, path);
1301  if (r.ret && !sv.empty() && !sv.front().is_undefined()) {
1302  val = sv[0].get<T>();
1303  }
1304  return r;
1305  }
1306 
1307  template <typename T>
1308  Result parse_and_get_value(const char* s, T& val, const char* path = nullptr) const {
1309  auto n = strlen(s);
1310  return parse_and_get_value(s, n, val, path);
1311  }
1312 
1313  template <typename T>
1314  Result parse_and_get_value(const char* s, size_t n, any& dt, T& val, const char* path = nullptr) const {
1315  SemanticValues sv;
1316  auto r = parse_core(s, n, sv, dt, path);
1317  if (r.ret && !sv.empty() && !sv.front().is_undefined()) {
1318  val = sv[0].get<T>();
1319  }
1320  return r;
1321  }
1322 
1323  template <typename T>
1324  Result parse_and_get_value(const char* s, any& dt, T& val, const char* path = nullptr) const {
1325  auto n = strlen(s);
1326  return parse_and_get_value(s, n, dt, val, path);
1327  }
1328 
1330  action = a;
1331  return *this;
1332  }
1333 
1334  template <typename T>
1336  operator=(fn);
1337  return *this;
1338  }
1339 
1341  ignoreSemanticValue = true;
1342  return *this;
1343  }
1344 
1346  holder_->accept(v);
1347  }
1348 
1349  std::shared_ptr<Ope> get_core_operator() {
1350  return holder_->ope_;
1351  }
1352 
1354  size_t id;
1356  std::function<void (any& dt)> enter;
1357  std::function<void (any& dt)> leave;
1358  std::function<std::string ()> error_message;
1360  std::shared_ptr<Ope> whitespaceOpe;
1362  bool is_token;
1365 
1366 private:
1367  friend class DefinitionReference;
1368 
1369  Definition& operator=(const Definition& rhs);
1371 
1372  Result parse_core(const char* s, size_t n, SemanticValues& sv, any& dt, const char* path) const {
1373  AssignIDToDefinition assignId;
1374  holder_->accept(assignId);
1375 
1376  std::shared_ptr<Ope> ope = holder_;
1377  if (whitespaceOpe) {
1378  ope = std::make_shared<Sequence>(whitespaceOpe, ope);
1379  }
1380 
1381  Context cxt(path, s, n, assignId.ids.size(), whitespaceOpe, enablePackratParsing, tracer);
1382  auto len = ope->parse(s, n, sv, cxt, dt);
1383  return Result{ success(len), len, cxt.error_pos, cxt.message_pos, cxt.message };
1384  }
1385 
1386  std::shared_ptr<Holder> holder_;
1387 };
1388 
1389 /*
1390  * Implementations
1391  */
1392 
1393 inline size_t LiteralString::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const {
1394  c.trace("LiteralString", s, n, sv, dt);
1395 
1396  size_t i = 0;
1397  for (; i < lit_.size(); i++) {
1398  if (i >= n || s[i] != lit_[i]) {
1399  c.set_error_pos(s);
1400  return static_cast<size_t>(-1);
1401  }
1402  }
1403 
1404  // Skip whiltespace
1405  if (!c.in_token) {
1406  if (c.whitespaceOpe) {
1407  auto len = c.whitespaceOpe->parse(s + i, n - i, sv, c, dt);
1408  if (fail(len)) {
1409  return static_cast<size_t>(-1);
1410  }
1411  i += len;
1412  }
1413  }
1414 
1415  return i;
1416 }
1417 
1418 inline size_t TokenBoundary::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const {
1419  c.in_token = true;
1420  auto se = make_scope_exit([&]() { c.in_token = false; });
1421  const auto& rule = *ope_;
1422  auto len = rule.parse(s, n, sv, c, dt);
1423  if (success(len)) {
1424  sv.tokens.push_back(std::make_pair(s, len));
1425 
1426  if (c.whitespaceOpe) {
1427  auto l = c.whitespaceOpe->parse(s + len, n - len, sv, c, dt);
1428  if (fail(l)) {
1429  return static_cast<size_t>(-1);
1430  }
1431  len += l;
1432  }
1433  }
1434  return len;
1435 }
1436 
1437 inline size_t Holder::parse(const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const {
1438  if (!ope_) {
1439  throw std::logic_error("Uninitialized definition ope was used...");
1440  }
1441 
1442  c.trace(outer_->name.c_str(), s, n, sv, dt);
1443  c.nest_level++;
1444  auto se = make_scope_exit([&]() { c.nest_level--; });
1445 
1446  size_t len;
1447  any val;
1448 
1449  c.packrat(s, outer_->id, len, val, [&](any& a_val) {
1450  auto& chldsv = c.push();
1451 
1452  if (outer_->enter) {
1453  outer_->enter(dt);
1454  }
1455 
1456  auto se2 = make_scope_exit([&]() {
1457  c.pop();
1458 
1459  if (outer_->leave) {
1460  outer_->leave(dt);
1461  }
1462  });
1463 
1464  const auto& rule = *ope_;
1465  len = rule.parse(s, n, chldsv, c, dt);
1466 
1467  // Invoke action
1468  if (success(len)) {
1469  chldsv.s_ = s;
1470  chldsv.n_ = len;
1471 
1472  try {
1473  a_val = reduce(chldsv, dt);
1474  } catch (const parse_error& e) {
1475  if (e.what()) {
1476  if (c.message_pos < s) {
1477  c.message_pos = s;
1478  c.message = e.what();
1479  }
1480  }
1481  len = static_cast<size_t>(-1);
1482  }
1483  }
1484  });
1485 
1486  if (success(len)) {
1487  if (!outer_->ignoreSemanticValue) {
1488  sv.emplace_back(val);
1489  }
1490  } else {
1491  if (outer_->error_message) {
1492  if (c.message_pos < s) {
1493  c.message_pos = s;
1494  c.message = outer_->error_message();
1495  }
1496  }
1497  }
1498 
1499  return len;
1500 }
1501 
1502 inline any Holder::reduce(const SemanticValues& sv, any& dt) const {
1503  if (outer_->action) {
1504  return outer_->action(sv, dt);
1505  } else if (sv.empty()) {
1506  return any();
1507  } else {
1508  return sv.front();
1509  }
1510 }
1511 
1512 inline size_t DefinitionReference::parse(
1513  const char* s, size_t n, SemanticValues& sv, Context& c, any& dt) const {
1514  const auto& rule = *get_rule();
1515  return rule.parse(s, n, sv, c, dt);
1516 }
1517 
1518 inline std::shared_ptr<Ope> DefinitionReference::get_rule() const {
1519  if (!rule_) {
1520  std::call_once(init_, [this]() {
1521  rule_ = grammar_.at(name_).holder_;
1522  });
1523  }
1524  assert(rule_);
1525  return rule_;
1526 }
1527 
1528 inline void Sequence::accept(Visitor& v) { v.visit(*this); }
1529 inline void PrioritizedChoice::accept(Visitor& v) { v.visit(*this); }
1530 inline void ZeroOrMore::accept(Visitor& v) { v.visit(*this); }
1531 inline void OneOrMore::accept(Visitor& v) { v.visit(*this); }
1532 inline void Option::accept(Visitor& v) { v.visit(*this); }
1533 inline void AndPredicate::accept(Visitor& v) { v.visit(*this); }
1534 inline void NotPredicate::accept(Visitor& v) { v.visit(*this); }
1535 inline void LiteralString::accept(Visitor& v) { v.visit(*this); }
1536 inline void CharacterClass::accept(Visitor& v) { v.visit(*this); }
1537 inline void Character::accept(Visitor& v) { v.visit(*this); }
1538 inline void AnyCharacter::accept(Visitor& v) { v.visit(*this); }
1539 inline void Capture::accept(Visitor& v) { v.visit(*this); }
1540 inline void TokenBoundary::accept(Visitor& v) { v.visit(*this); }
1541 inline void Ignore::accept(Visitor& v) { v.visit(*this); }
1542 inline void WeakHolder::accept(Visitor& v) { v.visit(*this); }
1543 inline void Holder::accept(Visitor& v) { v.visit(*this); }
1544 inline void DefinitionReference::accept(Visitor& v) { v.visit(*this); }
1545 inline void Whitespace::accept(Visitor& v) { v.visit(*this); }
1546 
1547 inline void AssignIDToDefinition::visit(Holder& ope) {
1548  auto p = static_cast<void*>(ope.outer_);
1549  if (ids.count(p)) {
1550  return;
1551  }
1552  auto id = ids.size();
1553  ids[p] = id;
1554  ope.outer_->id = id;
1555  ope.ope_->accept(*this);
1556 }
1557 
1558 /*
1559  * Factories
1560  */
1561 template <typename... Args>
1562 std::shared_ptr<Ope> seq(Args&& ...args) {
1563  return std::make_shared<Sequence>(static_cast<std::shared_ptr<Ope>>(args)...);
1564 }
1565 
1566 template <typename... Args>
1567 std::shared_ptr<Ope> cho(Args&& ...args) {
1568  return std::make_shared<PrioritizedChoice>(static_cast<std::shared_ptr<Ope>>(args)...);
1569 }
1570 
1571 inline std::shared_ptr<Ope> zom(const std::shared_ptr<Ope>& ope) {
1572  return std::make_shared<ZeroOrMore>(ope);
1573 }
1574 
1575 inline std::shared_ptr<Ope> oom(const std::shared_ptr<Ope>& ope) {
1576  return std::make_shared<OneOrMore>(ope);
1577 }
1578 
1579 inline std::shared_ptr<Ope> opt(const std::shared_ptr<Ope>& ope) {
1580  return std::make_shared<Option>(ope);
1581 }
1582 
1583 inline std::shared_ptr<Ope> apd(const std::shared_ptr<Ope>& ope) {
1584  return std::make_shared<AndPredicate>(ope);
1585 }
1586 
1587 inline std::shared_ptr<Ope> npd(const std::shared_ptr<Ope>& ope) {
1588  return std::make_shared<NotPredicate>(ope);
1589 }
1590 
1591 inline std::shared_ptr<Ope> lit(const std::string& lit) {
1592  return std::make_shared<LiteralString>(lit);
1593 }
1594 
1595 inline std::shared_ptr<Ope> cls(const std::string& chars) {
1596  return std::make_shared<CharacterClass>(chars);
1597 }
1598 
1599 inline std::shared_ptr<Ope> chr(char dt) {
1600  return std::make_shared<Character>(dt);
1601 }
1602 
1603 inline std::shared_ptr<Ope> dot() {
1604  return std::make_shared<AnyCharacter>();
1605 }
1606 
1607 inline std::shared_ptr<Ope> cap(const std::shared_ptr<Ope>& ope, MatchAction ma, size_t n, const std::string& s) {
1608  return std::make_shared<Capture>(ope, ma, n, s);
1609 }
1610 
1611 inline std::shared_ptr<Ope> cap(const std::shared_ptr<Ope>& ope, MatchAction ma) {
1612  return std::make_shared<Capture>(ope, ma, static_cast<size_t>(-1), std::string());
1613 }
1614 
1615 inline std::shared_ptr<Ope> tok(const std::shared_ptr<Ope>& ope) {
1616  return std::make_shared<TokenBoundary>(ope);
1617 }
1618 
1619 inline std::shared_ptr<Ope> ign(const std::shared_ptr<Ope>& ope) {
1620  return std::make_shared<Ignore>(ope);
1621 }
1622 
1623 inline std::shared_ptr<Ope> ref(const std::unordered_map<std::string, Definition>& grammar, const std::string& name, const char* s) {
1624  return std::make_shared<DefinitionReference>(grammar, name, s);
1625 }
1626 
1627 inline std::shared_ptr<Ope> wsp(const std::shared_ptr<Ope>& ope) {
1628  return std::make_shared<Whitespace>(std::make_shared<Ignore>(ope));
1629 }
1630 
1631 /*-----------------------------------------------------------------------------
1632  * PEG parser generator
1633  *---------------------------------------------------------------------------*/
1634 
1635 typedef std::unordered_map<std::string, Definition> Grammar;
1636 typedef std::function<void (size_t, size_t, const std::string&)> Log;
1637 
1639 {
1640 public:
1641  static std::shared_ptr<Grammar> parse(
1642  const char* s,
1643  size_t n,
1644  std::string& start,
1645  MatchAction ma,
1646  Log log)
1647  {
1648  return get_instance().perform_core(s, n, start, ma, log);
1649  }
1650 
1651  // For debuging purpose
1652  static Grammar& grammar() {
1653  return get_instance().g;
1654  }
1655 
1656 private:
1658  static ParserGenerator instance;
1659  return instance;
1660  }
1661 
1663  make_grammar();
1664  setup_actions();
1665  }
1666 
1667  struct Data {
1668  std::shared_ptr<Grammar> grammar;
1671  std::vector<std::pair<std::string, const char*>> duplicates;
1672  std::unordered_map<std::string, const char*> references;
1674 
1676  : grammar(std::make_shared<Grammar>())
1677  , capture_count(0)
1678  {}
1679  };
1680 
1683  : s_(nullptr), name_(name), done_(false) {}
1684 
1685  using Ope::Visitor::visit;
1686 
1687  void visit(Sequence& ope) override {
1688  for (auto op: ope.opes_) {
1689  op->accept(*this);
1690  if (done_) {
1691  break;
1692  } else if (s_) {
1693  done_ = true;
1694  break;
1695  }
1696  }
1697  }
1698  void visit(PrioritizedChoice& ope) override {
1699  for (auto op: ope.opes_) {
1700  op->accept(*this);
1701  if (s_) {
1702  done_ = true;
1703  break;
1704  }
1705  }
1706  }
1707  void visit(ZeroOrMore& ope) override {
1708  ope.ope_->accept(*this);
1709  done_ = false;
1710  }
1711  void visit(OneOrMore& ope) override {
1712  ope.ope_->accept(*this);
1713  done_ = true;
1714  }
1715  void visit(Option& ope) override {
1716  ope.ope_->accept(*this);
1717  done_ = false;
1718  }
1719  void visit(AndPredicate& ope) override {
1720  ope.ope_->accept(*this);
1721  done_ = false;
1722  }
1723  void visit(NotPredicate& ope) override {
1724  ope.ope_->accept(*this);
1725  done_ = false;
1726  }
1727  void visit(LiteralString& ope) override {
1728  done_ = !ope.lit_.empty();
1729  }
1730  void visit(CharacterClass& /*ope*/) override {
1731  done_ = true;
1732  }
1733  void visit(Character& /*ope*/) override {
1734  done_ = true;
1735  }
1736  void visit(AnyCharacter& /*ope*/) override {
1737  done_ = true;
1738  }
1739  void visit(Capture& ope) override {
1740  ope.ope_->accept(*this);
1741  }
1742  void visit(TokenBoundary& ope) override {
1743  ope.ope_->accept(*this);
1744  }
1745  void visit(Ignore& ope) override {
1746  ope.ope_->accept(*this);
1747  }
1748  void visit(WeakHolder& ope) override {
1749  ope.weak_.lock()->accept(*this);
1750  }
1751  void visit(Holder& ope) override {
1752  ope.ope_->accept(*this);
1753  }
1754  void visit(DefinitionReference& ope) override {
1755  if (ope.name_ == name_) {
1756  s_ = ope.s_;
1757  } else if (refs_.count(ope.name_)) {
1758  ;
1759  } else {
1760  refs_.insert(ope.name_);
1761  ope.get_rule()->accept(*this);
1762  }
1763  done_ = true;
1764  }
1765 
1766  const char* s_;
1767 
1768  private:
1770  std::set<std::string> refs_;
1771  bool done_;
1772  };
1773 
1774  void make_grammar() {
1775  // Setup PEG syntax parser
1776  g["Grammar"] <= seq(g["Spacing"], oom(g["Definition"]), g["EndOfFile"]);
1777  g["Definition"] <= seq(opt(g["IGNORE"]), g["Identifier"], g["LEFTARROW"], g["Expression"]);
1778 
1779  g["Expression"] <= seq(g["Sequence"], zom(seq(g["SLASH"], g["Sequence"])));
1780  g["Sequence"] <= zom(g["Prefix"]);
1781  g["Prefix"] <= seq(opt(cho(g["AND"], g["NOT"])), g["Suffix"]);
1782  g["Suffix"] <= seq(g["Primary"], opt(cho(g["QUESTION"], g["STAR"], g["PLUS"])));
1783  g["Primary"] <= cho(seq(opt(g["IGNORE"]), g["Identifier"], npd(g["LEFTARROW"])),
1784  seq(g["OPEN"], g["Expression"], g["CLOSE"]),
1785  seq(g["BeginTok"], g["Expression"], g["EndTok"]),
1786  seq(g["BeginCap"], g["Expression"], g["EndCap"]),
1787  g["Literal"], g["Class"], g["DOT"]);
1788 
1789  g["Identifier"] <= seq(g["IdentCont"], g["Spacing"]);
1790  g["IdentCont"] <= seq(g["IdentStart"], zom(g["IdentRest"]));
1791  g["IdentStart"] <= cls("a-zA-Z_\x80-\xff%");
1792  g["IdentRest"] <= cho(g["IdentStart"], cls("0-9"));
1793 
1794  g["Literal"] <= cho(seq(cls("'"), tok(zom(seq(npd(cls("'")), g["Char"]))), cls("'"), g["Spacing"]),
1795  seq(cls("\""), tok(zom(seq(npd(cls("\"")), g["Char"]))), cls("\""), g["Spacing"]));
1796 
1797  g["Class"] <= seq(chr('['), tok(zom(seq(npd(chr(']')), g["Range"]))), chr(']'), g["Spacing"]);
1798 
1799  g["Range"] <= cho(seq(g["Char"], chr('-'), g["Char"]), g["Char"]);
1800  g["Char"] <= cho(seq(chr('\\'), cls("nrt'\"[]\\")),
1801  seq(chr('\\'), cls("0-3"), cls("0-7"), cls("0-7")),
1802  seq(chr('\\'), cls("0-7"), opt(cls("0-7"))),
1803  seq(lit("\\x"), cls("0-9a-fA-F"), opt(cls("0-9a-fA-F"))),
1804  seq(npd(chr('\\')), dot()));
1805 
1806 #if !defined(PEGLIB_NO_UNICODE_CHARS)
1807  g["LEFTARROW"] <= seq(cho(lit("<-"), lit(u8"←")), g["Spacing"]);
1808 #else
1809  g["LEFTARROW"] <= seq(lit("<-"), g["Spacing"]);
1810 #endif
1811  ~g["SLASH"] <= seq(chr('/'), g["Spacing"]);
1812  g["AND"] <= seq(chr('&'), g["Spacing"]);
1813  g["NOT"] <= seq(chr('!'), g["Spacing"]);
1814  g["QUESTION"] <= seq(chr('?'), g["Spacing"]);
1815  g["STAR"] <= seq(chr('*'), g["Spacing"]);
1816  g["PLUS"] <= seq(chr('+'), g["Spacing"]);
1817  g["OPEN"] <= seq(chr('('), g["Spacing"]);
1818  g["CLOSE"] <= seq(chr(')'), g["Spacing"]);
1819  g["DOT"] <= seq(chr('.'), g["Spacing"]);
1820 
1821  g["Spacing"] <= zom(cho(g["Space"], g["Comment"]));
1822  g["Comment"] <= seq(chr('#'), zom(seq(npd(g["EndOfLine"]), dot())), g["EndOfLine"]);
1823  g["Space"] <= cho(chr(' '), chr('\t'), g["EndOfLine"]);
1824  g["EndOfLine"] <= cho(lit("\r\n"), chr('\n'), chr('\r'));
1825  g["EndOfFile"] <= npd(dot());
1826 
1827  g["BeginTok"] <= seq(chr('<'), g["Spacing"]);
1828  g["EndTok"] <= seq(chr('>'), g["Spacing"]);
1829 
1830  g["BeginCap"] <= seq(chr('$'), tok(opt(g["Identifier"])), chr('<'), g["Spacing"]);
1831  g["EndCap"] <= seq(lit(">"), g["Spacing"]);
1832 
1833  g["IGNORE"] <= chr('~');
1834 
1835  // Set definition names
1836  for (auto& x: g) {
1837  x.second.name = x.first;
1838  }
1839  }
1840 
1841  void setup_actions() {
1842  g["Definition"] = [&](const SemanticValues& sv, any& dt) {
1843  Data& data = *dt.get<Data*>();
1844 
1845  auto ignore = (sv.size() == 4);
1846  auto baseId = ignore ? 1u : 0u;
1847 
1848  const auto& name = sv[baseId].get<std::string>();
1849  auto ope = sv[baseId + 2].get<std::shared_ptr<Ope>>();
1850 
1851  auto& grammar = *data.grammar;
1852  if (!grammar.count(name)) {
1853  auto& rule = grammar[name];
1854  rule <= ope;
1855  rule.name = name;
1856  rule.ignoreSemanticValue = ignore;
1857 
1858  if (data.start.empty()) {
1859  data.start = name;
1860  }
1861  } else {
1862  data.duplicates.emplace_back(name, sv.c_str());
1863  }
1864  };
1865 
1866  g["Expression"] = [&](const SemanticValues& sv) {
1867  if (sv.size() == 1) {
1868  return sv[0].get<std::shared_ptr<Ope>>();
1869  } else {
1870  std::vector<std::shared_ptr<Ope>> opes;
1871  for (auto i = 0u; i < sv.size(); i++) {
1872  opes.emplace_back(sv[i].get<std::shared_ptr<Ope>>());
1873  }
1874  const std::shared_ptr<Ope> ope = std::make_shared<PrioritizedChoice>(opes);
1875  return ope;
1876  }
1877  };
1878 
1879  g["Sequence"] = [&](const SemanticValues& sv) {
1880  if (sv.size() == 1) {
1881  return sv[0].get<std::shared_ptr<Ope>>();
1882  } else {
1883  std::vector<std::shared_ptr<Ope>> opes;
1884  for (const auto& x: sv) {
1885  opes.emplace_back(x.get<std::shared_ptr<Ope>>());
1886  }
1887  const std::shared_ptr<Ope> ope = std::make_shared<Sequence>(opes);
1888  return ope;
1889  }
1890  };
1891 
1892  g["Prefix"] = [&](const SemanticValues& sv) {
1893  std::shared_ptr<Ope> ope;
1894  if (sv.size() == 1) {
1895  ope = sv[0].get<std::shared_ptr<Ope>>();
1896  } else {
1897  assert(sv.size() == 2);
1898  auto tok = sv[0].get<char>();
1899  ope = sv[1].get<std::shared_ptr<Ope>>();
1900  if (tok == '&') {
1901  ope = apd(ope);
1902  } else { // '!'
1903  ope = npd(ope);
1904  }
1905  }
1906  return ope;
1907  };
1908 
1909  g["Suffix"] = [&](const SemanticValues& sv) {
1910  auto ope = sv[0].get<std::shared_ptr<Ope>>();
1911  if (sv.size() == 1) {
1912  return ope;
1913  } else {
1914  assert(sv.size() == 2);
1915  auto tok = sv[1].get<char>();
1916  if (tok == '?') {
1917  return opt(ope);
1918  } else if (tok == '*') {
1919  return zom(ope);
1920  } else { // '+'
1921  return oom(ope);
1922  }
1923  }
1924  };
1925 
1926  g["Primary"] = [&](const SemanticValues& sv, any& dt) -> std::shared_ptr<Ope> {
1927  Data& data = *dt.get<Data*>();
1928 
1929  switch (sv.choice()) {
1930  case 0: { // Reference
1931  auto ignore = (sv.size() == 2);
1932  auto baseId = ignore ? 1u : 0u;
1933 
1934  const auto& ident = sv[baseId].get<std::string>();
1935 
1936  if (!data.references.count(ident)) {
1937  data.references[ident] = sv.c_str(); // for error handling
1938  }
1939 
1940  if (ignore) {
1941  return ign(ref(*data.grammar, ident, sv.c_str()));
1942  } else {
1943  return ref(*data.grammar, ident, sv.c_str());
1944  }
1945  }
1946  case 1: { // (Expression)
1947  return sv[1].get<std::shared_ptr<Ope>>();
1948  }
1949  case 2: { // TokenBoundary
1950  return tok(sv[1].get<std::shared_ptr<Ope>>());
1951  }
1952  case 3: { // Capture
1953  const auto& name = sv[0].get<std::string>();
1954  auto ope = sv[1].get<std::shared_ptr<Ope>>();
1955  return cap(ope, data.match_action, ++data.capture_count, name);
1956  }
1957  default: {
1958  return sv[0].get<std::shared_ptr<Ope>>();
1959  }
1960  }
1961  };
1962 
1963  g["IdentCont"] = [](const SemanticValues& sv) {
1964  return std::string(sv.c_str(), sv.length());
1965  };
1966 
1967  g["Literal"] = [this](const SemanticValues& sv) {
1968  const auto& tok = sv.tokens.front();
1969  return lit(resolve_escape_sequence(tok.first, tok.second));
1970  };
1971  g["Class"] = [this](const SemanticValues& sv) {
1972  const auto& tok = sv.tokens.front();
1973  return cls(resolve_escape_sequence(tok.first, tok.second));
1974  };
1975 
1976  g["AND"] = [](const SemanticValues& sv) { return *sv.c_str(); };
1977  g["NOT"] = [](const SemanticValues& sv) { return *sv.c_str(); };
1978  g["QUESTION"] = [](const SemanticValues& sv) { return *sv.c_str(); };
1979  g["STAR"] = [](const SemanticValues& sv) { return *sv.c_str(); };
1980  g["PLUS"] = [](const SemanticValues& sv) { return *sv.c_str(); };
1981 
1982  g["DOT"] = [](const SemanticValues& /*sv*/) { return dot(); };
1983 
1984  g["BeginCap"] = [](const SemanticValues& sv) { return sv.token(); };
1985  }
1986 
1987  std::shared_ptr<Grammar> perform_core(
1988  const char* s,
1989  size_t n,
1990  std::string& start,
1991  MatchAction ma,
1992  Log log)
1993  {
1994  Data data;
1995  data.match_action = ma;
1996 
1997  any dt = &data;
1998  auto r = g["Grammar"].parse(s, n, dt);
1999 
2000  if (!r.ret) {
2001  if (log) {
2002  if (r.message_pos) {
2003  auto line = line_info(s, r.message_pos);
2004  log(line.first, line.second, r.message);
2005  } else {
2006  auto line = line_info(s, r.error_pos);
2007  log(line.first, line.second, "syntax error");
2008  }
2009  }
2010  return nullptr;
2011  }
2012 
2013  auto& grammar = *data.grammar;
2014 
2015  // Check duplicated definitions
2016  bool ret = data.duplicates.empty();
2017 
2018  for (const auto& x: data.duplicates) {
2019  if (log) {
2020  const auto& name = x.first;
2021  auto ptr = x.second;
2022  auto line = line_info(s, ptr);
2023  log(line.first, line.second, "'" + name + "' is already defined.");
2024  }
2025  }
2026 
2027  // Check missing definitions
2028  for (const auto& x : data.references) {
2029  const auto& name = x.first;
2030  auto ptr = x.second;
2031  if (!grammar.count(name)) {
2032  if (log) {
2033  auto line = line_info(s, ptr);
2034  log(line.first, line.second, "'" + name + "' is not defined.");
2035  }
2036  ret = false;
2037  }
2038  }
2039 
2040  if (!ret) {
2041  return nullptr;
2042  }
2043 
2044  // Check left recursion
2045  ret = true;
2046 
2047  for (auto& x: grammar) {
2048  const auto& name = x.first;
2049  auto& rule = x.second;
2050 
2052  rule.accept(lr);
2053  if (lr.s_) {
2054  if (log) {
2055  auto line = line_info(s, lr.s_);
2056  log(line.first, line.second, "'" + name + "' is left recursive.");
2057  }
2058  ret = false;;
2059  }
2060  }
2061 
2062  if (!ret) {
2063  return nullptr;
2064  }
2065 
2066  // Set root definition
2067  start = data.start;
2068 
2069  // Automatic whitespace skipping
2070  if (grammar.count(WHITESPACE_DEFINITION_NAME)) {
2071  auto& rule = (*data.grammar)[start];
2072  rule.whitespaceOpe = wsp((*data.grammar)[WHITESPACE_DEFINITION_NAME].get_core_operator());
2073  }
2074 
2075  return data.grammar;
2076  }
2077 
2078  bool is_hex(char c, int& v) {
2079  if ('0' <= c && c <= '9') {
2080  v = c - '0';
2081  return true;
2082  } else if ('a' <= c && c <= 'f') {
2083  v = c - 'a' + 10;
2084  return true;
2085  } else if ('A' <= c && c <= 'F') {
2086  v = c - 'A' + 10;
2087  return true;
2088  }
2089  return false;
2090  }
2091 
2092  bool is_digit(char c, int& v) {
2093  if ('0' <= c && c <= '9') {
2094  v = c - '0';
2095  return true;
2096  }
2097  return false;
2098  }
2099 
2100  std::pair<char, size_t> parse_hex_number(const char* s, size_t n, size_t i) {
2101  char ret = 0;
2102  int val;
2103  while (i < n && is_hex(s[i], val)) {
2104  ret = static_cast<char>(ret * 16 + val);
2105  i++;
2106  }
2107  return std::make_pair(ret, i);
2108  }
2109 
2110  std::pair<char, size_t> parse_octal_number(const char* s, size_t n, size_t i) {
2111  char ret = 0;
2112  int val;
2113  while (i < n && is_digit(s[i], val)) {
2114  ret = static_cast<char>(ret * 8 + val);
2115  i++;
2116  }
2117  return std::make_pair(ret, i);
2118  }
2119 
2120  std::string resolve_escape_sequence(const char* s, size_t n) {
2121  std::string r;
2122  r.reserve(n);
2123 
2124  size_t i = 0;
2125  while (i < n) {
2126  auto ch = s[i];
2127  if (ch == '\\') {
2128  i++;
2129  switch (s[i]) {
2130  case 'n': r += '\n'; i++; break;
2131  case 'r': r += '\r'; i++; break;
2132  case 't': r += '\t'; i++; break;
2133  case '\'': r += '\''; i++; break;
2134  case '"': r += '"'; i++; break;
2135  case '[': r += '['; i++; break;
2136  case ']': r += ']'; i++; break;
2137  case '\\': r += '\\'; i++; break;
2138  case 'x': {
2139  std::tie(ch, i) = parse_hex_number(s, n, i + 1);
2140  r += ch;
2141  break;
2142  }
2143  default: {
2144  std::tie(ch, i) = parse_octal_number(s, n, i);
2145  r += ch;
2146  break;
2147  }
2148  }
2149  } else {
2150  r += ch;
2151  i++;
2152  }
2153  }
2154  return r;
2155  }
2156 
2158 };
2159 
2160 /*-----------------------------------------------------------------------------
2161  * AST
2162  *---------------------------------------------------------------------------*/
2163 
2164 const int AstDefaultTag = -1;
2165 
2166 #ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
2167 inline constexpr unsigned int str2tag(const char* str, int h = 0) {
2168  return !str[h] ? 5381 : (str2tag(str, h + 1) * 33) ^ static_cast<unsigned char>(str[h]);
2169 }
2170 
2171 namespace udl {
2172 inline constexpr unsigned int operator "" _(const char* s, size_t) {
2173  return str2tag(s);
2174 }
2175 }
2176 #endif
2177 
2178 template <typename Annotation>
2179 struct AstBase : public Annotation
2180 {
2181  AstBase(const char* a_path, size_t a_line, size_t a_column, const char* a_name, const std::vector<std::shared_ptr<AstBase>>& a_nodes)
2182  : path(a_path ? a_path : "")
2183  , line(a_line)
2184  , column(a_column)
2185  , name(a_name)
2186  , original_name(a_name)
2187 #ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
2188  , tag(str2tag(a_name))
2189  , original_tag(tag)
2190 #endif
2191  , is_token(false)
2192  , nodes(a_nodes)
2193  {}
2194 
2195  AstBase(const char* a_path, size_t a_line, size_t a_column, const char* a_name, const std::string& a_token)
2196  : path(a_path ? a_path : "")
2197  , line(a_line)
2198  , column(a_column)
2199  , name(a_name)
2200  , original_name(a_name)
2201 #ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
2202  , tag(str2tag(a_name))
2203  , original_tag(tag)
2204 #endif
2205  , is_token(true)
2206  , token(a_token)
2207  {}
2208 
2209  AstBase(const AstBase& ast, const char* a_original_name)
2210  : path(ast.path)
2211  , line(ast.line)
2212  , column(ast.column)
2213  , name(ast.name)
2214  , original_name(a_original_name)
2215 #ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
2216  , tag(ast.tag)
2217  , original_tag(str2tag(a_original_name))
2218 #endif
2219  , is_token(ast.is_token)
2220  , token(ast.token)
2221  , nodes(ast.nodes)
2222  , parent(ast.parent)
2223  {}
2224 
2226  const size_t line;
2227  const size_t column;
2228 
2231 #ifndef PEGLIB_NO_CONSTEXPR_SUPPORT
2232  const unsigned int tag;
2233  const unsigned int original_tag;
2234 #endif
2235 
2236  const bool is_token;
2238 
2239  std::vector<std::shared_ptr<AstBase<Annotation>>> nodes;
2240  std::shared_ptr<AstBase<Annotation>> parent;
2242  AstBase<Annotation>& operator [] (const char* name)
2243  {
2244  for(std::shared_ptr<AstBase<Annotation>>& node : nodes)
2245  {
2246  if(node->name == name)
2247  return *node;
2248  }
2249  return empty;
2250  }
2251  operator const char *()
2252  {
2253  return token.c_str();
2254  }
2255 };
2256 
2257 template <typename T>
2259  const std::shared_ptr<T>& ptr,
2260  std::string& s,
2261  int level,
2262  std::function<std::string (const T& ast, int level)> fn) {
2263 
2264  const auto& ast = *ptr;
2265  for (auto i = 0; i < level; i++) {
2266  s += " ";
2267  }
2268  std::string name;
2269  if (ast.name == ast.original_name) {
2270  name = ast.name;
2271  } else {
2272  name = ast.original_name + "[" + ast.name + "]";
2273  }
2274  if (ast.is_token) {
2275  s += "- " + name + " (" + ast.token + ")\n";
2276  } else {
2277  s += "+ " + name + "\n";
2278  }
2279  if (fn) {
2280  s += fn(ast, level + 1);
2281  }
2282  for (auto node : ast.nodes) {
2283  ast_to_s_core(node, s, level + 1, fn);
2284  }
2285 }
2286 
2287 template <typename T>
2289  const std::shared_ptr<T>& ptr,
2290  std::function<std::string (const T& ast, int level)> fn = nullptr) {
2291 
2292  std::string s;
2293  ast_to_s_core(ptr, s, 0, fn);
2294  return s;
2295 }
2296 
2298 {
2299  AstOptimizer(bool optimize_nodes, const std::vector<std::string>& filters = {})
2300  : optimize_nodes_(optimize_nodes)
2301  , filters_(filters) {}
2302 
2303  template <typename T>
2304  std::shared_ptr<T> optimize(std::shared_ptr<T> original, std::shared_ptr<T> parent = nullptr) {
2305 
2306  auto found = std::find(filters_.begin(), filters_.end(), original->name) != filters_.end();
2307  bool opt = optimize_nodes_ ? !found : found;
2308 
2309  if (opt && original->nodes.size() == 1) {
2310  auto child = optimize(original->nodes[0], parent);
2311  return std::make_shared<T>(*child, original->name.c_str());
2312  }
2313 
2314  auto ast = std::make_shared<T>(*original);
2315  ast->parent = parent;
2316  ast->nodes.clear();
2317  for (auto node : original->nodes) {
2318  auto child = optimize(node, ast);
2319  ast->nodes.push_back(child);
2320  }
2321  return ast;
2322  }
2323 
2324 private:
2325  const bool optimize_nodes_;
2326  const std::vector<std::string> filters_;
2327 };
2328 
2329 template <typename T>
2330 static std::shared_ptr<T> optimize_ast(
2331  std::shared_ptr<T> ast,
2332  const std::vector<std::string>& filters = {}) {
2333  return AstOptimizer(true, filters).optimize(ast);
2334 }
2335 
2336 struct EmptyType {};
2338 
2339 /*-----------------------------------------------------------------------------
2340  * parser
2341  *---------------------------------------------------------------------------*/
2342 
2343 class parser
2344 {
2345 public:
2346  parser() = default;
2347 
2348  parser(const char* s, size_t n) {
2349  load_grammar(s, n);
2350  }
2351 
2352  parser(const char* s)
2353  : parser(s, strlen(s)) {}
2354 
2355  operator bool() {
2356  return grammar_ != nullptr;
2357  }
2358 
2359  bool load_grammar(const char* s, size_t n) {
2360  grammar_ = ParserGenerator::parse(
2361  s, n,
2362  start_,
2363  [&](const char* a_s, size_t a_n, size_t a_id, const std::string& a_name) {
2364  if (match_action) match_action(a_s, a_n, a_id, a_name);
2365  },
2366  log);
2367 
2368  return grammar_ != nullptr;
2369  }
2370 
2371  bool load_grammar(const char* s) {
2372  auto n = strlen(s);
2373  return load_grammar(s, n);
2374  }
2375 
2376  bool parse_n(const char* s, size_t n, const char* path = nullptr) const {
2377  if (grammar_ != nullptr) {
2378  const auto& rule = (*grammar_)[start_];
2379  auto r = rule.parse(s, n, path);
2380  output_log(s, n, r);
2381  return r.ret && r.len == n;
2382  }
2383  return false;
2384  }
2385 
2386  bool parse(const char* s, const char* path = nullptr) const {
2387  auto n = strlen(s);
2388  return parse_n(s, n, path);
2389  }
2390 
2391  bool parse_n(const char* s, size_t n, any& dt, const char* path = nullptr) const {
2392  if (grammar_ != nullptr) {
2393  const auto& rule = (*grammar_)[start_];
2394  auto r = rule.parse(s, n, dt, path);
2395  output_log(s, n, r);
2396  return r.ret && r.len == n;
2397  }
2398  return false;
2399  }
2400 
2401  bool parse(const char* s, any& dt, const char* path = nullptr) const {
2402  auto n = strlen(s);
2403  return parse_n(s, n, dt, path);
2404  }
2405 
2406  template <typename T>
2407  bool parse_n(const char* s, size_t n, T& val, const char* path = nullptr) const {
2408  if (grammar_ != nullptr) {
2409  const auto& rule = (*grammar_)[start_];
2410  auto r = rule.parse_and_get_value(s, n, val, path);
2411  output_log(s, n, r);
2412  return r.ret && r.len == n;
2413  }
2414  return false;
2415  }
2416 
2417  template <typename T>
2418  bool parse(const char* s, T& val, const char* path = nullptr) const {
2419  auto n = strlen(s);
2420  return parse_n(s, n, val, path);
2421  }
2422 
2423  template <typename T>
2424  bool parse_n(const char* s, size_t n, any& dt, T& val, const char* path = nullptr) const {
2425  if (grammar_ != nullptr) {
2426  const auto& rule = (*grammar_)[start_];
2427  auto r = rule.parse_and_get_value(s, n, dt, val, path);
2428  output_log(s, n, r);
2429  return r.ret && r.len == n;
2430  }
2431  return false;
2432  }
2433 
2434  template <typename T>
2435  bool parse(const char* s, any& dt, T& val, const char* /*path*/ = nullptr) const {
2436  auto n = strlen(s);
2437  return parse_n(s, n, dt, val);
2438  }
2439 
2440  bool search(const char* s, size_t n, size_t& mpos, size_t& mlen) const {
2441  const auto& rule = (*grammar_)[start_];
2442  if (grammar_ != nullptr) {
2443  size_t pos = 0;
2444  while (pos < n) {
2445  size_t len = n - pos;
2446  auto r = rule.parse(s + pos, len);
2447  if (r.ret) {
2448  mpos = pos;
2449  mlen = len;
2450  return true;
2451  }
2452  pos++;
2453  }
2454  }
2455  mpos = 0;
2456  mlen = 0;
2457  return false;
2458  }
2459 
2460  bool search(const char* s, size_t& mpos, size_t& mlen) const {
2461  auto n = strlen(s);
2462  return search(s, n, mpos, mlen);
2463  }
2464 
2465  Definition& operator[](const char* s) {
2466  return (*grammar_)[s];
2467  }
2468 
2470  if (grammar_ != nullptr) {
2471  auto& rule = (*grammar_)[start_];
2472  rule.enablePackratParsing = true;
2473  }
2474  }
2475 
2476  template <typename T = Ast>
2478  for (auto& x: *grammar_) {
2479  const auto& name = x.first;
2480  auto& rule = x.second;
2481 
2482  if (!rule.action) {
2483  auto is_token = rule.is_token;
2484  rule.action = [=](const SemanticValues& sv) {
2485  auto line = line_info(sv.ss, sv.c_str());
2486 
2487  if (is_token) {
2488  return std::make_shared<T>(sv.path, line.first, line.second, name.c_str(), sv.token());
2489  }
2490 
2491  auto ast = std::make_shared<T>(sv.path, line.first, line.second, name.c_str(), sv.transform<std::shared_ptr<T>>());
2492 
2493  for (auto node: ast->nodes) {
2494  node->parent = ast;
2495  }
2496  return ast;
2497  };
2498  }
2499  }
2500  return *this;
2501  }
2502 
2503  void enable_trace(Tracer tracer) {
2504  if (grammar_ != nullptr) {
2505  auto& rule = (*grammar_)[start_];
2506  rule.tracer = tracer;
2507  }
2508  }
2509 
2512 
2513 private:
2514  void output_log(const char* s, size_t n, const Definition::Result& r) const {
2515  if (log) {
2516  if (!r.ret) {
2517  if (r.message_pos) {
2518  auto line = line_info(s, r.message_pos);
2519  log(line.first, line.second, r.message);
2520  } else {
2521  auto line = line_info(s, r.error_pos);
2522  log(line.first, line.second, "syntax error");
2523  }
2524  } else if (r.len != n) {
2525  auto line = line_info(s, s + r.len);
2526  log(line.first, line.second, "syntax error");
2527  }
2528  }
2529  }
2530 
2531  std::shared_ptr<Grammar> grammar_;
2533 };
2534 
2535 /*-----------------------------------------------------------------------------
2536  * Simple interface
2537  *---------------------------------------------------------------------------*/
2538 
2539 struct match
2540 {
2541  struct Item {
2542  const char* s;
2543  size_t n;
2544  size_t id;
2546 
2547  size_t length() const { return n; }
2548  std::string str() const { return std::string(s, n); }
2549  };
2550 
2551  std::vector<Item> matches;
2552 
2553  typedef std::vector<Item>::iterator iterator;
2554  typedef std::vector<Item>::const_iterator const_iterator;
2555 
2556  bool empty() const {
2557  return matches.empty();
2558  }
2559 
2560  size_t size() const {
2561  return matches.size();
2562  }
2563 
2564  size_t length(size_t n = 0) {
2565  return matches[n].length();
2566  }
2567 
2568  std::string str(size_t n = 0) const {
2569  return matches[n].str();
2570  }
2571 
2572  const Item& operator[](size_t n) const {
2573  return matches[n];
2574  }
2575 
2577  return matches.begin();
2578  }
2579 
2581  return matches.end();
2582  }
2583 
2585  return matches.cbegin();
2586  }
2587 
2589  return matches.cend();
2590  }
2591 
2592  std::vector<size_t> named_capture(const std::string& name) const {
2593  std::vector<size_t> ret;
2594  for (auto i = 0u; i < matches.size(); i++) {
2595  if (matches[i].name == name) {
2596  ret.push_back(i);
2597  }
2598  }
2599  return ret;
2600  }
2601 
2602  std::map<std::string, std::vector<size_t>> named_captures() const {
2603  std::map<std::string, std::vector<size_t>> ret;
2604  for (auto i = 0u; i < matches.size(); i++) {
2605  ret[matches[i].name].push_back(i);
2606  }
2607  return ret;
2608  }
2609 
2610  std::vector<size_t> indexed_capture(size_t id) const {
2611  std::vector<size_t> ret;
2612  for (auto i = 0u; i < matches.size(); i++) {
2613  if (matches[i].id == id) {
2614  ret.push_back(i);
2615  }
2616  }
2617  return ret;
2618  }
2619 
2620  std::map<size_t, std::vector<size_t>> indexed_captures() const {
2621  std::map<size_t, std::vector<size_t>> ret;
2622  for (auto i = 0u; i < matches.size(); i++) {
2623  ret[matches[i].id].push_back(i);
2624  }
2625  return ret;
2626  }
2627 };
2628 
2629 inline bool peg_match(const char* syntax, const char* s, match& m) {
2630  m.matches.clear();
2631 
2632  parser pg(syntax);
2633  pg.match_action = [&](const char* a_s, size_t a_n, size_t a_id, const std::string& a_name) {
2634  m.matches.push_back(match::Item{ a_s, a_n, a_id, a_name });
2635  };
2636 
2637  auto ret = pg.parse(s);
2638  if (ret) {
2639  auto n = strlen(s);
2640  m.matches.insert(m.matches.begin(), match::Item{ s, n, 0, std::string() });
2641  }
2642 
2643  return ret;
2644 }
2645 
2646 inline bool peg_match(const char* syntax, const char* s) {
2647  parser parser(syntax);
2648  return parser.parse(s);
2649 }
2650 
2651 inline bool peg_search(parser& pg, const char* s, size_t n, match& m) {
2652  m.matches.clear();
2653 
2654  pg.match_action = [&](const char* a_s, size_t a_n, size_t a_id, const std::string& a_name) {
2655  m.matches.push_back(match::Item{ a_s, a_n, a_id, a_name });
2656  };
2657 
2658  size_t mpos, mlen;
2659  auto ret = pg.search(s, n, mpos, mlen);
2660  if (ret) {
2661  m.matches.insert(m.matches.begin(), match::Item{ s + mpos, mlen, 0, std::string() });
2662  return true;
2663  }
2664 
2665  return false;
2666 }
2667 
2668 inline bool peg_search(parser& pg, const char* s, match& m) {
2669  auto n = strlen(s);
2670  return peg_search(pg, s, n, m);
2671 }
2672 
2673 inline bool peg_search(const char* syntax, const char* s, size_t n, match& m) {
2674  parser pg(syntax);
2675  return peg_search(pg, s, n, m);
2676 }
2677 
2678 inline bool peg_search(const char* syntax, const char* s, match& m) {
2679  parser pg(syntax);
2680  auto n = strlen(s);
2681  return peg_search(pg, s, n, m);
2682 }
2683 
2684 class peg_token_iterator : public std::iterator<std::forward_iterator_tag, match>
2685 {
2686 public:
2688  : s_(nullptr)
2689  , l_(0)
2690  , pos_((std::numeric_limits<size_t>::max)()) {}
2691 
2692  peg_token_iterator(const char* syntax, const char* s)
2693  : peg_(syntax)
2694  , s_(s)
2695  , l_(strlen(s))
2696  , pos_(0) {
2697  peg_.match_action = [&](const char* a_s, size_t a_n, size_t a_id, const std::string& a_name) {
2698  m_.matches.push_back(match::Item{ a_s, a_n, a_id, a_name });
2699  };
2700  search();
2701  }
2702 
2704  : peg_(rhs.peg_)
2705  , s_(rhs.s_)
2706  , l_(rhs.l_)
2707  , pos_(rhs.pos_)
2708  , m_(rhs.m_) {}
2709 
2711  search();
2712  return *this;
2713  }
2714 
2716  auto it = *this;
2717  search();
2718  return it;
2719  }
2720 
2722  return m_;
2723  }
2724 
2726  return &m_;
2727  }
2728 
2729  bool operator==(const peg_token_iterator& rhs) {
2730  return pos_ == rhs.pos_;
2731  }
2732 
2733  bool operator!=(const peg_token_iterator& rhs) {
2734  return pos_ != rhs.pos_;
2735  }
2736 
2737 private:
2738  void search() {
2739  m_.matches.clear();
2740  size_t mpos, mlen;
2741  if (peg_.search(s_ + pos_, l_ - pos_, mpos, mlen)) {
2742  m_.matches.insert(m_.matches.begin(), match::Item{ s_ + mpos, mlen, 0, std::string() });
2743  pos_ += mpos + mlen;
2744  } else {
2745  pos_ = (std::numeric_limits<size_t>::max)();
2746  }
2747  }
2748 
2750  const char* s_;
2751  size_t l_;
2752  size_t pos_;
2754 };
2755 
2759 
2760  peg_token_range(const char* syntax, const char* s)
2761  : beg_iter(peg_token_iterator(syntax, s))
2762  , end_iter() {}
2763 
2765  return beg_iter;
2766  }
2767 
2769  return end_iter;
2770  }
2771 
2773  return beg_iter;
2774  }
2775 
2777  return end_iter;
2778  }
2779 
2780 private:
2783 };
2784 
2785 } // namespace peg
2786 
2787 
2788 template<class _Elem, class _Traits, typename Annotation>
2789 std::basic_ios<_Elem, _Traits> &operator << (std::basic_ios<_Elem, _Traits> &ios,
2791 {
2792  return ios << node.token.c_str();
2793 }
2794 
2795 #endif
2796 
2797 // vim: et ts=4 sw=4 cin cino={1s ff=unix
std::string chars_
Definition: peglib.h:940
iterator begin()
Definition: peglib.h:2764
Definition: peglib.h:2179
const any & get() const
Definition: peglib.h:139
virtual void visit(ZeroOrMore &)
Definition: peglib.h:1124
Definition: peglib.h:667
iterator begin()
Definition: peglib.h:2576
Fty make_adaptor(F fn, R(F::*)(const SemanticValues &sv) const)
Definition: peglib.h:423
AstBase(const char *a_path, size_t a_line, size_t a_column, const char *a_name, const std::string &a_token)
Definition: peglib.h:2195
static std::shared_ptr< T > optimize_ast(std::shared_ptr< T > ast, const std::vector< std::string > &filters={})
Definition: peglib.h:2330
std::vector< std::pair< std::string, const char * > > duplicates
Definition: peglib.h:1671
GLuint const GLchar * name
Definition: glext.h:6671
Definition: peglib.h:1638
GLuint * ids
Definition: glext.h:6547
std::pair< size_t, size_t > line_info() const
Definition: peglib.h:251
Definition & operator[](const char *s)
Definition: peglib.h:2465
Definition: peglib.h:492
virtual void visit(Sequence &)
Definition: peglib.h:1122
std::function< size_t(const char *s, size_t n, SemanticValues &sv, any &dt)> Parser
Definition: peglib.h:1035
const GLvoid * ptr
Definition: nx_glsym.h:242
std::string token(size_t id=0) const
Definition: peglib.h:261
const char * message_pos
Definition: peglib.h:1216
Fty make_adaptor(F fn, R(*)(const SemanticValues &sv, any &dt))
Definition: peglib.h:448
Whitespace(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1099
peg_token_iterator beg_iter
Definition: peglib.h:2781
virtual ~placeholder()
Definition: peglib.h:145
virtual void visit(TokenBoundary &)
Definition: peglib.h:1134
Definition: peglib.h:1171
Definition: peglib.h:401
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:810
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
void visit(DefinitionReference &ope) override
Definition: peglib.h:1166
virtual void visit(Capture &)
Definition: peglib.h:1133
#define const
Definition: zconf.h:217
~scope_exit()
Definition: peglib.h:184
bool empty() const
Definition: peglib.h:2556
std::shared_ptr< AstBase< Annotation > > parent
Definition: peglib.h:2240
GLuint GLfloat * val
Definition: glext.h:7847
set set set set set set set macro pixldst1 op
Definition: pixman-arm-neon-asm.h:54
size_t nest_level
Definition: peglib.h:506
const peg_token_iterator const_iterator
Definition: peglib.h:2758
any(const any &rhs)
Definition: peglib.h:59
void visit(PrioritizedChoice &ope) override
Definition: peglib.h:1182
static const unsigned char tag[MAX_TESTS *3][16]
Definition: gcm.c:696
Result parse(const char *s, const char *path=nullptr) const
Definition: peglib.h:1281
Definition(Definition &&rhs)
Definition: peglib.h:1238
Action(F fn)
Definition: peglib.h:368
Definition: peglib.h:943
peg_token_iterator end_iter
Definition: peglib.h:2782
std::shared_ptr< Ope > wsp(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1627
void accept(Visitor &v) override
Definition: peglib.h:1540
AstBase< EmptyType > Ast
Definition: peglib.h:2337
Definition: peglib.h:2541
std::pair< size_t, size_t > line_info(const char *start, const char *cur)
Definition: peglib.h:215
Sequence(const Sequence &rhs)
Definition: peglib.h:625
void pop()
Definition: peglib.h:596
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:728
Definition: peglib.h:865
void trace(const char *name, const char *a_s, size_t n, SemanticValues &sv, any &dt) const
Definition: peglib.h:604
match & operator*()
Definition: peglib.h:2721
std::basic_ios< _Elem, _Traits > & operator<<(std::basic_ios< _Elem, _Traits > &ios, peg::AstBase< Annotation > &node)
Definition: peglib.h:2789
std::shared_ptr< Ope > ope_
Definition: peglib.h:835
void visit(AndPredicate &ope) override
Definition: peglib.h:1159
Holder(Definition *outer)
Definition: peglib.h:1057
Definition: peglib.h:2336
Definition: peglib.h:759
#define T(x)
bool parse_n(const char *s, size_t n, any &dt, T &val, const char *path=nullptr) const
Definition: peglib.h:2424
Definition()
Definition: peglib.h:1220
std::shared_ptr< Grammar > grammar_
Definition: peglib.h:2531
GLuint start
Definition: glext.h:6292
const std::string original_name
Definition: peglib.h:2230
Character(char ch)
Definition: peglib.h:946
auto transform(size_t beg=0, size_t end=static_cast< size_t >(-1)) const -> vector< T >
Definition: peglib.h:272
std::vector< std::shared_ptr< Ope > > opes_
Definition: peglib.h:720
Definition: peglib.h:622
Definition * outer_
Definition: peglib.h:1067
bool operator!=(const peg_token_iterator &rhs)
Definition: peglib.h:2733
const bool enablePackratParsing
Definition: peglib.h:514
const std::string message
Definition: peglib.h:1217
Definition & operator=(Action a)
Definition: peglib.h:1329
const char * s_
Definition: peglib.h:1766
scope_exit(scope_exit &&rhs)
Definition: peglib.h:178
~any()
Definition: peglib.h:89
GLdouble GLdouble GLdouble r
Definition: glext.h:6406
std::shared_ptr< Ope > cho(Args &&...args)
Definition: peglib.h:1567
Action(const Action &rhs)
Definition: peglib.h:365
std::shared_ptr< Ope > seq(Args &&...args)
Definition: peglib.h:1562
GLsizei const GLchar ** path
Definition: glext.h:7901
bool done_
Definition: peglib.h:1771
std::function< void(const char *name, const char *s, size_t n, const SemanticValues &sv, const Context &c, const any &dt)> Tracer
Definition: peglib.h:488
void accept(Visitor &v) override
Definition: peglib.h:1528
std::shared_ptr< T > optimize(std::shared_ptr< T > original, std::shared_ptr< T > parent=nullptr)
Definition: peglib.h:2304
size_t id_
Definition: peglib.h:1000
peg_token_iterator iterator
Definition: peglib.h:2757
std::string lit_
Definition: peglib.h:904
static overlayled_t * cur
Definition: led_overlay.c:18
void visit(OneOrMore &ope) override
Definition: peglib.h:1157
Definition & operator<=(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1264
GLenum GLsizei len
Definition: glext.h:7389
bool operator==(const peg_token_iterator &rhs)
Definition: peglib.h:2729
void accept(Visitor &v) override
Definition: peglib.h:1536
const std::vector< std::string > filters_
Definition: peglib.h:2326
void accept(Visitor &v) override
Definition: peglib.h:1532
virtual size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const =0
AndPredicate(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:841
GLsizeiptr size
Definition: glext.h:6559
const size_t l
Definition: peglib.h:497
const bool optimize_nodes_
Definition: peglib.h:2325
std::unordered_map< std::string, const char * > references
Definition: peglib.h:1672
virtual void visit(PrioritizedChoice &)
Definition: peglib.h:1123
GLfloat f
Definition: glext.h:8207
std::string name
Definition: peglib.h:2545
constexpr unsigned int str2tag(const char *str, int h=0)
Definition: peglib.h:2167
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld_src SRC pixld MASK if DST_R else pixld DST_R endif if
Definition: pixman-arm-neon-asm.h:543
Result parse_and_get_value(const char *s, T &val, const char *path=nullptr) const
Definition: peglib.h:1308
size_t size() const
Definition: peglib.h:718
std::vector< Item >::const_iterator const_iterator
Definition: peglib.h:2554
std::function< R(const SemanticValues &sv, any &dt)> fn_
Definition: peglib.h:417
GLenum GLuint id
Definition: glext.h:6233
Definition: peglib.h:2756
Definition: peglib.h:907
std::shared_ptr< Grammar > grammar
Definition: peglib.h:1668
void visit(AnyCharacter &) override
Definition: peglib.h:1736
std::map< std::pair< size_t, size_t >, std::tuple< size_t, any > > cache_values
Definition: peglib.h:518
TypeAdaptor(std::function< R(const SemanticValues &sv)> fn)
Definition: peglib.h:402
size_t length(size_t n=0)
Definition: peglib.h:2564
bool search(const char *s, size_t n, size_t &mpos, size_t &mlen) const
Definition: peglib.h:2440
GLdouble s
Definition: glext.h:6390
size_t choice() const
Definition: peglib.h:256
std::shared_ptr< Ope > ref(const std::unordered_map< std::string, Definition > &grammar, const std::string &name, const char *s)
Definition: peglib.h:1623
Definition: peglib.h:2539
const size_t column
Definition: peglib.h:2227
std::once_flag init_
Definition: peglib.h:1092
void visit(CharacterClass &) override
Definition: peglib.h:1730
Definition: peglib.h:838
PrioritizedChoice(std::vector< std::shared_ptr< Ope >> &&opes)
Definition: peglib.h:687
size_t parse(const char *s, size_t n, SemanticValues &, Context &c, any &dt) const override
Definition: peglib.h:1021
void enable_trace(Tracer tracer)
Definition: peglib.h:2503
Result parse_core(const char *s, size_t n, SemanticValues &sv, any &dt, const char *path) const
Definition: peglib.h:1372
void visit(LiteralString &ope) override
Definition: peglib.h:1727
GLsizei const GLchar *const * string
Definition: glext.h:6699
Log log
Definition: peglib.h:2511
ParserGenerator()
Definition: peglib.h:1662
peg_token_range(const char *syntax, const char *s)
Definition: peglib.h:2760
static std::shared_ptr< Grammar > parse(const char *s, size_t n, std::string &start, MatchAction ma, Log log)
Definition: peglib.h:1641
const char * path
Definition: peglib.h:239
std::shared_ptr< Ope > get_rule() const
Definition: peglib.h:1518
scope_exit(EF &&f)
Definition: peglib.h:174
Action()=default
AstBase(const char *a_path, size_t a_line, size_t a_column, const char *a_name, const std::vector< std::shared_ptr< AstBase >> &a_nodes)
Definition: peglib.h:2181
typedef void(__stdcall *PFN_DESTRUCTION_CALLBACK)(void *pData)
void make_grammar()
Definition: peglib.h:1774
bool parse(const char *s, any &dt, const char *path=nullptr) const
Definition: peglib.h:2401
const Item & operator[](size_t n) const
Definition: peglib.h:2572
std::shared_ptr< Ope > get_core_operator()
Definition: peglib.h:1349
bool parse(const char *s, T &val, const char *path=nullptr) const
Definition: peglib.h:2418
void visit(TokenBoundary &) override
Definition: peglib.h:1191
T value_
Definition: peglib.h:155
OneOrMore(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:762
Definition: ibxm.h:9
peg_token_iterator()
Definition: peglib.h:2687
bool success(size_t len)
Definition: peglib.h:475
any(const T &value)
Definition: peglib.h:66
void accept(Visitor &v) override
Definition: peglib.h:1530
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:912
#define R(t)
GLsizei GLsizei GLenum GLenum const GLvoid * data
Definition: glext.h:6303
const GLubyte * c
Definition: glext.h:9812
void accept(Visitor &v) override
Definition: peglib.h:1535
size_t id
Definition: peglib.h:1354
typedef bool(RETRO_CALLCONV *retro_replace_image_index_t)(unsigned index
static Grammar & grammar()
Definition: peglib.h:1652
std::string name_
Definition: peglib.h:1769
bool is_hex(char c, int &v)
Definition: peglib.h:2078
std::string str() const
Definition: peglib.h:246
size_t len
Definition: peglib.h:1214
bool is_token() const
Definition: peglib.h:1196
void visit(ZeroOrMore &ope) override
Definition: peglib.h:1707
const std::unordered_map< std::string, Definition > & grammar_
Definition: peglib.h:1087
const char * s
Definition: peglib.h:496
const std::string name_
Definition: peglib.h:1088
void visit(Sequence &ope) override
Definition: peglib.h:1146
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:1512
std::pair< char, size_t > parse_octal_number(const char *s, size_t n, size_t i)
Definition: peglib.h:2110
bool parse(const char *s, const char *path=nullptr) const
Definition: peglib.h:2386
void accept(Visitor &v) override
Definition: peglib.h:1544
size_t pos_
Definition: peglib.h:2752
size_t l_
Definition: peglib.h:2751
Action(F)
Definition: peglib.h:374
const size_t def_count
Definition: peglib.h:513
NotPredicate(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:868
const_iterator begin() const
Definition: peglib.h:2584
static ParserGenerator & get_instance()
Definition: peglib.h:1657
std::vector< Item > matches
Definition: peglib.h:2551
void visit(Character &) override
Definition: peglib.h:1733
Data()
Definition: peglib.h:1675
void visit(Capture &ope) override
Definition: peglib.h:1190
#define log(...)
Definition: spirv_cross.cpp:28
GLenum type
Definition: glext.h:6233
virtual void visit(Whitespace &)
Definition: peglib.h:1139
bool parse_n(const char *s, size_t n, const char *path=nullptr) const
Definition: peglib.h:2376
virtual void visit(CharacterClass &)
Definition: peglib.h:1130
AstBase(const AstBase &ast, const char *a_original_name)
Definition: peglib.h:2209
std::string start
Definition: peglib.h:1669
bool l
Definition: connect_wiiupro.c:37
any & operator=(any &&rhs)
Definition: peglib.h:78
const char * ss
Definition: peglib.h:240
Fty fn_
Definition: peglib.h:452
std::shared_ptr< Ope > ope_
Definition: peglib.h:756
std::string name_
Definition: peglib.h:1001
void visit(Ignore &ope) override
Definition: peglib.h:1163
const unsigned int original_tag
Definition: peglib.h:2233
Definition: peglib.h:1004
std::shared_ptr< Ope > ope_
Definition: peglib.h:1113
placeholder * content_
Definition: peglib.h:162
IsToken()
Definition: peglib.h:1173
holder(const T &value)
Definition: peglib.h:151
virtual void visit(Option &)
Definition: peglib.h:1126
std::vector< std::shared_ptr< AstBase< Annotation > > > nodes
Definition: peglib.h:2239
void accept(Visitor &v) override
Definition: peglib.h:1537
PrioritizedChoice(const std::vector< std::shared_ptr< Ope >> &opes)
Definition: peglib.h:686
bool search(const char *s, size_t &mpos, size_t &mlen) const
Definition: peglib.h:2460
std::shared_ptr< Ope > oom(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1575
DefinitionReference(const std::unordered_map< std::string, Definition > &grammar, const std::string &name, const char *s)
Definition: peglib.h:1075
std::shared_ptr< Ope > dot()
Definition: peglib.h:1603
const std::string name
Definition: peglib.h:2229
Definition & operator~()
Definition: peglib.h:1340
std::function< void(size_t, size_t, const std::string &)> Log
Definition: peglib.h:1636
Fty make_adaptor(F fn, R(F::*)(const SemanticValues &sv, any &dt) const)
Definition: peglib.h:438
std::function< any(const SemanticValues &sv, any &dt)> Fty
Definition: peglib.h:420
VULKAN_HPP_INLINE void swap(UniqueHandle< Type > &lhs, UniqueHandle< Type > &rhs)
Definition: vulkan.hpp:441
peg_token_iterator & operator++()
Definition: peglib.h:2710
std::shared_ptr< Ope > ope_
Definition: peglib.h:802
Sequence(const Args &...args)
Definition: peglib.h:640
std::shared_ptr< Ope > ope_
Definition: peglib.h:1066
std::vector< std::pair< const char *, size_t > > tokens
Definition: peglib.h:259
std::function< void(const char *, const char *, size_t, const SemanticValues &, const Context &, const any &)> tracer
Definition: peglib.h:520
size_t strlen(const char *str)
Definition: compat_ctype.c:152
void visit(OneOrMore &ope) override
Definition: peglib.h:1711
bool in_token
Definition: peglib.h:508
std::shared_ptr< Ope > rule_
Definition: peglib.h:1093
GLint level
Definition: glext.h:6293
bool is_undefined() const
Definition: peglib.h:93
any operator()(const SemanticValues &sv, any &dt)
Definition: peglib.h:414
void packrat(const char *a_s, size_t def_id, size_t &len, any &val, T fn)
Definition: peglib.h:549
std::string str(size_t n=0) const
Definition: peglib.h:2568
virtual void visit(NotPredicate &)
Definition: peglib.h:1128
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:843
std::shared_ptr< Holder > holder_
Definition: peglib.h:1386
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:948
void visit(OneOrMore &ope) override
Definition: peglib.h:1188
Definition: peglib.h:1096
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:870
std::function< void(any &dt)> enter
Definition: peglib.h:1356
Definition: peglib.h:172
std::string name
Definition: peglib.h:1353
TokenBoundary(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1007
const char * what() const
Definition: peglib.h:462
std::shared_ptr< Ope > zom(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1571
peg_token_iterator(const peg_token_iterator &rhs)
Definition: peglib.h:2703
const int AstDefaultTag
Definition: peglib.h:2164
const T & get() const
Definition: peglib.h:125
Result parse_and_get_value(const char *s, size_t n, T &val, const char *path=nullptr) const
Definition: peglib.h:1297
std::shared_ptr< Grammar > perform_core(const char *s, size_t n, std::string &start, MatchAction ma, Log log)
Definition: peglib.h:1987
iterator end()
Definition: peglib.h:2768
void visit(Holder &ope) override
Definition: peglib.h:1751
size_t n
Definition: peglib.h:2543
std::set< std::string > refs_
Definition: peglib.h:1770
GLint GLint GLint GLint GLint x
Definition: glext.h:6295
void visit(NotPredicate &ope) override
Definition: peglib.h:1723
parser peg_
Definition: peglib.h:2749
AstOptimizer(bool optimize_nodes, const std::vector< std::string > &filters={})
Definition: peglib.h:2299
void output_log(const char *s, size_t n, const Definition::Result &r) const
Definition: peglib.h:2514
size_t value_stack_size
Definition: peglib.h:504
iterator end()
Definition: peglib.h:2580
const size_t line
Definition: peglib.h:2226
void operator=(const scope_exit &)=delete
void visit(ZeroOrMore &ope) override
Definition: peglib.h:1156
bool ignoreSemanticValue
Definition: peglib.h:1359
void visit(TokenBoundary &ope) override
Definition: peglib.h:1742
void visit(TokenBoundary &ope) override
Definition: peglib.h:1162
dictionary args
Definition: test_shaders.py:20
match m_
Definition: peglib.h:2753
PrioritizedChoice(const Args &...args)
Definition: peglib.h:683
virtual void visit(Holder &)
Definition: peglib.h:1137
void visit(Option &ope) override
Definition: peglib.h:1189
const_iterator cbegin() const
Definition: peglib.h:2772
virtual void visit(Character &)
Definition: peglib.h:1131
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:966
parse_error()=default
std::shared_ptr< Ope > cls(const std::string &chars)
Definition: peglib.h:1595
void visit(Capture &ope) override
Definition: peglib.h:1739
const char * s_
Definition: peglib.h:1089
bool enablePackratParsing
Definition: peglib.h:1361
std::shared_ptr< Ope > ope_
Definition: peglib.h:892
std::string message
Definition: peglib.h:501
GLfloat GLfloat p
Definition: glext.h:9809
bool load_grammar(const char *s)
Definition: peglib.h:2371
const std::string token
Definition: peglib.h:2237
parse_error(const char *s)
Definition: peglib.h:461
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 idx
Definition: pixman-arm-neon-asm.h:96
GLenum GLenum GLvoid GLvoid * column
Definition: glext.h:6316
T & get()
Definition: peglib.h:101
bool is_token
Definition: peglib.h:1362
void visit(Sequence &ope) override
Definition: peglib.h:1687
const char * error_pos
Definition: peglib.h:499
std::string resolve_escape_sequence(const char *s, size_t n)
Definition: peglib.h:2120
Definition: peglib.h:1212
Definition: peglib.h:459
placeholder * clone() const
Definition: peglib.h:158
Result parse(const char *s, size_t n, any &dt, const char *path=nullptr) const
Definition: peglib.h:1286
void visit(ZeroOrMore &ope) override
Definition: peglib.h:1187
virtual void visit(OneOrMore &)
Definition: peglib.h:1125
match * operator->()
Definition: peglib.h:2725
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:1437
const char * s
Definition: peglib.h:2542
std::shared_ptr< Ope > opt(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1579
std::shared_ptr< Ope > tok(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1615
virtual placeholder * clone() const =0
parser(const char *s)
Definition: peglib.h:2352
Fty make_adaptor(F fn, R(*)(const SemanticValues &sv))
Definition: peglib.h:433
Grammar g
Definition: peglib.h:2157
void release()
Definition: peglib.h:190
Ignore(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1019
bool has_token_boundary
Definition: peglib.h:1363
void accept(Visitor &v) override
Definition: peglib.h:1538
virtual ~Ope()
Definition: peglib.h:617
std::shared_ptr< Ope > ope_
Definition: peglib.h:1032
const char * error_pos
Definition: peglib.h:1215
Capture(const std::shared_ptr< Ope > &ope, MatchAction ma, size_t id, const std::string &name)
Definition: peglib.h:982
bool is_digit(char c, int &v)
Definition: peglib.h:2092
bool execute_on_destruction
Definition: peglib.h:200
void accept(Ope::Visitor &v)
Definition: peglib.h:1345
void accept(Visitor &v) override
Definition: peglib.h:1531
static peg::AstBase< Annotation > empty
Definition: peglib.h:2241
bool fail(size_t len)
Definition: peglib.h:479
SemanticValues()
Definition: peglib.h:276
void ast_to_s_core(const std::shared_ptr< T > &ptr, std::string &s, int level, std::function< std::string(const T &ast, int level)> fn)
Definition: peglib.h:2258
std::shared_ptr< Ope > ope_
Definition: peglib.h:1013
std::map< size_t, std::vector< size_t > > indexed_captures() const
Definition: peglib.h:2620
void visit(WeakHolder &ope) override
Definition: peglib.h:1193
std::shared_ptr< Ope > whitespaceOpe
Definition: peglib.h:510
void accept(Visitor &v) override
Definition: peglib.h:1539
Result parse(const char *s, any &dt, const char *path=nullptr) const
Definition: peglib.h:1291
const GLdouble * v
Definition: glext.h:6391
bool in_whitespace
Definition: peglib.h:511
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:646
Definition & operator,(T fn)
Definition: peglib.h:1335
void visit(Sequence &ope) override
Definition: peglib.h:1177
Definition: peglib.h:1037
Definition: peglib.h:54
void visit(PrioritizedChoice &ope) override
Definition: peglib.h:1698
GLenum cap
Definition: glext.h:10546
bool load_grammar(const char *s, size_t n)
Definition: peglib.h:2359
std::string str() const
Definition: peglib.h:2548
bool parse(const char *s, any &dt, T &val, const char *=nullptr) const
Definition: peglib.h:2435
const_iterator cend() const
Definition: peglib.h:2776
Option(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:808
std::shared_ptr< Ope > lit(const std::string &lit)
Definition: peglib.h:1591
const char * s_
Definition: peglib.h:2750
placeholder * clone() const override
Definition: peglib.h:152
Definition: peglib.h:2297
u32 col
Definition: gx_regdef.h:5093
Definition: peglib.h:723
std::function< R(const SemanticValues &sv)> fn_
Definition: peglib.h:407
std::vector< size_t > named_capture(const std::string &name) const
Definition: peglib.h:2592
void visit(AndPredicate &ope) override
Definition: peglib.h:1719
Definition: peglib.h:979
GLboolean GLboolean g
Definition: glext.h:6844
std::vector< std::shared_ptr< SemanticValues > > value_stack
Definition: peglib.h:503
void accept(Visitor &v) override
Definition: peglib.h:1542
size_t size() const
Definition: peglib.h:2560
const_iterator end() const
Definition: peglib.h:2588
void accept(Visitor &v) override
Definition: peglib.h:1534
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:1101
void search()
Definition: peglib.h:2738
std::vector< size_t > indexed_capture(size_t id) const
Definition: peglib.h:2610
std::shared_ptr< Ope > npd(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1587
Tracer tracer
Definition: peglib.h:1364
Sequence(std::vector< std::shared_ptr< Ope >> &&opes)
Definition: peglib.h:644
virtual void visit(WeakHolder &)
Definition: peglib.h:1136
void visit(WeakHolder &ope) override
Definition: peglib.h:1748
std::shared_ptr< Ope > ope_
Definition: peglib.h:862
void operator=(F fn)
Definition: peglib.h:377
ZeroOrMore(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:726
void visit(WeakHolder &ope) override
Definition: peglib.h:1164
void accept(Visitor &v) override
Definition: peglib.h:1533
EF exit_function
Definition: peglib.h:199
parser(const char *s, size_t n)
Definition: peglib.h:2348
void accept(Visitor &v) override
Definition: peglib.h:1545
void visit(Ignore &ope) override
Definition: peglib.h:1745
std::shared_ptr< Ope > whitespaceOpe
Definition: peglib.h:1360
Definition(const Definition &rhs)
Definition: peglib.h:1227
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:1042
LiteralString(const std::string &s)
Definition: peglib.h:898
std::vector< Item >::iterator iterator
Definition: peglib.h:2553
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:985
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:689
size_t choice_
Definition: peglib.h:308
const char * c_str() const
Definition: peglib.h:243
auto make_scope_exit(EF &&exit_function) -> scope_exit< EF >
Definition: peglib.h:204
bool ret
Definition: peglib.h:1213
virtual void visit(DefinitionReference &)
Definition: peglib.h:1138
char ch_
Definition: peglib.h:960
void setup_actions()
Definition: peglib.h:1841
std::function< void(const char *s, size_t n, size_t id, const std::string &name)> MatchAction
Definition: peglib.h:470
any operator()(const SemanticValues &sv, any &)
Definition: peglib.h:404
Definition: peglib.h:1142
Definition: peglib.h:360
void visit(DefinitionReference &) override
Definition: peglib.h:1194
MatchAction match_action
Definition: peglib.h:2510
std::string s_
Definition: peglib.h:464
void visit(Option &ope) override
Definition: peglib.h:1158
Definition: peglib.h:2684
Definition: peglib.h:895
std::vector< bool > cache_registered
Definition: peglib.h:515
void visit(Ignore &ope) override
Definition: peglib.h:1192
std::string ast_to_s(const std::shared_ptr< T > &ptr, std::function< std::string(const T &ast, int level)> fn=nullptr)
Definition: peglib.h:2288
bool peg_search(const char *syntax, const char *s, match &m)
Definition: peglib.h:2678
any reduce(const SemanticValues &sv, any &dt) const
Definition: peglib.h:1502
virtual void visit(Ignore &)
Definition: peglib.h:1135
Definition: peglib.h:1072
any & operator=(const any &rhs)
Definition: peglib.h:68
Definition: peglib.h:150
GLsizei const GLfloat * value
Definition: glext.h:6709
std::shared_ptr< Ope > apd(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1583
size_t length() const
Definition: peglib.h:244
std::shared_ptr< Ope > ign(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1619
size_t length() const
Definition: peglib.h:2547
void visit(PrioritizedChoice &ope) override
Definition: peglib.h:1151
static const char * WHITESPACE_DEFINITION_NAME
Definition: peglib.h:1204
auto transform(F f) const -> vector< typename std::remove_const< decltype(f(any()))>::type >
Definition: peglib.h:311
bool has_token_boundary
Definition: peglib.h:1200
Definition: Common.h:43
Definition: peglib.h:1016
const unsigned int tag
Definition: peglib.h:2232
void accept(Visitor &v) override
Definition: peglib.h:1543
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:764
parser & enable_ast()
Definition: peglib.h:2477
size_t n_
Definition: peglib.h:307
DetectLeftRecursion(const std::string &name)
Definition: peglib.h:1682
const bool is_token
Definition: peglib.h:2236
Definition: peglib.h:963
peg_token_iterator(const char *syntax, const char *s)
Definition: peglib.h:2692
const char * message_pos
Definition: peglib.h:500
GLuint GLuint end
Definition: glext.h:6292
peg_token_iterator operator++(int)
Definition: peglib.h:2715
bool parse_n(const char *s, size_t n, T &val, const char *path=nullptr) const
Definition: peglib.h:2407
std::map< std::string, std::vector< size_t > > named_captures() const
Definition: peglib.h:2602
void visit(NotPredicate &ope) override
Definition: peglib.h:1160
#define false
Definition: ordinals.h:83
Context(const char *a_path, const char *a_s, size_t a_l, size_t a_def_count, std::shared_ptr< Ope > a_whitespaceOpe, bool a_enablePackratParsing, Tracer a_tracer)
Definition: peglib.h:522
CharacterClass(const std::string &chars)
Definition: peglib.h:910
std::unordered_map< void *, size_t > ids
Definition: peglib.h:1168
std::shared_ptr< Ope > chr(char dt)
Definition: peglib.h:1599
void operator=(F)
Definition: peglib.h:387
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:8390
void set_error_pos(const char *a_s)
Definition: peglib.h:600
MatchAction match_action_
Definition: peglib.h:999
virtual ~Visitor()
Definition: peglib.h:1121
virtual void visit(AnyCharacter &)
Definition: peglib.h:1132
void visit(Option &ope) override
Definition: peglib.h:1715
#define true
Definition: ordinals.h:82
Definition: peglib.h:1667
Definition: peglib.h:612
SemanticValues & push()
Definition: peglib.h:579
std::vector< bool > cache_success
Definition: peglib.h:516
virtual void accept(Visitor &v)=0
Sequence(const std::vector< std::shared_ptr< Ope >> &opes)
Definition: peglib.h:643
Result parse_and_get_value(const char *s, size_t n, any &dt, T &val, const char *path=nullptr) const
Definition: peglib.h:1314
Fty make_adaptor(F fn, R(F::*)(const SemanticValues &sv))
Definition: peglib.h:428
#define F(x, y, z)
uint8_t u8
8bit unsigned integer
Definition: gctypes.h:17
virtual void visit(LiteralString &)
Definition: peglib.h:1129
Result parse_and_get_value(const char *s, any &dt, T &val, const char *path=nullptr) const
Definition: peglib.h:1324
Definition: peglib.h:1209
Definition: peglib.h:411
std::vector< std::shared_ptr< Ope > > opes_
Definition: peglib.h:664
bool parse_n(const char *s, size_t n, any &dt, const char *path=nullptr) const
Definition: peglib.h:2391
any()
Definition: peglib.h:57
std::shared_ptr< Ope > ope_
Definition: peglib.h:996
size_t id
Definition: peglib.h:2544
Definition: peglib.h:1119
void * enabler
Definition: peglib.h:236
std::function< void(any &dt)> leave
Definition: peglib.h:1357
void visit(Capture &ope) override
Definition: peglib.h:1161
void accept(Visitor &v) override
Definition: peglib.h:1529
Context contains the render state used by various components.
Definition: Context.h:26
GLdouble n
Definition: glext.h:8396
size_t capture_count
Definition: peglib.h:1673
std::function< std::string()> error_message
Definition: peglib.h:1358
any call(F fn, Args &&... args)
Definition: peglib.h:337
const GLfloat * m
Definition: glext.h:11755
void enable_packrat_parsing()
Definition: peglib.h:2469
std::unordered_map< std::string, Definition > Grammar
Definition: peglib.h:1635
Definition(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1250
#define is_digit(c)
Definition: kprintf.c:17
Result parse(const char *s, size_t n, const char *path=nullptr) const
Definition: peglib.h:1275
Definition: peglib.h:1054
Definition: peglib.h:144
bool has_rule
Definition: peglib.h:1201
const char *const str
Definition: portlistingparse.c:18
void accept(Visitor &v) override
Definition: peglib.h:1541
const std::string path
Definition: peglib.h:2225
void visit(DefinitionReference &ope) override
Definition: peglib.h:1754
virtual void visit(AndPredicate &)
Definition: peglib.h:1127
any operator()(const SemanticValues &sv, any &dt) const
Definition: peglib.h:395
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6844
bool peg_match(const char *syntax, const char *s)
Definition: peglib.h:2646
auto transform(size_t beg, size_t end, F f) const -> vector< typename std::remove_const< decltype(f(any()))>::type >
Definition: peglib.h:320
const char * s_
Definition: peglib.h:306
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:1393
TypeAdaptor_c(std::function< R(const SemanticValues &sv, any &dt)> fn)
Definition: peglib.h:412
std::string start_
Definition: peglib.h:2532
std::pair< char, size_t > parse_hex_number(const char *s, size_t n, size_t i)
Definition: peglib.h:2100
std::weak_ptr< Ope > weak_
Definition: peglib.h:1051
MatchAction match_action
Definition: peglib.h:1670
Action action
Definition: peglib.h:1355
const char * path
Definition: peglib.h:495
Definition: peglib.h:2343
any(any &&rhs)
Definition: peglib.h:61
Definition: peglib.h:805
size_t parse(const char *s, size_t n, SemanticValues &sv, Context &c, any &dt) const override
Definition: peglib.h:1418
WeakHolder(const std::shared_ptr< Ope > &ope)
Definition: peglib.h:1040
Fty make_adaptor(F fn, R(F::*)(const SemanticValues &sv, any &dt))
Definition: peglib.h:443
Definition: peglib.h:42