8 #ifndef INCLUDED_ORCUS_YAML_PARSER_HPP 9 #define INCLUDED_ORCUS_YAML_PARSER_HPP 11 #include "orcus/yaml_parser_base.hpp" 12 #include "orcus/parser_global.hpp" 16 template<
typename _Handler>
20 typedef _Handler handler_type;
22 yaml_parser(
const char* p,
size_t n, handler_type& hdl);
28 void check_or_begin_document();
29 void check_or_begin_map();
30 void check_or_begin_sequence();
31 void parse_value(
const char* p,
size_t len);
32 void push_value(
const char* p,
size_t len);
33 void parse_line(
const char* p,
size_t len);
34 void parse_map_key(
const char* p,
size_t len);
37 handler_type& m_handler;
40 template<
typename _Handler>
44 template<
typename _Handler>
47 m_handler.begin_parse();
52 if (indent == parse_indent_end_of_stream)
55 if (indent == parse_indent_blank_line)
58 size_t cur_scope = get_scope();
60 if (cur_scope <= indent)
62 if (in_literal_block())
64 handle_line_in_literal(indent);
68 if (has_line_buffer())
72 handle_line_in_multi_line_string();
77 if (cur_scope == scope_empty || indent > cur_scope)
81 else if (indent < cur_scope)
86 cur_scope = end_scope();
87 if (cur_scope < indent)
90 while (indent < cur_scope);
97 assert(!line.empty());
98 parse_line(line.get(), line.size());
102 size_t cur_scope = get_scope();
103 while (cur_scope != scope_empty)
104 cur_scope = end_scope();
107 m_handler.end_document();
109 m_handler.end_parse();
112 template<
typename _Handler>
115 switch (get_scope_type())
117 case yaml::scope_t::map:
120 case yaml::scope_t::sequence:
121 m_handler.end_sequence();
123 case yaml::scope_t::multi_line_string:
125 pstring merged = merge_line_buffer();
126 m_handler.string(merged.get(), merged.size());
131 if (has_line_buffer())
133 assert(get_line_buffer_count() == 1);
134 pstring line = pop_line_front();
135 parse_value(line.get(), line.size());
142 template<
typename _Handler>
148 m_handler.begin_document();
152 template<
typename _Handler>
155 if (get_scope_type() == yaml::scope_t::unset)
157 check_or_begin_document();
158 set_scope_type(yaml::scope_t::map);
159 m_handler.begin_map();
163 template<
typename _Handler>
166 if (get_scope_type() == yaml::scope_t::unset)
168 check_or_begin_document();
169 set_scope_type(yaml::scope_t::sequence);
170 m_handler.begin_sequence();
174 template<
typename _Handler>
177 check_or_begin_document();
180 const char* p_end = p + len;
181 double val = parse_numeric(p, len);
184 m_handler.number(val);
188 yaml::keyword_t kw = parse_keyword(p0, len);
190 if (kw != yaml::keyword_t::unknown)
194 case yaml::keyword_t::null:
197 case yaml::keyword_t::boolean_true:
198 m_handler.boolean_true();
200 case yaml::keyword_t::boolean_false:
201 m_handler.boolean_false();
211 m_handler.string(p0, len);
214 template<
typename _Handler>
217 check_or_begin_document();
219 if (has_line_buffer() && get_scope_type() == yaml::scope_t::unset)
220 set_scope_type(yaml::scope_t::multi_line_string);
222 push_line_back(p, len);
225 template<
typename _Handler>
228 const char* p_end = p + len;
237 check_or_begin_sequence();
251 yaml::parse_error::throw_with(
"parse_line: '-' expected but '", *p,
"' found.");
255 m_handler.begin_document();
259 skip_blanks(p, p_end-p);
264 parse_line(p, p_end-p);
270 check_or_begin_sequence();
275 throw yaml::parse_error(
"parse_line: list item expected, but the line ended prematurely.");
277 skip_blanks(p, p_end-p);
279 size_t scope_width = get_scope() + (p-p0);
280 push_scope(scope_width);
281 parse_line(p, p_end-p);
290 parse_map_key(p, len);
293 template<
typename _Handler>
296 const char* p_end = p + len;
303 pstring quoted_str = parse_double_quoted_string_value(p, len);
307 m_handler.string(quoted_str.get(), quoted_str.size());
311 skip_blanks(p, p_end-p);
314 throw yaml::parse_error(
"parse_map_key: ':' is expected after the quoted string key.");
316 check_or_begin_map();
317 m_handler.begin_map_key();
318 m_handler.string(quoted_str.get(), quoted_str.size());
319 m_handler.end_map_key();
326 skip_blanks(p, p_end-p);
331 pstring quoted_str = parse_single_quoted_string_value(p, len);
335 m_handler.string(quoted_str.get(), quoted_str.size());
339 skip_blanks(p, p_end-p);
342 throw yaml::parse_error(
"parse_map_key: ':' is expected after the quoted string key.");
344 check_or_begin_map();
345 m_handler.begin_map_key();
346 m_handler.string(quoted_str.get(), quoted_str.size());
347 m_handler.end_map_key();
353 skip_blanks(p, p_end-p);
358 key_value kv = parse_key_value(p, p_end-p);
365 start_literal_block();
373 check_or_begin_map();
374 m_handler.begin_map_key();
375 parse_value(kv.key.get(), kv.key.size());
376 m_handler.end_map_key();
378 if (kv.value.empty())
387 start_literal_block();
393 throw yaml::parse_error(
"parse_map_key: sequence entry is not allowed as an inline map item.");
395 size_t scope_width = get_scope() + (p-p0);
396 push_scope(scope_width);
397 parse_line(p, p_end-p);
Definition: yaml_parser_base.hpp:59
Definition: pstring.hpp:24
Definition: yaml_parser.hpp:17
const char * get_doc_hash() const
void set_doc_hash(const char *hash)
pstring parse_to_end_of_line()
Definition: yaml_parser_base.hpp:19
Definition: base64.hpp:15
Definition: yaml_parser_base.hpp:44