1 #ifndef _C4_YML_EVENT_HANDLER_STACK_HPP_
2 #define _C4_YML_EVENT_HANDLER_STACK_HPP_
4 #ifndef _C4_YML_DETAIL_STACK_HPP_
5 #include "c4/yml/detail/stack.hpp"
8 #ifndef _C4_YML_DETAIL_PARSER_DBG_HPP_
9 #include "c4/yml/detail/parser_dbg.hpp"
12 #ifndef _C4_YML_PARSER_STATE_HPP_
17 #ifndef _C4_YML_DETAIL_PRINT_HPP_
18 #include "c4/yml/detail/print.hpp"
34 template<
class HandlerImpl,
class HandlerState>
37 static_assert(std::is_base_of<ParserState, HandlerState>::value,
38 "ParserState must be a base of HandlerState");
61 _RYML_CB_ASSERT(
m_stack.m_callbacks, relocate_arena !=
nullptr);
62 _RYML_CB_ASSERT(
m_stack.m_callbacks, relocate_arena_data !=
nullptr);
96 m_curr->reset_after_push();
109 _c4dbgpf(
"popped! top is now node={} (parent={})",
m_curr->node_id,
m_parent->node_id);
111 _c4dbgpf(
"popped! top is now node={} @ ROOT",
m_curr->node_id);
118 #define _has_any_(bits) (static_cast<HandlerImpl const* C4_RESTRICT>(this)->template _has_any__<bits>())
122 const bool is_root = (
m_stack.size() == 1u);
128 const bool is_root = (
m_stack.size() == 1u);
138 if(st.line_contents.rem.is_sub(prev))
140 if(st.line_contents.full.is_sub(prev))
142 if(st.line_contents.stripped.is_sub(prev))
152 _RYML_CB_ASSERT(
m_stack.m_callbacks, prev.is_super(s));
153 auto pos = s.str - prev.str;
154 substr out = {curr.str + pos, s.len};
155 _RYML_CB_ASSERT(
m_stack.m_callbacks, curr.is_super(out));
167 const bool is_root = (
m_stack.size() == 1u);
168 const bool isndoc = (
m_curr->flags &
NDOC) != 0;
170 _c4dbgpf(
"target={} isroot={} suspicious={} ndoc={}",
m_curr->node_id, is_root, suspicious, isndoc);
171 if((is_root ||
_has_any_(
DOC)) && suspicious && !isndoc)
172 _RYML_CB_ERR_(
m_stack.m_callbacks,
"parse error",
m_curr->pos);
@ MAP
a map: a parent of KEYVAL/KEYSEQ/KEYMAP nodes
@ VAL
a scalar: has a scalar (ie string) value, possibly empty. must be a leaf node, and cannot be MAP or S...
@ SEQ
a seq: a parent of VAL/SEQ/MAP nodes
void(*)(void *, csubstr prev_arena, substr next_arena) pfn_relocate_arena
@ NDOC
no document mode. a document has ended and another has not started yet.
a c-style callbacks class.
Use this class a base of implementations of event handler to simplify the stack logic.
void _stack_finish_parse()
substr _stack_relocate_to_new_arena(csubstr s, csubstr prev, substr curr)
void _stack_reset_non_root()
state * m_curr
current stack level: top of the stack. cached here for easier access.
void * m_relocate_arena_data
void _stack_start_parse(const char *filename, pfn_relocate_arena relocate_arena, void *relocate_arena_data)
pfn_relocate_arena m_relocate_arena
callback when the arena gets relocated
bool _stack_should_push_on_begin_doc() const
EventHandlerStack(Callbacks const &cb)
void check_trailing_doc_token() const
Check whether the current parse tokens are trailing on the previous doc, and raise an error if they a...
detail::stack< state > m_stack
void _stack_relocate_to_new_arena(csubstr prev, substr curr)
state * m_parent
parent of the current stack level.
bool _stack_should_pop_on_end_doc() const
detail::pfn_relocate_arena pfn_relocate_arena