25 #ifndef PARSE_TREE_HPP_ 26 #define PARSE_TREE_HPP_ 32 #include <type_traits> 36 #include <pegtl/config.hpp> 37 #include <pegtl/internal/demangle.hpp> 38 #include <pegtl/internal/iterator.hpp> 39 #include <pegtl/normal.hpp> 40 #include <pegtl/nothing.hpp> 41 #include <pegtl/parse.hpp> 51 namespace pegtl = tao::pegtl;
54 struct default_node_children
57 using children_t = std::vector< std::unique_ptr< node_t > >;
61 default_node_children() =
default;
65 default_node_children(
const default_node_children &) =
delete;
66 default_node_children(default_node_children &&) =
delete;
68 ~default_node_children() =
default;
71 default_node_children &operator=(
72 const default_node_children &) =
delete;
73 default_node_children &operator=(
74 default_node_children &&) =
delete;
76 typename children_t::reference at(
77 const typename children_t::size_type pos)
79 return children.at(pos);
82 typename children_t::const_reference at(
83 const typename children_t::size_type pos)
const 85 return children.at(pos);
88 typename children_t::reference front()
90 return children.front();
93 typename children_t::const_reference front()
const 95 return children.front();
98 typename children_t::reference back()
100 return children.back();
103 typename children_t::const_reference back()
const 105 return children.back();
108 bool empty() const noexcept
110 return children.empty();
113 typename children_t::size_type size() const noexcept
115 return children.size();
122 template<
typename... States>
124 std::unique_ptr< node_t > child, States &&... )
127 children.emplace_back(std::move(child));
131 struct default_node_content
133 const std::type_info *id_ =
nullptr;
134 pegtl::internal::iterator begin_;
135 pegtl::internal::iterator end_;
138 bool is_root() const noexcept
140 return id_ ==
nullptr;
144 bool is() const noexcept
146 return id_ == &
typeid(T);
149 std::string
name()
const 152 return pegtl::internal::demangle(id_->name());
155 pegtl::position begin()
const 157 return pegtl::position(begin_, source_);
160 pegtl::position end()
const 162 return pegtl::position(end_, source_);
165 const std::string &source() const noexcept
170 bool has_content() const noexcept
172 return end_.data !=
nullptr;
175 std::string content()
const 177 assert(has_content());
178 return std::string(begin_.data, end_.data);
181 template<
typename... States >
182 void remove_content(States &&... ) noexcept
188 template<
typename Rule,
typename Input,
typename... States>
189 void start(
const Input &in, States &&... )
192 begin_ = in.iterator();
193 source_ = in.source();
197 template<
typename Rule,
typename Input,
typename... States>
198 void success(
const Input &in, States &&... ) noexcept
200 end_ = in.iterator();
204 template<
typename Rule,
typename Input,
typename... States>
206 const Input & , States &&... ) noexcept
213 : default_node_children<T>, default_node_content
224 template<
typename Node>
227 std::vector<std::unique_ptr<Node>> stack;
236 stack.emplace_back(std::unique_ptr< Node >(
new Node));
239 std::unique_ptr<Node> &back() noexcept
244 void pop_back() noexcept
246 return stack.pop_back();
250 template<
typename Node,
typename S,
typename =
void>
253 template<
typename... States>
254 static void call(std::unique_ptr< Node > & ,
255 States &&... ) noexcept
260 template<
typename Node,
typename S>
263 S::transform(std::declval<std::unique_ptr<Node>& >()), void()) >
265 template<
typename... States>
267 std::unique_ptr<Node> &n, States &&... st)
268 noexcept(noexcept(S::transform(n)))
270 S::transform(n, st...);
275 template <
typename T,
typename =
int>
276 struct has_error_message : std::false_type {};
279 template <
typename T>
280 struct has_error_message <T, decltype((void) T::error_message, 0)>
283 template<
template<
typename>
class S>
286 template<typename Rule, bool = S<Rule>::value>
289 template<
typename Rule>
290 using type = control<Rule>;
293 template<
template<
typename>
class S>
294 template<
typename Rule>
295 struct make_control< S >::control< Rule, false >
296 : pegtl::normal< Rule >
300 template<
typename Input,
typename... States >
301 static void raise(
const Input &in, States &&...)
303 if constexpr(has_error_message<S<Rule>>::value)
305 throw pegtl::parse_error(S<Rule>::error_message, in);
309 throw pegtl::parse_error(
310 "Parse error matching " +
311 pegtl::internal::demangle<Rule>(), in);
317 template<
template<
typename>
class S>
318 template<
typename Rule>
319 struct make_control<S>::control< Rule, true >
320 : pegtl::normal<Rule>
324 template<
typename Input,
typename... States >
325 static void raise(
const Input &in, States &&...)
327 if constexpr(has_error_message<S<Rule>>::value)
329 throw pegtl::parse_error(S<Rule>::error_message, in);
333 throw pegtl::parse_error(
334 "Parse error matching " +
335 pegtl::internal::demangle<Rule>(), in);
339 template<
typename Input,
typename Node,
typename... States>
341 const Input &in, state< Node > &state, States &&... st)
343 state.emplace_back();
344 state.back()->template start<Rule>(in, st...);
347 template<
typename Input,
typename Node,
typename... States >
349 const Input &in, state<Node> &state, States &&... st)
351 auto n = std::move(state.back());
353 n->template success<Rule>(in, st...);
354 transform<Node, S<Rule>>
::call(n, st...);
358 state.back()->emplace_back(std::move(n), st...);
362 template<
typename Input,
typename Node,
typename... States>
364 const Input &in, state< Node > &state, States &&... st)
365 noexcept(noexcept(std::declval<node &>().
template 366 failure<Rule>(in, st...)))
368 state.back()->template failure< Rule >(in, st...);
374 struct store_all : std::true_type
383 template<
typename>
class S = internal::store_all,
386 std::unique_ptr<Node>
parse(Input &in, States && ... st)
388 internal::state< Node > state;
391 Rule, pegtl::nothing,
392 internal::make_control<S>::template type >
398 assert(state.stack.size() == 1);
399 return std::move(state.back());
404 template<
typename>
class S = internal::store_all,
407 std::unique_ptr<node>
parse(Input &in, States && ... st)
409 return parse<Rule, node, S>(in, st...);
std::unique_ptr< config::parse_tree::node > parse(Input &in)
std::string name(unsigned long id)