parse_as_tree.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2023 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), _reader(input.get()->reader())
22  {}
23 
25  {
26  using iterator = typename Reader::iterator;
27 
28  public:
30 
32  {
33  if (handler._depth++ == 0)
34  handler._builder.emplace(LEXY_MOV(*handler._tree), _validate.get_info());
35  else
36  _marker = handler._builder->start_production(_validate.get_info());
37 
38  _validate.on(handler._validate, ev, pos);
39  }
40 
42  {
43  if (--handler._depth == 0)
44  {
45  auto reader = handler._reader;
46  reader.set_position(pos);
48  auto end = reader.position();
49 
50  *handler._tree = LEXY_MOV(*handler._builder).finish({pos, end});
51  }
52  else
53  {
54  handler._builder->finish_production(LEXY_MOV(_marker));
55  }
56  }
57 
59  {
60  if (--handler._depth == 0)
61  {
62  handler._tree->clear();
63  }
64  else
65  {
66  // Cancelling the production removes all nodes from the tree.
67  // To ensure that the parse tree remains lossless, we add everything consumed by it
68  // as an error token.
69  handler._builder->cancel_production(LEXY_MOV(_marker));
70  handler._builder->token(lexy::error_token_kind, _validate.production_begin(), pos);
71  }
72  }
73 
75  {
76  // As we don't know the production yet (or whether it is actually an operation),
77  // we create a container node to decide later.
78  return handler._builder->start_container();
79  }
80  template <typename Operation>
82  {
83  // We set the production of the current container.
84  // This will do a "left rotation" on the parse tree, making a new container the parent.
85  handler._builder->set_container_production(op);
86  }
87  template <typename Marker>
88  void on(_pth& handler, lexy::parse_events::operation_chain_finish, Marker&& marker,
89  iterator)
90  {
91  handler._builder->finish_container(LEXY_MOV(marker));
92  }
93 
94  template <typename TokenKind>
95  void on(_pth& handler, parse_events::token, TokenKind kind, iterator begin, iterator end)
96  {
97  handler._builder->token(kind, begin, end);
98  }
99 
100  template <typename Error>
101  void on(_pth& handler, parse_events::error ev, Error&& error)
102  {
103  _validate.on(handler._validate, ev, LEXY_FWD(error));
104  }
105 
106  template <typename Event, typename... Args>
107  auto on(_pth& handler, Event ev, Args&&... args)
108  {
109  return _validate.on(handler._validate, ev, LEXY_FWD(args)...);
110  }
111 
112  private:
113  typename Tree::builder::marker _marker;
115  };
116 
117  template <typename Production, typename State>
119 
120  template <typename T>
121  constexpr auto get_result(bool rule_parse_result) &&
122  {
124  return LEXY_MOV(_validate).template get_result<T>(rule_parse_result);
125  }
126 
127 private:
129  Tree* _tree;
130  int _depth;
131 
133  Reader _reader;
134 };
135 
136 template <typename State, typename Input, typename ErrorCallback, typename TokenKind = void,
137  typename MemoryResource = void>
139 {
141 
143  const ErrorCallback* _callback;
144  State* _state = nullptr;
145 
147  using state = State;
148  using input = Input;
149 
150  template <typename>
152 
153  constexpr explicit parse_as_tree_action(tree_type& tree, const ErrorCallback& callback)
154  : _tree(&tree), _callback(&callback)
155  {}
156  template <typename U = State>
157  constexpr explicit parse_as_tree_action(U& state, tree_type& tree,
158  const ErrorCallback& callback)
159  : _tree(&tree), _callback(&callback), _state(&state)
160  {}
161 
162  template <typename Production>
163  constexpr auto operator()(Production, const Input& input) const
164  {
165  _detail::any_holder input_holder(&input);
167  auto reader = input.reader();
168  return lexy::do_action<Production, result_type>(handler(*_tree, input_holder, sink), _state,
169  reader);
170  }
171 };
172 
173 template <typename Production, typename TokenKind, typename MemoryResource, typename Input,
174  typename ErrorCallback>
175 auto parse_as_tree(parse_tree<lexy::input_reader<Input>, TokenKind, MemoryResource>& tree,
176  const Input& input, const ErrorCallback& callback)
178 {
179  return parse_as_tree_action<void, Input, ErrorCallback, TokenKind,
180  MemoryResource>(tree, callback)(Production{}, input);
181 }
182 template <typename Production, typename TokenKind, typename MemoryResource, typename Input,
183  typename State, typename ErrorCallback>
184 auto parse_as_tree(parse_tree<lexy::input_reader<Input>, TokenKind, MemoryResource>& tree,
185  const Input& input, State& state, const ErrorCallback& callback)
187 {
188  return parse_as_tree_action<State, Input, ErrorCallback, TokenKind,
189  MemoryResource>(state, tree, callback)(Production{}, input);
190 }
191 template <typename Production, typename TokenKind, typename MemoryResource, typename Input,
192  typename State, typename ErrorCallback>
193 auto parse_as_tree(parse_tree<lexy::input_reader<Input>, TokenKind, MemoryResource>& tree,
194  const Input& input, const State& state, const ErrorCallback& callback)
196 {
197  return parse_as_tree_action<const State, Input, ErrorCallback, TokenKind,
198  MemoryResource>(state, tree, callback)(Production{}, input);
199 }
200 } // namespace lexy
201 
202 #endif // LEXY_ACTION_PARSE_AS_TREE_HPP_INCLUDED
203 
lexy::parse_as_tree_action::_tree
tree_type * _tree
Definition: parse_as_tree.hpp:142
LEXY_MOV
#define LEXY_MOV(...)
Definition: config.hpp:21
lexy::parse_events::production_finish
Definition: dsl/base.hpp:21
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:153
lexy::_pth::_builder
lexy::_detail::lazy_init< typename Tree::builder > _builder
Definition: parse_as_tree.hpp:128
lexy::parse_as_tree_action
Definition: parse_as_tree.hpp:138
lexy::_pth::event_handler::on
auto on(_pth &handler, Event ev, Args &&... args)
Definition: parse_as_tree.hpp:107
lexy::_pth::event_handler
Definition: parse_as_tree.hpp:24
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::production_cancel, iterator pos)
Definition: parse_as_tree.hpp:58
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::production_finish, iterator pos)
Definition: parse_as_tree.hpp:41
lexy::_pth::_tree
Tree * _tree
Definition: parse_as_tree.hpp:129
lexy::parse_as_tree_action::operator()
constexpr auto operator()(Production, const Input &input) const
Definition: parse_as_tree.hpp:163
lexy::_pth::_depth
int _depth
Definition: parse_as_tree.hpp:130
lexy::_vh
Definition: validate.hpp:167
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:22
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::error ev, Error &&error)
Definition: parse_as_tree.hpp:101
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:95
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:157
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:21
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:105
lexy::parse_as_tree_action::state
State state
Definition: parse_as_tree.hpp:147
lexy::_detail::lazy_init< typename Tree::builder >
lexy::parse_events::error
Definition: dsl/base.hpp:55
lexy::try_match_token
constexpr LEXY_FORCE_INLINE auto try_match_token(TokenRule, Reader &reader)
Definition: dsl/base.hpp:232
lexy::_pth::event_handler::_marker
Tree::builder::marker _marker
Definition: parse_as_tree.hpp:113
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:175
lexy::parse_tree
Definition: parse_tree.hpp:331
any.hpp
lexy::_pth::event_handler::on
void on(_pth &handler, parse_events::production_start ev, iterator pos)
Definition: parse_as_tree.hpp:31
lexy::_pth::_reader
Reader _reader
Definition: parse_as_tree.hpp:133
lexy::error_token_kind
@ error_token_kind
Definition: grammar.hpp:77
lexy::parse_events::production_start
Definition: dsl/base.hpp:17
detail::get
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())
Definition: json.hpp:5342
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:35
lexy::_pth::get_result
constexpr auto get_result(bool rule_parse_result) &&
Definition: parse_as_tree.hpp:121
lexy::parse_as_tree_action::input
Input input
Definition: parse_as_tree.hpp:148
lexy::_pth::event_handler::on
void on(_pth &handler, lexy::parse_events::operation_chain_finish, Marker &&marker, iterator)
Definition: parse_as_tree.hpp:88
validate.hpp
lexy::_detail::void_value_callback
Definition: action/base.hpp:246
lexy::parse_events::production_cancel
Definition: dsl/base.hpp:25
lexy::parse_events::token
Definition: dsl/base.hpp:44
lexy::parse_as_tree_action::_state
State * _state
Definition: parse_as_tree.hpp:144
lexy::production_info
Definition: grammar.hpp:178
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:146
lexy::_pth::event_handler::_validate
_vh< Reader >::event_handler _validate
Definition: parse_as_tree.hpp:114
lexy::_vh::event_handler
Definition: validate.hpp:176
lexy::parse_events::operation_chain_finish
Definition: dsl/base.hpp:39
lexy::parse_as_tree_action::_callback
const ErrorCallback * _callback
Definition: parse_as_tree.hpp:143
lexy::_pth::_validate
_vh< Reader > _validate
Definition: parse_as_tree.hpp:132
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:92
lexy::_pth::event_handler::on
void on(_pth &handler, lexy::parse_events::operation_chain_op, Operation op, iterator)
Definition: parse_as_tree.hpp:81
lexy::parse_events::operation_chain_start
Definition: dsl/base.hpp:31
lexy::_pth::event_handler::on
auto on(_pth &handler, lexy::parse_events::operation_chain_start, iterator)
Definition: parse_as_tree.hpp:74


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Fri Jun 28 2024 02:20:08