parse_as_tree.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_ACTION_PARSE_AS_TREE_HPP_INCLUDED
5 #define LEXY_ACTION_PARSE_AS_TREE_HPP_INCLUDED
6 
7 #include <lexy/action/base.hpp>
9 #include <lexy/dsl/any.hpp>
10 #include <lexy/parse_tree.hpp>
11 
12 namespace lexy
13 {
14 template <typename Tree, typename Reader>
15 class _pth
16 {
17 public:
18  template <typename Input, typename Sink>
19  explicit _pth(Tree& tree, const _detail::any_holder<const Input*>& input,
21  : _tree(&tree), _depth(0), _validate(input, sink)
22  {}
23 
25  {
26  using iterator = typename Reader::iterator;
27 
28  public:
30 
32  {
33  LEXY_PRECONDITION(handler._depth == 0);
34 
35  handler._builder.emplace(LEXY_MOV(*handler._tree), _validate.get_info());
36  }
37  void on(_pth& handler, parse_events::grammar_finish, Reader& reader)
38  {
39  LEXY_PRECONDITION(handler._depth == 0);
40 
41  auto begin = reader.position();
43  auto end = reader.position();
44 
45  *handler._tree = LEXY_MOV(*handler._builder).finish({begin, end});
46  }
47  void on(_pth& handler, parse_events::grammar_cancel, Reader&)
48  {
49  LEXY_PRECONDITION(handler._depth == 0);
50 
51  handler._tree->clear();
52  }
53 
55  {
56  if (handler._depth++ > 0)
57  _marker = handler._builder->start_production(_validate.get_info());
58 
59  _validate.on(handler._validate, ev, pos);
60  }
61 
63  {
64  if (--handler._depth > 0)
65  {
66  if (handler._builder->current_child_count() == 0)
67  handler._builder->token(lexy::position_token_kind, _validate.production_begin(),
68  _validate.production_begin());
69  handler._builder->finish_production(LEXY_MOV(_marker));
70  }
71 
72  _validate.on(handler._validate, ev, pos);
73  }
74 
76  {
77  if (--handler._depth > 0)
78  {
79  // Cancelling the production removes all nodes from the tree.
80  // To ensure that the parse tree remains lossless, we add everything consumed by it
81  // as an error token.
82  handler._builder->cancel_production(LEXY_MOV(_marker));
83  handler._builder->token(lexy::error_token_kind, _validate.production_begin(), pos);
84  }
85 
86  _validate.on(handler._validate, ev, pos);
87  }
88 
90  {
91  // As we don't know the production yet (or whether it is actually an operation),
92  // we create a container node to decide later.
93  return handler._builder->start_container();
94  }
95  template <typename Operation>
97  {
98  // We set the production of the current container.
99  // This will do a "left rotation" on the parse tree, making a new container the parent.
100  handler._builder->set_container_production(op);
101  }
102  template <typename Marker>
103  void on(_pth& handler, lexy::parse_events::operation_chain_finish, Marker&& marker,
104  iterator)
105  {
106  handler._builder->finish_container(LEXY_MOV(marker));
107  }
108 
109  template <typename TokenKind>
110  void on(_pth& handler, parse_events::token, TokenKind kind, iterator begin, iterator end)
111  {
112  handler._builder->token(kind, begin, end);
113  }
114 
115  template <typename Error>
116  void on(_pth& handler, parse_events::error ev, Error&& error)
117  {
118  _validate.on(handler._validate, ev, LEXY_FWD(error));
119  }
120 
121  template <typename Event, typename... Args>
122  auto on(_pth& handler, Event ev, Args&&... args)
123  {
124  return _validate.on(handler._validate, ev, LEXY_FWD(args)...);
125  }
126 
127  private:
128  typename Tree::builder::marker _marker;
130  };
131 
132  template <typename Production, typename State>
134 
135  template <typename T>
136  constexpr auto get_result(bool rule_parse_result) &&
137  {
139  return LEXY_MOV(_validate).template get_result<T>(rule_parse_result);
140  }
141 
142 private:
144  Tree* _tree;
145  int _depth;
146 
148 };
149 
150 template <typename State, typename Input, typename ErrorCallback, typename TokenKind = void,
151  typename MemoryResource = void>
153 {
155 
157  const ErrorCallback* _callback;
158  State* _state = nullptr;
159 
161  using state = State;
162  using input = Input;
163 
164  template <typename>
166 
167  constexpr explicit parse_as_tree_action(tree_type& tree, const ErrorCallback& callback)
168  : _tree(&tree), _callback(&callback)
169  {}
170  template <typename U = State>
171  constexpr explicit parse_as_tree_action(U& state, tree_type& tree,
172  const ErrorCallback& callback)
173  : _tree(&tree), _callback(&callback), _state(&state)
174  {}
175 
176  template <typename Production>
177  constexpr auto operator()(Production, const Input& input) const
178  {
179  _detail::any_holder input_holder(&input);
181  auto reader = input.reader();
182  return lexy::do_action<Production, result_type>(handler(*_tree, input_holder, sink), _state,
183  reader);
184  }
185 };
186 
187 template <typename Production, typename TokenKind, typename MemoryResource, typename Input,
188  typename ErrorCallback>
189 auto parse_as_tree(parse_tree<lexy::input_reader<Input>, TokenKind, MemoryResource>& tree,
190  const Input& input, const ErrorCallback& callback)
192 {
193  return parse_as_tree_action<void, Input, ErrorCallback, TokenKind,
194  MemoryResource>(tree, callback)(Production{}, input);
195 }
196 template <typename Production, typename TokenKind, typename MemoryResource, typename Input,
197  typename State, typename ErrorCallback>
198 auto parse_as_tree(parse_tree<lexy::input_reader<Input>, TokenKind, MemoryResource>& tree,
199  const Input& input, State& state, const ErrorCallback& callback)
201 {
202  return parse_as_tree_action<State, Input, ErrorCallback, TokenKind,
203  MemoryResource>(state, tree, callback)(Production{}, input);
204 }
205 template <typename Production, typename TokenKind, typename MemoryResource, typename Input,
206  typename State, typename ErrorCallback>
207 auto parse_as_tree(parse_tree<lexy::input_reader<Input>, TokenKind, MemoryResource>& tree,
208  const Input& input, const State& state, const ErrorCallback& callback)
210 {
211  return parse_as_tree_action<const State, Input, ErrorCallback, TokenKind,
212  MemoryResource>(state, tree, callback)(Production{}, input);
213 }
214 } // namespace lexy
215 
216 #endif // LEXY_ACTION_PARSE_AS_TREE_HPP_INCLUDED
217 
lexy::parse_as_tree_action::_tree
tree_type * _tree
Definition: parse_as_tree.hpp:156
LEXY_MOV
#define LEXY_MOV(...)
Definition: config.hpp:29
lexy::parse_events::production_finish
Definition: dsl/base.hpp:34
lexy::parse_as_tree_action::parse_as_tree_action
constexpr parse_as_tree_action(tree_type &tree, const ErrorCallback &callback)
Definition: parse_as_tree.hpp:167
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::grammar_cancel, Reader &)
Definition: parse_as_tree.hpp:47
lexy::_pth::_builder
lexy::_detail::lazy_init< typename Tree::builder > _builder
Definition: parse_as_tree.hpp:143
lexy::parse_as_tree_action
Definition: parse_as_tree.hpp:152
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::production_cancel ev, iterator pos)
Definition: parse_as_tree.hpp:75
lexy::_pth::event_handler::on
auto on(_pth &handler, Event ev, Args &&... args)
Definition: parse_as_tree.hpp:122
lexy::_pth::event_handler
Definition: parse_as_tree.hpp:24
lexy::position_token_kind
@ position_token_kind
Definition: grammar.hpp:91
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::grammar_finish, Reader &reader)
Definition: parse_as_tree.hpp:37
lexy::_pth::_tree
Tree * _tree
Definition: parse_as_tree.hpp:144
lexy::parse_as_tree_action::operator()
constexpr auto operator()(Production, const Input &input) const
Definition: parse_as_tree.hpp:177
lexy::_pth::_depth
int _depth
Definition: parse_as_tree.hpp:145
lexy::_vh
Definition: validate.hpp:167
lexy::parse_events::grammar_finish
Definition: dsl/base.hpp:21
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::error ev, Error &&error)
Definition: parse_as_tree.hpp:116
lexy::validate_result
Definition: validate.hpp:45
lexy
Definition: any_ref.hpp:12
LEXY_PRECONDITION
#define LEXY_PRECONDITION(Expr)
Definition: assert.hpp:36
lexy::_pth
Definition: parse_as_tree.hpp:15
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::token, TokenKind kind, iterator begin, iterator end)
Definition: parse_as_tree.hpp:110
lexy::parse_as_tree_action::parse_as_tree_action
constexpr parse_as_tree_action(U &state, tree_type &tree, const ErrorCallback &callback)
Definition: parse_as_tree.hpp:171
cx::end
constexpr auto end(const C &c) -> decltype(c.end())
Definition: wildcards.hpp:686
detail::void
j template void())
Definition: json.hpp:4893
lexy::_callback
Definition: adapter.hpp:12
lexy::callback
constexpr auto callback(Fns &&... fns)
Creates a callback.
Definition: adapter.hpp:48
lexy::error
Generic failure.
Definition: error.hpp:14
lexy::_get_error_sink
constexpr auto _get_error_sink(const Callback &callback)
Definition: validate.hpp:19
lexy::_detail::lazy_init::emplace
constexpr T & emplace(Args &&... args)
Definition: lazy_init.hpp:117
lexy::parse_as_tree_action::state
State state
Definition: parse_as_tree.hpp:161
lexy::_detail::lazy_init< typename Tree::builder >
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexy::try_match_token
constexpr LEXY_FORCE_INLINE auto try_match_token(TokenRule, Reader &reader)
Definition: dsl/base.hpp:245
lexy::_pth::event_handler::_marker
Tree::builder::marker _marker
Definition: parse_as_tree.hpp:128
lexy::_pth::event_handler::iterator
typename Reader::iterator iterator
Definition: parse_as_tree.hpp:26
lexy::parse_as_tree
auto parse_as_tree(parse_tree< lexy::input_reader< Input >, TokenKind, MemoryResource > &tree, const Input &input, const ErrorCallback &callback) -> validate_result< ErrorCallback >
Definition: parse_as_tree.hpp:189
lexy::parse_tree
Definition: parse_tree.hpp:344
any.hpp
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::production_start ev, iterator pos)
Definition: parse_as_tree.hpp:54
lexy::parse_events::grammar_start
Definition: dsl/base.hpp:17
lexy::error_token_kind
@ error_token_kind
Definition: grammar.hpp:86
lexy::parse_events::production_start
Definition: dsl/base.hpp:30
lexy::op
typename LEXY_DECAY_DECLTYPE(Operator)::op_tag_type op
Definition: operator.hpp:41
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
lexy::_pth::event_handler::event_handler
event_handler(production_info info)
Definition: parse_as_tree.hpp:29
lexy::parse_events::operation_chain_op
Definition: dsl/base.hpp:48
lexy::_pth::get_result
constexpr auto get_result(bool rule_parse_result) &&
Definition: parse_as_tree.hpp:136
lexy::parse_as_tree_action::input
Input input
Definition: parse_as_tree.hpp:162
lexy::_pth::event_handler::on
void on(_pth &handler, lexy::parse_events::operation_chain_finish, Marker &&marker, iterator)
Definition: parse_as_tree.hpp:103
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::grammar_start, iterator)
Definition: parse_as_tree.hpp:31
validate.hpp
lexy::_detail::void_value_callback
Definition: action/base.hpp:253
lexy::parse_events::production_cancel
Definition: dsl/base.hpp:38
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::production_finish ev, iterator pos)
Definition: parse_as_tree.hpp:62
lexy::parse_events::token
Definition: dsl/base.hpp:57
lexy::parse_as_tree_action::_state
State * _state
Definition: parse_as_tree.hpp:158
lexy::production_info
Definition: grammar.hpp:192
lexy::_pth::_pth
_pth(Tree &tree, const _detail::any_holder< const Input * > &input, _detail::any_holder< Sink > &sink)
Definition: parse_as_tree.hpp:19
parse_tree.hpp
base.hpp
lexy::parse_as_tree_action::handler
_pth< tree_type, lexy::input_reader< Input > > handler
Definition: parse_as_tree.hpp:160
lexy::_pth::event_handler::_validate
_vh< Reader >::event_handler _validate
Definition: parse_as_tree.hpp:129
lexy::parse_events::grammar_cancel
Definition: dsl/base.hpp:25
lexy::_vh::event_handler
Definition: validate.hpp:176
lexy::parse_events::operation_chain_finish
Definition: dsl/base.hpp:52
lexy::parse_as_tree_action::_callback
const ErrorCallback * _callback
Definition: parse_as_tree.hpp:157
lexy::_pth::_validate
_vh< Reader > _validate
Definition: parse_as_tree.hpp:147
lexyd::any
constexpr auto any
Matches anything and consumes all remaining characters.
Definition: 3rdparty/lexy/include/lexy/dsl/any.hpp:42
lexy::_detail::any_holder< const Input * >
lexy::input_reader
decltype(LEXY_DECLVAL(Input).reader()) input_reader
Definition: input/base.hpp:106
lexy::_pth::event_handler::on
void on(_pth &handler, lexy::parse_events::operation_chain_op, Operation op, iterator)
Definition: parse_as_tree.hpp:96
lexy::parse_events::operation_chain_start
Definition: dsl/base.hpp:44
lexy::_pth::event_handler::on
auto on(_pth &handler, lexy::parse_events::operation_chain_start, iterator)
Definition: parse_as_tree.hpp:89


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