dsl/token.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_TOKEN_HPP_INCLUDED
5 #define LEXY_DSL_TOKEN_HPP_INCLUDED
6 
7 #include <lexy/action/match.hpp>
8 #include <lexy/dsl/base.hpp>
9 #include <lexy/error.hpp>
10 
11 namespace lexy
12 {
14 {
15  static LEXY_CONSTEVAL auto name()
16  {
17  return "missing token";
18  }
19 };
20 } // namespace lexy
21 
22 //=== token_base ===//
23 namespace lexyd
24 {
25 template <typename Tag, typename Token>
26 struct _toke;
27 template <auto Kind, typename Token>
28 struct _tokk;
29 
30 template <typename ImplOrTag, bool IsImpl = lexy::is_token_rule<ImplOrTag>>
32 template <typename Impl>
33 struct _token_inherit<Impl, true> : Impl // no need to inherit from _token_base
34 {};
35 template <typename Tag>
36 struct _token_inherit<Tag, false> : _token_base, Tag // need to turn it into a token
37 {};
38 
39 // ImplOrTag is either a branch base that indicates whether the token is an unconditional branch,
40 // or an actual token rule whose implementation will be used.
41 template <typename Derived, typename ImplOrTag = branch_base>
42 struct token_base : _token_inherit<ImplOrTag>
43 {
44  using token_type = Derived;
45 
46  template <typename Reader>
47  struct bp
48  {
49  typename Reader::marker end;
50 
51  constexpr auto try_parse(const void*, const Reader& reader)
52  {
54  auto result = parser.try_parse(reader);
55  end = parser.end;
56  return result;
57  }
58 
59  template <typename Context>
60  constexpr void cancel(Context&)
61  {}
62 
63  template <typename NextParser, typename Context, typename... Args>
64  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
65  {
66  context.on(_ev::token{}, Derived{}, reader.position(), end.position());
67  reader.reset(end);
69  LEXY_FWD(args)...);
70  }
71  };
72 
73  template <typename Context, typename Reader>
74  LEXY_PARSER_FUNC static bool token_parse(Context& context, Reader& reader)
75  {
76  auto begin = reader.position();
78 
79  using try_parse_result = decltype(parser.try_parse(reader));
80  if constexpr (std::is_same_v<try_parse_result, std::true_type>)
81  {
82  parser.try_parse(reader);
83  }
84  else
85  {
86  if (!parser.try_parse(reader))
87  {
88  context.on(_ev::token{}, lexy::error_token_kind, reader.position(),
89  parser.end.position());
90  parser.report_error(context, reader);
91  reader.reset(parser.end);
92 
93  return false;
94  }
95  }
96 
97  context.on(_ev::token{}, typename Derived::token_type{}, begin, parser.end.position());
98  reader.reset(parser.end);
99 
100  return true;
101  }
102 
103  template <typename NextParser>
104  struct p
105  {
106  template <typename Context, typename Reader, typename... Args>
107  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
108  {
109  if (!token_parse(context, reader))
110  return false;
111  else
113  LEXY_FWD(args)...);
114  }
115  };
116 
117  //=== dsl ===//
118  template <typename Tag>
120 
121  template <auto Kind>
123 };
124 
125 // We forward all implementation to Token.
126 // We cannot directly inherit from Token as that wouldn't override the token_type.
127 template <auto Kind, typename Token>
128 struct _tokk : token_base<_tokk<Kind, Token>, Token>
129 {};
130 
131 template <typename Tag, typename Token>
132 struct _toke : token_base<_toke<Tag, Token>, Token>
133 {
134  // If we're overriding the error for a char class rule, we also want to change its error
135  // reporting. Otherwise, rules such as `dsl::delimited()` building on char classes will generate
136  // the "wrong" error.
137  //
138  // If it's not a char class, adding this function doesn't hurt.
139  template <typename Reader, typename Context>
140  static constexpr void char_class_report_error(Context& context,
141  typename Reader::iterator position)
142  {
144  context.on(_ev::error{}, err);
145  }
146 
147  template <typename Reader>
148  struct tp : lexy::token_parser_for<Token, Reader>
149  {
150  constexpr explicit tp(const Reader& reader) : lexy::token_parser_for<Token, Reader>(reader)
151  {}
152 
153  template <typename Context>
154  constexpr void report_error(Context& context, const Reader& reader)
155  {
156  // Report a different error.
157  auto err = lexy::error<Reader, Tag>(reader.position(), this->end.position());
158  context.on(_ev::error{}, err);
159  }
160  };
161 };
162 } // namespace lexyd
163 
164 namespace lexy
165 {
166 template <auto Kind, typename Token>
167 constexpr auto token_kind_of<lexy::dsl::_tokk<Kind, Token>> = Kind;
168 template <typename Tag, typename Token>
169 constexpr auto token_kind_of<lexy::dsl::_toke<Tag, Token>> = token_kind_of<Token>;
170 } // namespace lexy
171 
172 //=== token rule ===//
173 namespace lexyd
174 {
175 template <typename Rule>
176 struct _token : token_base<_token<Rule>>
177 {
178  struct _production
179  {
180  static constexpr auto name = "<token>";
181  static constexpr auto max_recursion_depth = 0;
182  static constexpr auto rule = Rule{};
183  };
184 
185  template <typename Reader>
186  struct tp
187  {
188  typename Reader::marker end;
189 
190  constexpr explicit tp(const Reader& reader) : end(reader.current()) {}
191 
192  constexpr bool try_parse(Reader reader)
193  {
194  // We match a dummy production that only consists of the rule.
195  auto success = lexy::do_action<
196  _production,
199  reader);
200  end = reader.current();
201  return success;
202  }
203 
204  template <typename Context>
205  constexpr void report_error(Context& context, const Reader& reader)
206  {
207  auto err = lexy::error<Reader, lexy::missing_token>(reader.position(), end.position());
208  context.on(_ev::error{}, err);
209  }
210  };
211 };
212 
214 template <typename Rule>
215 constexpr auto token(Rule)
216 {
217  if constexpr (lexy::is_token_rule<Rule>)
218  return Rule{};
219  else
220  return _token<Rule>{};
221 }
222 } // namespace lexyd
223 
224 #endif // LEXY_DSL_TOKEN_HPP_INCLUDED
225 
lexyd::position
constexpr auto position
Produces an iterator to the current reader position without parsing anything.
Definition: position.hpp:79
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::token_base::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: dsl/token.hpp:107
lexyd::_token::tp
Definition: dsl/token.hpp:186
lexyd::_token::_production::max_recursion_depth
static constexpr auto max_recursion_depth
Definition: dsl/token.hpp:181
lexyd::_toke
Definition: dsl/token.hpp:26
lexyd::_token_inherit
Definition: dsl/token.hpp:31
lexyd::_token::tp::try_parse
constexpr bool try_parse(Reader reader)
Definition: dsl/token.hpp:192
lexyd::token_base::token_parse
static LEXY_PARSER_FUNC bool token_parse(Context &context, Reader &reader)
Definition: dsl/token.hpp:74
lexy::no_parse_state
constexpr void * no_parse_state
Definition: action/base.hpp:198
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexyd::token_base::error
static constexpr _toke< Tag, Derived > error
Definition: dsl/token.hpp:119
lexy::missing_token
Definition: dsl/token.hpp:13
lexy
Definition: any_ref.hpp:12
lexyd::_toke::tp::tp
constexpr tp(const Reader &reader)
Definition: dsl/token.hpp:150
lexy::missing_token::name
static LEXY_CONSTEVAL auto name()
Definition: dsl/token.hpp:15
lexyd::token_base::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: dsl/token.hpp:64
lexyd::_token::tp::end
Reader::marker end
Definition: dsl/token.hpp:188
lexy::error
Generic failure.
Definition: error.hpp:14
lexyd::_token
Definition: dsl/token.hpp:176
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_token::_production::name
static constexpr auto name
Definition: dsl/token.hpp:180
lexyd::token_base
Definition: dsl/token.hpp:42
lexy::_detail::automatic_ws_parser::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: whitespace.hpp:178
match.hpp
lexyd::_token::_production
Definition: dsl/token.hpp:178
lexyd::token_base::p
Definition: dsl/token.hpp:104
lexyd::token_base::kind
static constexpr _tokk< Kind, Derived > kind
Definition: dsl/token.hpp:122
lexy::error_token_kind
@ error_token_kind
Definition: grammar.hpp:86
lexyd::_toke::tp::report_error
constexpr void report_error(Context &context, const Reader &reader)
Definition: dsl/token.hpp:154
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:108
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexyd::_token::_production::rule
static constexpr auto rule
Definition: dsl/token.hpp:182
lexyd::_token_base
Definition: grammar.hpp:26
lexyd::_toke::char_class_report_error
static constexpr void char_class_report_error(Context &context, typename Reader::iterator position)
Definition: dsl/token.hpp:140
lexyd::token_base::bp::end
Reader::marker end
Definition: dsl/token.hpp:49
base.hpp
lexyd::token_base::bp
Definition: dsl/token.hpp:47
lexy::parse_events::token
Definition: dsl/base.hpp:57
lexy::match_action
Definition: match.hpp:48
lexyd::_toke::tp
Definition: dsl/token.hpp:148
lexyd::_tokk
Definition: dsl/token.hpp:28
lexyd::_token::tp::tp
constexpr tp(const Reader &reader)
Definition: dsl/token.hpp:190
lexy::do_action
constexpr auto do_action(Handler &&handler, State *state, Reader &reader)
Definition: action/base.hpp:228
lexy::token_parser_for
typename TokenRule::template tp< Reader > token_parser_for
Definition: dsl/base.hpp:242
lexyd
Definition: trace.hpp:22
lexyd::token_base::bp::cancel
constexpr void cancel(Context &)
Definition: dsl/token.hpp:60
lexyd::token_base::bp::try_parse
constexpr auto try_parse(const void *, const Reader &reader)
Definition: dsl/token.hpp:51
lexyd::_token::tp::report_error
constexpr void report_error(Context &context, const Reader &reader)
Definition: dsl/token.hpp:205
lexy::_mh
Definition: match.hpp:11
lexyd::token_base< _xid_start >::token_type
_xid_start token_type
Definition: dsl/token.hpp:44
error.hpp


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