parse_tree_node.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_PARSE_TREE_NODE_HPP_INCLUDED
5 #define LEXY_DSL_PARSE_TREE_NODE_HPP_INCLUDED
6 
7 #include <lexy/dsl/base.hpp>
8 #include <lexy/dsl/token.hpp>
9 
10 #if !LEXY_EXPERIMENTAL
11 # error "lexy::dsl::tnode/pnode are experimental"
12 #endif
13 
14 //=== impl ===//
15 namespace lexyd
16 {
17 template <typename Derived>
18 struct _n;
19 
20 template <typename Derived, typename R>
21 struct _nr : branch_base
22 {
23  template <typename NextParser>
24  struct _cont
25  {
26  template <typename Context, typename ChildReader, typename Reader, typename... Args>
27  LEXY_PARSER_FUNC static bool parse(Context& context, ChildReader& child_reader,
28  bool& rule_succeded, Reader& reader, Args&&... args)
29  {
30  rule_succeded = true;
31 
32  if (child_reader.peek() != ChildReader::encoding::eof())
33  {
34  auto begin = child_reader.position();
35  auto end = reader.position();
36  context.on(_ev::token{}, lexy::error_token_kind, begin, end);
37 
39  context.on(_ev::error{}, err);
40  }
41 
43  LEXY_FWD(args)...);
44  }
45  };
46 
47  template <typename NextParser, typename Context, typename Reader, typename... Args>
48  LEXY_PARSER_FUNC static bool _parse_rule(Context& context, Reader& reader,
49  typename Reader::marker end, Args&&... args)
50  {
51  auto child_reader = Derived::node_child_reader(reader);
52  reader.reset(end);
53 
54  using rule_parser
56  if (auto rule_succeded = false;
57  rule_parser::parse(context, child_reader, rule_succeded, reader, LEXY_FWD(args)...))
58  {
59  return true;
60  }
61  else
62  {
63  if (!rule_succeded)
64  // Report an error token for the child span that wasn't able to be parsed.
65  context.on(_ev::token{}, lexy::error_token_kind, child_reader.position(),
66  end.position());
67  return false;
68  }
69  }
70 
71  template <typename Reader>
72  struct bp
73  {
74  typename Reader::marker end;
75 
76  constexpr bool try_parse(const void*, const Reader& reader)
77  {
78  lexy::token_parser_for<_n<Derived>, Reader> parser(reader);
79  auto result = parser.try_parse(reader);
80  end = parser.end;
81  return result;
82  }
83 
84  template <typename Context>
85  constexpr void cancel(Context&)
86  {}
87 
88  template <typename NextParser, typename Context, typename... Args>
89  LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
90  {
91  return _parse_rule<NextParser>(context, reader, end, LEXY_FWD(args)...);
92  }
93  };
94 
95  template <typename NextParser>
96  struct p
97  {
98  template <typename Context, typename Reader, typename... Args>
99  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
100  {
101  lexy::token_parser_for<_n<Derived>, Reader> parser(reader);
102  if (!parser.try_parse(reader))
103  {
104  LEXY_ASSERT(parser.end.position() == reader.position(), "impl should be LL(1)");
105  parser.report_error(context, reader);
106  return false;
107  }
108 
109  return _parse_rule<NextParser>(context, reader, parser.end, LEXY_FWD(args)...);
110  }
111  };
112 };
113 
114 template <typename Derived>
115 struct _n : token_base<Derived>
116 {
117  template <typename Reader>
118  struct tp
119  {
120  typename Reader::marker end;
121 
122  constexpr explicit tp(const Reader& reader) : end(reader.current()) {}
123 
124  constexpr auto try_parse(Reader reader)
125  {
126  if constexpr (lexy::is_node_encoding<typename Reader::encoding>)
127  {
128  if (!Reader::encoding::match(reader.peek(), Derived::node_kind()))
129  return false;
130 
131  reader.bump();
132  end = reader.current();
133  return true;
134  }
135  else
136  {
137  // This happens when it is used as whitespace, which is inherited while parsing the
138  // token lexeme, we don't match anything in that case.
139  return std::false_type{};
140  }
141  }
142 
143  template <typename Context>
144  constexpr void report_error(Context& context, Reader reader)
145  {
146  constexpr auto name = Derived::node_kind_name();
147 
148  auto err = lexy::error<Reader, lexy::expected_char_class>(reader.position(), name);
149  context.on(_ev::error{}, err);
150  }
151  };
152 
153  template <typename Rule>
154  constexpr auto operator()(Rule) const
155  {
156  return _nr<Derived, Rule>{};
157  }
158 };
159 } // namespace lexyd
160 
161 //=== dsl::tnode ===//
162 namespace lexy
163 {
165 {
166  static LEXY_CONSTEVAL auto name()
167  {
168  return "expected token end";
169  }
170 };
171 } // namespace lexy
172 
173 namespace lexyd
174 {
175 template <auto Kind>
176 struct _tn : _n<_tn<Kind>>
177 {
178  static LEXY_CONSTEVAL auto node_kind()
179  {
180  return Kind;
181  }
182 
184  {
185  using lexy::token_kind_name;
186  return token_kind_name(Kind);
187  }
188 
190 
191  template <typename Reader>
192  static constexpr auto node_child_reader(Reader& reader)
193  {
194  return reader.lexeme_reader();
195  }
196 };
197 
198 template <auto Kind>
199 constexpr auto tnode = _tn<Kind>{};
200 } // namespace lexyd
201 
202 namespace lexy
203 {
204 template <auto Kind>
205 constexpr auto token_kind_of<lexy::dsl::_tn<Kind>> = Kind;
206 } // namespace lexy
207 
208 //=== dsl::pnode ===//
209 namespace lexy
210 {
212 {
213  static LEXY_CONSTEVAL auto name()
214  {
215  return "expected production end";
216  }
217 };
218 } // namespace lexy
219 
220 namespace lexyd
221 {
222 template <typename Production>
223 struct _pn : _n<_pn<Production>>
224 {
225  static_assert(lexy::is_production<Production>);
226 
227  static LEXY_CONSTEVAL auto node_kind()
228  {
229  return Production{};
230  }
231 
233  {
234  return lexy::production_name<Production>();
235  }
236 
238 
239  template <typename Reader>
240  static constexpr auto node_child_reader(Reader& reader)
241  {
242  return reader.child_reader();
243  }
244 };
245 
246 template <typename Production>
247 constexpr auto pnode = _pn<Production>{};
248 } // namespace lexyd
249 
250 #endif // LEXY_DSL_PARSE_TREE_NODE_HPP_INCLUDED
251 
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:98
lexyd::branch_base
Definition: grammar.hpp:20
lexyd::tnode
constexpr auto tnode
Definition: parse_tree_node.hpp:199
lexyd::_nr::_parse_rule
static LEXY_PARSER_FUNC bool _parse_rule(Context &context, Reader &reader, typename Reader::marker end, Args &&... args)
Definition: parse_tree_node.hpp:48
token.hpp
lexyd::_nr::p
Definition: parse_tree_node.hpp:96
lexy::expected_production_end::name
static LEXY_CONSTEVAL auto name()
Definition: parse_tree_node.hpp:213
lexyd::_pn::node_kind
static LEXY_CONSTEVAL auto node_kind()
Definition: parse_tree_node.hpp:227
lexyd::_n::tp::report_error
constexpr void report_error(Context &context, Reader reader)
Definition: parse_tree_node.hpp:144
lexyd::_nr::bp::cancel
constexpr void cancel(Context &)
Definition: parse_tree_node.hpp:85
lexyd::_pn::node_kind_name
static LEXY_CONSTEVAL auto node_kind_name()
Definition: parse_tree_node.hpp:232
lexyd::_nr::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: parse_tree_node.hpp:99
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexyd::_pn::node_child_reader
static constexpr auto node_child_reader(Reader &reader)
Definition: parse_tree_node.hpp:240
lexyd::_nr
Definition: parse_tree_node.hpp:21
lexy
Definition: any_ref.hpp:12
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
lexy::error
Generic failure.
Definition: error.hpp:14
lexyd::_nr::_cont::parse
static LEXY_PARSER_FUNC bool parse(Context &context, ChildReader &child_reader, bool &rule_succeded, Reader &reader, Args &&... args)
Definition: parse_tree_node.hpp:27
lexy::parse
constexpr auto parse(const Input &input, const ErrorCallback &callback)
Parses the production into a value, invoking the callback on error.
Definition: parse.hpp:171
lexyd::_n
Definition: parse_tree_node.hpp:18
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_n::tp::end
Reader::marker end
Definition: parse_tree_node.hpp:120
lexyd::_nr::_cont
Definition: parse_tree_node.hpp:24
lexy::_detail::automatic_ws_parser::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: whitespace.hpp:178
lexyd::_nr::bp
Definition: parse_tree_node.hpp:72
lexy::token_kind_name
constexpr const char * token_kind_name(const T &) noexcept
Definition: grammar.hpp:101
lexy::error_token_kind
@ error_token_kind
Definition: grammar.hpp:86
lexyd::_pn
Definition: parse_tree_node.hpp:223
lexyd::_nr::bp::end
Reader::marker end
Definition: parse_tree_node.hpp:74
lexyd::_tn::node_kind_name
static LEXY_CONSTEVAL auto node_kind_name()
Definition: parse_tree_node.hpp:183
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
lexy::whitespace_parser
Definition: dsl/base.hpp:229
lexyd::_nr::bp::finish
LEXY_PARSER_FUNC bool finish(Context &context, Reader &reader, Args &&... args)
Definition: parse_tree_node.hpp:89
base.hpp
lexy::parse_events::token
Definition: dsl/base.hpp:57
lexyd::_n::tp::tp
constexpr tp(const Reader &reader)
Definition: parse_tree_node.hpp:122
lexyd::_n::tp::try_parse
constexpr auto try_parse(Reader reader)
Definition: parse_tree_node.hpp:124
lexyd::_tn
Definition: parse_tree_node.hpp:176
lexyd::_n::operator()
constexpr auto operator()(Rule) const
Definition: parse_tree_node.hpp:154
lexy::match
constexpr bool match(const Input &input)
Definition: match.hpp:73
lexyd::_n::tp
Definition: parse_tree_node.hpp:118
lexy::expected_production_end
Definition: parse_tree_node.hpp:211
lexy::expected_token_end::name
static LEXY_CONSTEVAL auto name()
Definition: parse_tree_node.hpp:166
lexyd::pnode
constexpr auto pnode
Definition: parse_tree_node.hpp:247
lexyd::_tn::node_kind
static LEXY_CONSTEVAL auto node_kind()
Definition: parse_tree_node.hpp:178
lexy::token_parser_for
typename TokenRule::template tp< Reader > token_parser_for
Definition: dsl/base.hpp:242
lexyd::_tn::node_child_reader
static constexpr auto node_child_reader(Reader &reader)
Definition: parse_tree_node.hpp:192
lexy::expected_token_end
Definition: parse_tree_node.hpp:164
lexyd
Definition: trace.hpp:22
lexyd::eof
constexpr auto eof
Matches EOF.
Definition: eof.hpp:72
LEXY_ASSERT
#define LEXY_ASSERT(Expr, Msg)
Definition: assert.hpp:37
lexyd::_nr::bp::try_parse
constexpr bool try_parse(const void *, const Reader &reader)
Definition: parse_tree_node.hpp:76


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