3 * The parser implements the following grammar:
5 * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
6 * implicit_document ::= block_node DOCUMENT-END*
7 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
8 * block_node_or_indentless_sequence ::=
10 * | properties (block_content | indentless_block_sequence)?
12 * | indentless_block_sequence
13 * block_node ::= ALIAS
14 * | properties block_content?
17 * | properties flow_content?
19 * properties ::= TAG ANCHOR? | ANCHOR TAG?
20 * block_content ::= block_collection | flow_collection | SCALAR
21 * flow_content ::= flow_collection | SCALAR
22 * block_collection ::= block_sequence | block_mapping
23 * flow_collection ::= flow_sequence | flow_mapping
24 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
25 * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
26 * block_mapping ::= BLOCK-MAPPING_START
27 * ((KEY block_node_or_indentless_sequence?)?
28 * (VALUE block_node_or_indentless_sequence?)?)*
30 * flow_sequence ::= FLOW-SEQUENCE-START
31 * (flow_sequence_entry FLOW-ENTRY)*
32 * flow_sequence_entry?
34 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35 * flow_mapping ::= FLOW-MAPPING-START
36 * (flow_mapping_entry FLOW-ENTRY)*
39 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
42 #include "yaml_private.h"
45 * Peek the next token in the token queue.
48 #define PEEK_TOKEN(parser) \
49 ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
50 parser->tokens.head : NULL)
53 * Remove the next token from the queue (must be called after PEEK_TOKEN).
56 #define SKIP_TOKEN(parser) \
57 (parser->token_available = 0, \
58 parser->tokens_parsed ++, \
59 parser->stream_end_produced = \
60 (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \
61 parser->tokens.head ++)
64 * Public API declarations.
68 yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
75 yaml_parser_set_parser_error(yaml_parser_t *parser,
76 const char *problem, yaml_mark_t problem_mark);
79 yaml_parser_set_parser_error_context(yaml_parser_t *parser,
80 const char *context, yaml_mark_t context_mark,
81 const char *problem, yaml_mark_t problem_mark);
88 yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
91 yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
94 yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
98 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
101 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
104 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105 int block, int indentless_sequence);
108 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109 yaml_event_t *event, int first);
112 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113 yaml_event_t *event);
116 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117 yaml_event_t *event, int first);
120 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121 yaml_event_t *event);
124 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125 yaml_event_t *event, int first);
128 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129 yaml_event_t *event);
132 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133 yaml_event_t *event);
136 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137 yaml_event_t *event);
140 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141 yaml_event_t *event, int first);
144 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145 yaml_event_t *event, int empty);
152 yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153 yaml_event_t *event, yaml_mark_t mark);
156 yaml_parser_process_directives(yaml_parser_t *parser,
157 yaml_version_directive_t **version_directive_ref,
158 yaml_tag_directive_t **tag_directives_start_ref,
159 yaml_tag_directive_t **tag_directives_end_ref);
162 yaml_parser_append_tag_directive(yaml_parser_t *parser,
163 yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
166 * Get the next event.
170 yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
172 assert(parser); /* Non-NULL parser object is expected. */
173 assert(event); /* Non-NULL event object is expected. */
175 /* Erase the event object. */
177 memset(event, 0, sizeof(yaml_event_t));
179 /* No events after the end of the stream or error. */
181 if (parser->stream_end_produced || parser->error ||
182 parser->state == YAML_PARSE_END_STATE) {
186 /* Generate the next event. */
188 return yaml_parser_state_machine(parser, event);
196 yaml_parser_set_parser_error(yaml_parser_t *parser,
197 const char *problem, yaml_mark_t problem_mark)
199 parser->error = YAML_PARSER_ERROR;
200 parser->problem = problem;
201 parser->problem_mark = problem_mark;
207 yaml_parser_set_parser_error_context(yaml_parser_t *parser,
208 const char *context, yaml_mark_t context_mark,
209 const char *problem, yaml_mark_t problem_mark)
211 parser->error = YAML_PARSER_ERROR;
212 parser->context = context;
213 parser->context_mark = context_mark;
214 parser->problem = problem;
215 parser->problem_mark = problem_mark;
226 yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
228 switch (parser->state)
230 case YAML_PARSE_STREAM_START_STATE:
231 return yaml_parser_parse_stream_start(parser, event);
233 case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
234 return yaml_parser_parse_document_start(parser, event, 1);
236 case YAML_PARSE_DOCUMENT_START_STATE:
237 return yaml_parser_parse_document_start(parser, event, 0);
239 case YAML_PARSE_DOCUMENT_CONTENT_STATE:
240 return yaml_parser_parse_document_content(parser, event);
242 case YAML_PARSE_DOCUMENT_END_STATE:
243 return yaml_parser_parse_document_end(parser, event);
245 case YAML_PARSE_BLOCK_NODE_STATE:
246 return yaml_parser_parse_node(parser, event, 1, 0);
248 case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
249 return yaml_parser_parse_node(parser, event, 1, 1);
251 case YAML_PARSE_FLOW_NODE_STATE:
252 return yaml_parser_parse_node(parser, event, 0, 0);
254 case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
255 return yaml_parser_parse_block_sequence_entry(parser, event, 1);
257 case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
258 return yaml_parser_parse_block_sequence_entry(parser, event, 0);
260 case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
261 return yaml_parser_parse_indentless_sequence_entry(parser, event);
263 case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
264 return yaml_parser_parse_block_mapping_key(parser, event, 1);
266 case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
267 return yaml_parser_parse_block_mapping_key(parser, event, 0);
269 case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
270 return yaml_parser_parse_block_mapping_value(parser, event);
272 case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
273 return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
275 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
276 return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
278 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
279 return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
281 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
282 return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
284 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
285 return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
287 case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
288 return yaml_parser_parse_flow_mapping_key(parser, event, 1);
290 case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
291 return yaml_parser_parse_flow_mapping_key(parser, event, 0);
293 case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
294 return yaml_parser_parse_flow_mapping_value(parser, event, 0);
296 case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
297 return yaml_parser_parse_flow_mapping_value(parser, event, 1);
300 assert(1); /* Invalid state. */
307 * Parse the production:
308 * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
313 yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
317 token = PEEK_TOKEN(parser);
318 if (!token) return 0;
320 if (token->type != YAML_STREAM_START_TOKEN) {
321 return yaml_parser_set_parser_error(parser,
322 "did not find expected <stream-start>", token->start_mark);
325 parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
326 STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
327 token->start_mark, token->start_mark);
334 * Parse the productions:
335 * implicit_document ::= block_node DOCUMENT-END*
337 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
338 * *************************
342 yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
346 yaml_version_directive_t *version_directive = NULL;
348 yaml_tag_directive_t *start;
349 yaml_tag_directive_t *end;
350 } tag_directives = { NULL, NULL };
352 token = PEEK_TOKEN(parser);
353 if (!token) return 0;
355 /* Parse extra document end indicators. */
359 while (token->type == YAML_DOCUMENT_END_TOKEN) {
361 token = PEEK_TOKEN(parser);
362 if (!token) return 0;
366 /* Parse an implicit document. */
368 if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
369 token->type != YAML_TAG_DIRECTIVE_TOKEN &&
370 token->type != YAML_DOCUMENT_START_TOKEN &&
371 token->type != YAML_STREAM_END_TOKEN)
373 if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
375 if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
377 parser->state = YAML_PARSE_BLOCK_NODE_STATE;
378 DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
379 token->start_mark, token->start_mark);
383 /* Parse an explicit document. */
385 else if (token->type != YAML_STREAM_END_TOKEN)
387 yaml_mark_t start_mark, end_mark;
388 start_mark = token->start_mark;
389 if (!yaml_parser_process_directives(parser, &version_directive,
390 &tag_directives.start, &tag_directives.end))
392 token = PEEK_TOKEN(parser);
393 if (!token) goto error;
394 if (token->type != YAML_DOCUMENT_START_TOKEN) {
395 yaml_parser_set_parser_error(parser,
396 "did not find expected <document start>", token->start_mark);
399 if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
401 parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
402 end_mark = token->end_mark;
403 DOCUMENT_START_EVENT_INIT(*event, version_directive,
404 tag_directives.start, tag_directives.end, 0,
405 start_mark, end_mark);
407 version_directive = NULL;
408 tag_directives.start = tag_directives.end = NULL;
412 /* Parse the stream end. */
416 parser->state = YAML_PARSE_END_STATE;
417 STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
423 yaml_free(version_directive);
424 while (tag_directives.start != tag_directives.end) {
425 yaml_free(tag_directives.end[-1].handle);
426 yaml_free(tag_directives.end[-1].prefix);
427 tag_directives.end --;
429 yaml_free(tag_directives.start);
434 * Parse the productions:
435 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
440 yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
444 token = PEEK_TOKEN(parser);
445 if (!token) return 0;
447 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
448 token->type == YAML_TAG_DIRECTIVE_TOKEN ||
449 token->type == YAML_DOCUMENT_START_TOKEN ||
450 token->type == YAML_DOCUMENT_END_TOKEN ||
451 token->type == YAML_STREAM_END_TOKEN) {
452 parser->state = POP(parser, parser->states);
453 return yaml_parser_process_empty_scalar(parser, event,
457 return yaml_parser_parse_node(parser, event, 1, 0);
462 * Parse the productions:
463 * implicit_document ::= block_node DOCUMENT-END*
465 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
470 yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
473 yaml_mark_t start_mark, end_mark;
476 token = PEEK_TOKEN(parser);
477 if (!token) return 0;
479 start_mark = end_mark = token->start_mark;
481 if (token->type == YAML_DOCUMENT_END_TOKEN) {
482 end_mark = token->end_mark;
487 while (!STACK_EMPTY(parser, parser->tag_directives)) {
488 yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
489 yaml_free(tag_directive.handle);
490 yaml_free(tag_directive.prefix);
493 parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494 DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
500 * Parse the productions:
501 * block_node_or_indentless_sequence ::=
504 * | properties (block_content | indentless_block_sequence)?
506 * | block_content | indentless_block_sequence
508 * block_node ::= ALIAS
510 * | properties block_content?
514 * flow_node ::= ALIAS
516 * | properties flow_content?
520 * properties ::= TAG ANCHOR? | ANCHOR TAG?
521 * *************************
522 * block_content ::= block_collection | flow_collection | SCALAR
524 * flow_content ::= flow_collection | SCALAR
529 yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530 int block, int indentless_sequence)
533 yaml_char_t *anchor = NULL;
534 yaml_char_t *tag_handle = NULL;
535 yaml_char_t *tag_suffix = NULL;
536 yaml_char_t *tag = NULL;
537 yaml_mark_t start_mark, end_mark, tag_mark;
540 token = PEEK_TOKEN(parser);
541 if (!token) return 0;
543 if (token->type == YAML_ALIAS_TOKEN)
545 parser->state = POP(parser, parser->states);
546 ALIAS_EVENT_INIT(*event, token->data.alias.value,
547 token->start_mark, token->end_mark);
554 start_mark = end_mark = token->start_mark;
556 if (token->type == YAML_ANCHOR_TOKEN)
558 anchor = token->data.anchor.value;
559 start_mark = token->start_mark;
560 end_mark = token->end_mark;
562 token = PEEK_TOKEN(parser);
563 if (!token) goto error;
564 if (token->type == YAML_TAG_TOKEN)
566 tag_handle = token->data.tag.handle;
567 tag_suffix = token->data.tag.suffix;
568 tag_mark = token->start_mark;
569 end_mark = token->end_mark;
571 token = PEEK_TOKEN(parser);
572 if (!token) goto error;
575 else if (token->type == YAML_TAG_TOKEN)
577 tag_handle = token->data.tag.handle;
578 tag_suffix = token->data.tag.suffix;
579 start_mark = tag_mark = token->start_mark;
580 end_mark = token->end_mark;
582 token = PEEK_TOKEN(parser);
583 if (!token) goto error;
584 if (token->type == YAML_ANCHOR_TOKEN)
586 anchor = token->data.anchor.value;
587 end_mark = token->end_mark;
589 token = PEEK_TOKEN(parser);
590 if (!token) goto error;
597 yaml_free(tag_handle);
598 tag_handle = tag_suffix = NULL;
601 yaml_tag_directive_t *tag_directive;
602 for (tag_directive = parser->tag_directives.start;
603 tag_directive != parser->tag_directives.top;
605 if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
606 size_t prefix_len = strlen((char *)tag_directive->prefix);
607 size_t suffix_len = strlen((char *)tag_suffix);
608 tag = YAML_MALLOC(prefix_len+suffix_len+1);
610 parser->error = YAML_MEMORY_ERROR;
613 memcpy(tag, tag_directive->prefix, prefix_len);
614 memcpy(tag+prefix_len, tag_suffix, suffix_len);
615 tag[prefix_len+suffix_len] = '\0';
616 yaml_free(tag_handle);
617 yaml_free(tag_suffix);
618 tag_handle = tag_suffix = NULL;
623 yaml_parser_set_parser_error_context(parser,
624 "while parsing a node", start_mark,
625 "found undefined tag handle", tag_mark);
631 implicit = (!tag || !*tag);
632 if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
633 end_mark = token->end_mark;
634 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
635 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
636 YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
640 if (token->type == YAML_SCALAR_TOKEN) {
641 int plain_implicit = 0;
642 int quoted_implicit = 0;
643 end_mark = token->end_mark;
644 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
645 || (tag && strcmp((char *)tag, "!") == 0)) {
651 parser->state = POP(parser, parser->states);
652 SCALAR_EVENT_INIT(*event, anchor, tag,
653 token->data.scalar.value, token->data.scalar.length,
654 plain_implicit, quoted_implicit,
655 token->data.scalar.style, start_mark, end_mark);
659 else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
660 end_mark = token->end_mark;
661 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
662 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
663 YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
666 else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
667 end_mark = token->end_mark;
668 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
669 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
670 YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
673 else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
674 end_mark = token->end_mark;
675 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
676 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
677 YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
680 else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
681 end_mark = token->end_mark;
682 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
683 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
684 YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
687 else if (anchor || tag) {
688 yaml_char_t *value = YAML_MALLOC(1);
690 parser->error = YAML_MEMORY_ERROR;
694 parser->state = POP(parser, parser->states);
695 SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
696 implicit, 0, YAML_PLAIN_SCALAR_STYLE,
697 start_mark, end_mark);
701 yaml_parser_set_parser_error_context(parser,
702 (block ? "while parsing a block node"
703 : "while parsing a flow node"), start_mark,
704 "did not find expected node content", token->start_mark);
712 yaml_free(tag_handle);
713 yaml_free(tag_suffix);
720 * Parse the productions:
721 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722 * ******************** *********** * *********
726 yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727 yaml_event_t *event, int first)
732 token = PEEK_TOKEN(parser);
733 if (!PUSH(parser, parser->marks, token->start_mark))
738 token = PEEK_TOKEN(parser);
739 if (!token) return 0;
741 if (token->type == YAML_BLOCK_ENTRY_TOKEN)
743 yaml_mark_t mark = token->end_mark;
745 token = PEEK_TOKEN(parser);
746 if (!token) return 0;
747 if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
748 token->type != YAML_BLOCK_END_TOKEN) {
749 if (!PUSH(parser, parser->states,
750 YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
752 return yaml_parser_parse_node(parser, event, 1, 0);
755 parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756 return yaml_parser_process_empty_scalar(parser, event, mark);
760 else if (token->type == YAML_BLOCK_END_TOKEN)
762 parser->state = POP(parser, parser->states);
763 (void)POP(parser, parser->marks);
764 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
771 return yaml_parser_set_parser_error_context(parser,
772 "while parsing a block collection", POP(parser, parser->marks),
773 "did not find expected '-' indicator", token->start_mark);
778 * Parse the productions:
779 * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
784 yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
789 token = PEEK_TOKEN(parser);
790 if (!token) return 0;
792 if (token->type == YAML_BLOCK_ENTRY_TOKEN)
794 yaml_mark_t mark = token->end_mark;
796 token = PEEK_TOKEN(parser);
797 if (!token) return 0;
798 if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
799 token->type != YAML_KEY_TOKEN &&
800 token->type != YAML_VALUE_TOKEN &&
801 token->type != YAML_BLOCK_END_TOKEN) {
802 if (!PUSH(parser, parser->states,
803 YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
805 return yaml_parser_parse_node(parser, event, 1, 0);
808 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
809 return yaml_parser_process_empty_scalar(parser, event, mark);
815 parser->state = POP(parser, parser->states);
816 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
822 * Parse the productions:
823 * block_mapping ::= BLOCK-MAPPING_START
824 * *******************
825 * ((KEY block_node_or_indentless_sequence?)?
827 * (VALUE block_node_or_indentless_sequence?)?)*
834 yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
835 yaml_event_t *event, int first)
840 token = PEEK_TOKEN(parser);
841 if (!PUSH(parser, parser->marks, token->start_mark))
846 token = PEEK_TOKEN(parser);
847 if (!token) return 0;
849 if (token->type == YAML_KEY_TOKEN)
851 yaml_mark_t mark = token->end_mark;
853 token = PEEK_TOKEN(parser);
854 if (!token) return 0;
855 if (token->type != YAML_KEY_TOKEN &&
856 token->type != YAML_VALUE_TOKEN &&
857 token->type != YAML_BLOCK_END_TOKEN) {
858 if (!PUSH(parser, parser->states,
859 YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
861 return yaml_parser_parse_node(parser, event, 1, 1);
864 parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
865 return yaml_parser_process_empty_scalar(parser, event, mark);
869 else if (token->type == YAML_BLOCK_END_TOKEN)
871 parser->state = POP(parser, parser->states);
872 (void)POP(parser, parser->marks);
873 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
880 return yaml_parser_set_parser_error_context(parser,
881 "while parsing a block mapping", POP(parser, parser->marks),
882 "did not find expected key", token->start_mark);
887 * Parse the productions:
888 * block_mapping ::= BLOCK-MAPPING_START
890 * ((KEY block_node_or_indentless_sequence?)?
892 * (VALUE block_node_or_indentless_sequence?)?)*
899 yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
904 token = PEEK_TOKEN(parser);
905 if (!token) return 0;
907 if (token->type == YAML_VALUE_TOKEN)
909 yaml_mark_t mark = token->end_mark;
911 token = PEEK_TOKEN(parser);
912 if (!token) return 0;
913 if (token->type != YAML_KEY_TOKEN &&
914 token->type != YAML_VALUE_TOKEN &&
915 token->type != YAML_BLOCK_END_TOKEN) {
916 if (!PUSH(parser, parser->states,
917 YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
919 return yaml_parser_parse_node(parser, event, 1, 1);
922 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
923 return yaml_parser_process_empty_scalar(parser, event, mark);
929 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
930 return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
935 * Parse the productions:
936 * flow_sequence ::= FLOW-SEQUENCE-START
937 * *******************
938 * (flow_sequence_entry FLOW-ENTRY)*
940 * flow_sequence_entry?
944 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
949 yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
950 yaml_event_t *event, int first)
955 token = PEEK_TOKEN(parser);
956 if (!PUSH(parser, parser->marks, token->start_mark))
961 token = PEEK_TOKEN(parser);
962 if (!token) return 0;
964 if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
967 if (token->type == YAML_FLOW_ENTRY_TOKEN) {
969 token = PEEK_TOKEN(parser);
970 if (!token) return 0;
973 return yaml_parser_set_parser_error_context(parser,
974 "while parsing a flow sequence", POP(parser, parser->marks),
975 "did not find expected ',' or ']'", token->start_mark);
979 if (token->type == YAML_KEY_TOKEN) {
980 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
981 MAPPING_START_EVENT_INIT(*event, NULL, NULL,
982 1, YAML_FLOW_MAPPING_STYLE,
983 token->start_mark, token->end_mark);
988 else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
989 if (!PUSH(parser, parser->states,
990 YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
992 return yaml_parser_parse_node(parser, event, 0, 0);
996 parser->state = POP(parser, parser->states);
997 (void)POP(parser, parser->marks);
998 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1004 * Parse the productions:
1005 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1010 yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1011 yaml_event_t *event)
1013 yaml_token_t *token;
1015 token = PEEK_TOKEN(parser);
1016 if (!token) return 0;
1018 if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1019 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1020 if (!PUSH(parser, parser->states,
1021 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1023 return yaml_parser_parse_node(parser, event, 0, 0);
1026 yaml_mark_t mark = token->end_mark;
1028 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1029 return yaml_parser_process_empty_scalar(parser, event, mark);
1034 * Parse the productions:
1035 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1040 yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1041 yaml_event_t *event)
1043 yaml_token_t *token;
1045 token = PEEK_TOKEN(parser);
1046 if (!token) return 0;
1048 if (token->type == YAML_VALUE_TOKEN) {
1050 token = PEEK_TOKEN(parser);
1051 if (!token) return 0;
1052 if (token->type != YAML_FLOW_ENTRY_TOKEN
1053 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1054 if (!PUSH(parser, parser->states,
1055 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1057 return yaml_parser_parse_node(parser, event, 0, 0);
1060 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1061 return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1065 * Parse the productions:
1066 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1071 yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1072 yaml_event_t *event)
1074 yaml_token_t *token;
1076 token = PEEK_TOKEN(parser);
1077 if (!token) return 0;
1079 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1081 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1086 * Parse the productions:
1087 * flow_mapping ::= FLOW-MAPPING-START
1088 * ******************
1089 * (flow_mapping_entry FLOW-ENTRY)*
1091 * flow_mapping_entry?
1092 * ******************
1095 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1100 yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1101 yaml_event_t *event, int first)
1103 yaml_token_t *token;
1106 token = PEEK_TOKEN(parser);
1107 if (!PUSH(parser, parser->marks, token->start_mark))
1112 token = PEEK_TOKEN(parser);
1113 if (!token) return 0;
1115 if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1118 if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1120 token = PEEK_TOKEN(parser);
1121 if (!token) return 0;
1124 return yaml_parser_set_parser_error_context(parser,
1125 "while parsing a flow mapping", POP(parser, parser->marks),
1126 "did not find expected ',' or '}'", token->start_mark);
1130 if (token->type == YAML_KEY_TOKEN) {
1132 token = PEEK_TOKEN(parser);
1133 if (!token) return 0;
1134 if (token->type != YAML_VALUE_TOKEN
1135 && token->type != YAML_FLOW_ENTRY_TOKEN
1136 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1137 if (!PUSH(parser, parser->states,
1138 YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1140 return yaml_parser_parse_node(parser, event, 0, 0);
1143 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1144 return yaml_parser_process_empty_scalar(parser, event,
1148 else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1149 if (!PUSH(parser, parser->states,
1150 YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1152 return yaml_parser_parse_node(parser, event, 0, 0);
1156 parser->state = POP(parser, parser->states);
1157 (void)POP(parser, parser->marks);
1158 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1164 * Parse the productions:
1165 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1170 yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1171 yaml_event_t *event, int empty)
1173 yaml_token_t *token;
1175 token = PEEK_TOKEN(parser);
1176 if (!token) return 0;
1179 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1180 return yaml_parser_process_empty_scalar(parser, event,
1184 if (token->type == YAML_VALUE_TOKEN) {
1186 token = PEEK_TOKEN(parser);
1187 if (!token) return 0;
1188 if (token->type != YAML_FLOW_ENTRY_TOKEN
1189 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1190 if (!PUSH(parser, parser->states,
1191 YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1193 return yaml_parser_parse_node(parser, event, 0, 0);
1197 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1198 return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1202 * Generate an empty scalar event.
1206 yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1211 value = YAML_MALLOC(1);
1213 parser->error = YAML_MEMORY_ERROR;
1218 SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1219 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1229 yaml_parser_process_directives(yaml_parser_t *parser,
1230 yaml_version_directive_t **version_directive_ref,
1231 yaml_tag_directive_t **tag_directives_start_ref,
1232 yaml_tag_directive_t **tag_directives_end_ref)
1234 yaml_tag_directive_t default_tag_directives[] = {
1235 {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1236 {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1239 yaml_tag_directive_t *default_tag_directive;
1240 yaml_version_directive_t *version_directive = NULL;
1242 yaml_tag_directive_t *start;
1243 yaml_tag_directive_t *end;
1244 yaml_tag_directive_t *top;
1245 } tag_directives = { NULL, NULL, NULL };
1246 yaml_token_t *token;
1248 if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
1251 token = PEEK_TOKEN(parser);
1252 if (!token) goto error;
1254 while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1255 token->type == YAML_TAG_DIRECTIVE_TOKEN)
1257 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1258 if (version_directive) {
1259 yaml_parser_set_parser_error(parser,
1260 "found duplicate %YAML directive", token->start_mark);
1263 if (token->data.version_directive.major != 1
1264 || token->data.version_directive.minor != 1) {
1265 yaml_parser_set_parser_error(parser,
1266 "found incompatible YAML document", token->start_mark);
1269 version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
1270 if (!version_directive) {
1271 parser->error = YAML_MEMORY_ERROR;
1274 version_directive->major = token->data.version_directive.major;
1275 version_directive->minor = token->data.version_directive.minor;
1278 else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1279 yaml_tag_directive_t value;
1280 value.handle = token->data.tag_directive.handle;
1281 value.prefix = token->data.tag_directive.prefix;
1283 if (!yaml_parser_append_tag_directive(parser, value, 0,
1286 if (!PUSH(parser, tag_directives, value))
1291 token = PEEK_TOKEN(parser);
1292 if (!token) goto error;
1295 for (default_tag_directive = default_tag_directives;
1296 default_tag_directive->handle; default_tag_directive++) {
1297 if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1302 if (version_directive_ref) {
1303 *version_directive_ref = version_directive;
1305 if (tag_directives_start_ref) {
1306 if (STACK_EMPTY(parser, tag_directives)) {
1307 *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1308 STACK_DEL(parser, tag_directives);
1311 *tag_directives_start_ref = tag_directives.start;
1312 *tag_directives_end_ref = tag_directives.top;
1316 STACK_DEL(parser, tag_directives);
1322 yaml_free(version_directive);
1323 while (!STACK_EMPTY(parser, tag_directives)) {
1324 yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1325 yaml_free(tag_directive.handle);
1326 yaml_free(tag_directive.prefix);
1328 STACK_DEL(parser, tag_directives);
1333 * Append a tag directive to the directives stack.
1337 yaml_parser_append_tag_directive(yaml_parser_t *parser,
1338 yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1340 yaml_tag_directive_t *tag_directive;
1341 yaml_tag_directive_t copy = { NULL, NULL };
1343 for (tag_directive = parser->tag_directives.start;
1344 tag_directive != parser->tag_directives.top; tag_directive ++) {
1345 if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1346 if (allow_duplicates)
1348 return yaml_parser_set_parser_error(parser,
1349 "found duplicate %TAG directive", mark);
1353 copy.handle = yaml_strdup(value.handle);
1354 copy.prefix = yaml_strdup(value.prefix);
1355 if (!copy.handle || !copy.prefix) {
1356 parser->error = YAML_MEMORY_ERROR;
1360 if (!PUSH(parser, parser->tag_directives, copy))
1366 yaml_free(copy.handle);
1367 yaml_free(copy.prefix);