peek.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2024 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DSL_PEEK_HPP_INCLUDED
5 #define LEXY_DSL_PEEK_HPP_INCLUDED
6 
7 #include <lexy/dsl/base.hpp>
8 #include <lexy/dsl/token.hpp>
9 
10 namespace lexy
11 {
14 {
15  static LEXY_CONSTEVAL auto name()
16  {
17  return "peek failure";
18  }
19 };
20 
22 struct unexpected
23 {
24  static LEXY_CONSTEVAL auto name()
25  {
26  return "unexpected";
27  }
28 };
29 } // namespace lexy
30 
31 namespace lexyd
32 {
33 template <typename Rule, typename Tag>
35 {
36  template <typename Reader>
37  struct bp
38  {
39  typename Reader::iterator begin;
40  typename Reader::marker end;
41 
42  constexpr bool try_parse(const void*, Reader reader)
43  {
44  // We need to match the entire rule.
45  lexy::token_parser_for<decltype(lexy::dsl::token(Rule{})), Reader> parser(reader);
46 
47  begin = reader.position();
48  auto result = parser.try_parse(reader);
49  end = parser.end;
50 
51  return result;
52  }
53 
54  template <typename Context>
55  constexpr void cancel(Context& context)
56  {
57  context.on(_ev::backtracked{}, begin, end.position());
58  }
59 
60  template <typename NextParser, typename Context, typename... Args>
61  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
62  {
63  context.on(_ev::backtracked{}, begin, end.position());
64  return NextParser::parse(context, reader, LEXY_FWD(args)...);
65  }
66  };
67 
68  template <typename NextParser>
69  struct p
70  {
71  template <typename Context, typename Reader, typename... Args>
72  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
73  {
74  bp<Reader> impl{};
75  if (!impl.try_parse(context.control_block, reader))
76  {
77  // Report that we've failed.
79  auto err = lexy::error<Reader, tag>(impl.begin, impl.end.position());
80  context.on(_ev::error{}, err);
81 
82  // But recover immediately, as we wouldn't have consumed anything either way.
83  }
84 
85  context.on(_ev::backtracked{}, impl.begin, impl.end.position());
86  return NextParser::parse(context, reader, LEXY_FWD(args)...);
87  }
88  };
89 
90  template <typename Error>
91  static constexpr _peek<Rule, Error> error = {};
92 };
93 
94 template <typename Rule, typename Tag>
96 {
97  template <typename Reader>
98  struct bp
99  {
100  typename Reader::iterator begin;
101  typename Reader::marker end;
102 
103  constexpr bool try_parse(const void*, Reader reader)
104  {
105  // We must not match the rule.
106  lexy::token_parser_for<decltype(lexy::dsl::token(Rule{})), Reader> parser(reader);
107 
108  begin = reader.position();
109  auto result = !parser.try_parse(reader);
110  end = parser.end;
111 
112  return result;
113  }
114 
115  template <typename Context>
116  constexpr void cancel(Context& context)
117  {
118  context.on(_ev::backtracked{}, begin, end.position());
119  }
120 
121  template <typename NextParser, typename Context, typename... Args>
122  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
123  {
124  context.on(_ev::backtracked{}, begin, end.position());
125  return NextParser::parse(context, reader, LEXY_FWD(args)...);
126  }
127  };
128 
129  template <typename NextParser>
130  struct p
131  {
132  template <typename Context, typename Reader, typename... Args>
133  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
134  {
135  bp<Reader> impl{};
136  if (!impl.try_parse(context.control_block, reader))
137  {
138  // Report that we've failed.
140  auto err = lexy::error<Reader, tag>(impl.begin, impl.end.position());
141  context.on(_ev::error{}, err);
142 
143  // And recover by consuming the input.
144  context.on(_ev::recovery_start{}, impl.begin);
145  context.on(_ev::token{}, lexy::error_token_kind, impl.begin, impl.end.position());
146  context.on(_ev::recovery_finish{}, impl.end.position());
147 
148  reader.reset(impl.end);
149  return NextParser::parse(context, reader, LEXY_FWD(args)...);
150  }
151  else
152  {
153  context.on(_ev::backtracked{}, impl.begin, impl.end.position());
154  return NextParser::parse(context, reader, LEXY_FWD(args)...);
155  }
156  }
157  };
158 
159  template <typename Error>
160  static constexpr _peekn<Rule, Error> error = {};
161 };
162 
165 template <typename Rule>
166 constexpr auto peek(Rule)
167 {
168  return _peek<Rule, void>{};
169 }
170 
172 template <typename Rule>
173 constexpr auto peek_not(Rule)
174 {
175  return _peekn<Rule, void>{};
176 }
177 } // namespace lexyd
178 
179 #endif // LEXY_DSL_PEEK_HPP_INCLUDED
180 
lexyd::peek_not
constexpr auto peek_not(Rule)
Checks if at this reader position, the rule would not match.
Definition: peek.hpp:173
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:98
lexyd::token
constexpr auto token(Rule)
Turns the arbitrary rule into a token by matching it without producing any values.
Definition: dsl/token.hpp:215
lexyd::branch_base
Definition: grammar.hpp:20
lexy::parse_events::recovery_start
Definition: dsl/base.hpp:74
lexyd::peek
constexpr auto peek(Rule)
Definition: peek.hpp:166
token.hpp
lexyd::_peekn::bp::end
Reader::marker end
Definition: peek.hpp:101
lexyd::_peekn::bp::try_parse
constexpr bool try_parse(const void *, Reader reader)
Definition: peek.hpp:103
lexyd::_peek::error
static constexpr _peek< Rule, Error > error
Definition: peek.hpp:91
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexy::_detail::type_or
std::conditional_t< std::is_void_v< T >, Fallback, T > type_or
Definition: config.hpp:64
lexy::peek_failure
We've failed to match a peek.
Definition: peek.hpp:13
lexyd::_peek::bp::try_parse
constexpr bool try_parse(const void *, Reader reader)
Definition: peek.hpp:42
lexy
Definition: any_ref.hpp:12
lexyd::_peekn
Definition: peek.hpp:95
lexyd::_peek::p
Definition: peek.hpp:69
lexyd::_peekn::bp
Definition: peek.hpp:98
lexy::error
Generic failure.
Definition: error.hpp:14
lexy::parse_events::backtracked
Definition: dsl/base.hpp:63
lexy::parse
constexpr auto parse(const Input &input, const ErrorCallback &callback)
Parses the production into a value, invoking the callback on error.
Definition: parse.hpp:171
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_peek
Definition: peek.hpp:34
lexyd::_peekn::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: peek.hpp:133
lexyd::_peekn::error
static constexpr _peekn< Rule, Error > error
Definition: peek.hpp:160
lexyd::_peek::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: peek.hpp:72
lexyd::_peekn::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: peek.hpp:122
lexyd::_peek::bp
Definition: peek.hpp:37
lexy::unexpected
We've failed to match a peek not.
Definition: peek.hpp:22
lexyd::_peekn::bp::cancel
constexpr void cancel(Context &context)
Definition: peek.hpp:116
lexyd::_peek::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: peek.hpp:61
lexy::error_token_kind
@ error_token_kind
Definition: grammar.hpp:86
lexyd::_peekn::p
Definition: peek.hpp:130
lexy::parse_events::recovery_finish
Definition: dsl/base.hpp:79
lexy::unexpected::name
static LEXY_CONSTEVAL auto name()
Definition: peek.hpp:24
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:108
lexy::peek_failure::name
static LEXY_CONSTEVAL auto name()
Definition: peek.hpp:15
lexyd::_peek::bp::cancel
constexpr void cancel(Context &context)
Definition: peek.hpp:55
lexyd::_peekn::bp::begin
Reader::iterator begin
Definition: peek.hpp:100
base.hpp
lexy::parse_events::token
Definition: dsl/base.hpp:57
lexyd::_peek::bp::end
Reader::marker end
Definition: peek.hpp:40
lexy::token_parser_for
typename TokenRule::template tp< Reader > token_parser_for
Definition: dsl/base.hpp:242
lexyd
Definition: trace.hpp:22
lexyd::_peek::bp::begin
Reader::iterator begin
Definition: peek.hpp:39


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