Actual source code: parser.c
2: /*
3: * The parser implements the following grammar:
4: *
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 ::=
9: * ALIAS
10: * | properties (block_content | indentless_block_sequence)?
11: * | block_content
12: * | indentless_block_sequence
13: * block_node ::= ALIAS
14: * | properties block_content?
15: * | block_content
16: * flow_node ::= ALIAS
17: * | properties flow_content?
18: * | 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?)?)*
29: * BLOCK-END
30: * flow_sequence ::= FLOW-SEQUENCE-START
31: * (flow_sequence_entry FLOW-ENTRY)*
32: * flow_sequence_entry?
33: * FLOW-SEQUENCE-END
34: * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35: * flow_mapping ::= FLOW-MAPPING-START
36: * (flow_mapping_entry FLOW-ENTRY)*
37: * flow_mapping_entry?
38: * FLOW-MAPPING-END
39: * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
40: */
42: #include "yaml_private.h"
44: /*
45: * Peek the next token in the token queue.
46: */
48: #define PEEK_TOKEN(parser) \
49: ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
50: parser->tokens.head : NULL)
52: /*
53: * Remove the next token from the queue (must be called after PEEK_TOKEN).
54: */
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 ++)
63: /*
64: * Public API declarations.
65: */
67: YAML_DECLARE(int)
68: yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
70: /*
71: * Error handling.
72: */
74: static int
75: yaml_parser_set_parser_error(yaml_parser_t *parser,
76: const char *problem, yaml_mark_t problem_mark);
78: static int
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);
83: /*
84: * State functions.
85: */
87: static int
88: yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
90: static int
91: yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
93: static int
94: yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
95: int implicit);
97: static int
98: yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
100: static int
101: yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
103: static int
104: yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105: int block, int indentless_sequence);
107: static int
108: yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109: yaml_event_t *event, int first);
111: static int
112: yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113: yaml_event_t *event);
115: static int
116: yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117: yaml_event_t *event, int first);
119: static int
120: yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121: yaml_event_t *event);
123: static int
124: yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125: yaml_event_t *event, int first);
127: static int
128: yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129: yaml_event_t *event);
131: static int
132: yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133: yaml_event_t *event);
135: static int
136: yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137: yaml_event_t *event);
139: static int
140: yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141: yaml_event_t *event, int first);
143: static int
144: yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145: yaml_event_t *event, int empty);
147: /*
148: * Utility functions.
149: */
151: static int
152: yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153: yaml_event_t *event, yaml_mark_t mark);
155: static int
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);
161: static int
162: yaml_parser_append_tag_directive(yaml_parser_t *parser,
163: yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
165: /*
166: * Get the next event.
167: */
169: YAML_DECLARE(int)
170: yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
171: {
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) {
183: return 1;
184: }
186: /* Generate the next event. */
188: return yaml_parser_state_machine(parser, event);
189: }
191: /*
192: * Set parser error.
193: */
195: static int
196: yaml_parser_set_parser_error(yaml_parser_t *parser,
197: const char *problem, yaml_mark_t problem_mark)
198: {
199: parser->error = YAML_PARSER_ERROR;
200: parser->problem = problem;
201: parser->problem_mark = problem_mark;
203: return 0;
204: }
206: static int
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)
210: {
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;
217: return 0;
218: }
221: /*
222: * State dispatcher.
223: */
225: static int
226: yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
227: {
228: switch (parser->state)
229: {
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);
299: default:
300: assert(1); /* Invalid state. */
301: }
303: return 0;
304: }
306: /*
307: * Parse the production:
308: * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
309: * ************
310: */
312: static int
313: yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
314: {
315: yaml_token_t *token;
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);
323: }
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);
328: SKIP_TOKEN(parser);
330: return 1;
331: }
333: /*
334: * Parse the productions:
335: * implicit_document ::= block_node DOCUMENT-END*
336: * *
337: * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
338: * *************************
339: */
341: static int
342: yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
343: int implicit)
344: {
345: yaml_token_t *token;
346: yaml_version_directive_t *version_directive = NULL;
347: struct {
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. */
357: if (!implicit)
358: {
359: while (token->type == YAML_DOCUMENT_END_TOKEN) {
360: SKIP_TOKEN(parser);
361: token = PEEK_TOKEN(parser);
362: if (!token) return 0;
363: }
364: }
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)
372: {
373: if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
374: return 0;
375: if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
376: return 0;
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);
380: return 1;
381: }
383: /* Parse an explicit document. */
385: else if (token->type != YAML_STREAM_END_TOKEN)
386: {
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))
391: return 0;
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);
397: goto error;
398: }
399: if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
400: goto error;
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);
406: SKIP_TOKEN(parser);
407: version_directive = NULL;
408: tag_directives.start = tag_directives.end = NULL;
409: return 1;
410: }
412: /* Parse the stream end. */
414: else
415: {
416: parser->state = YAML_PARSE_END_STATE;
417: STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
418: SKIP_TOKEN(parser);
419: return 1;
420: }
422: error:
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 --;
428: }
429: yaml_free(tag_directives.start);
430: return 0;
431: }
433: /*
434: * Parse the productions:
435: * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436: * ***********
437: */
439: static int
440: yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441: {
442: yaml_token_t *token;
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,
454: token->start_mark);
455: }
456: else {
457: return yaml_parser_parse_node(parser, event, 1, 0);
458: }
459: }
461: /*
462: * Parse the productions:
463: * implicit_document ::= block_node DOCUMENT-END*
464: * *************
465: * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
466: * *************
467: */
469: static int
470: yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
471: {
472: yaml_token_t *token;
473: yaml_mark_t start_mark, end_mark;
474: int implicit = 1;
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;
483: SKIP_TOKEN(parser);
484: implicit = 0;
485: }
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);
491: }
493: parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494: DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
496: return 1;
497: }
499: /*
500: * Parse the productions:
501: * block_node_or_indentless_sequence ::=
502: * ALIAS
503: * *****
504: * | properties (block_content | indentless_block_sequence)?
505: * ********** *
506: * | block_content | indentless_block_sequence
507: * *
508: * block_node ::= ALIAS
509: * *****
510: * | properties block_content?
511: * ********** *
512: * | block_content
513: * *
514: * flow_node ::= ALIAS
515: * *****
516: * | properties flow_content?
517: * ********** *
518: * | flow_content
519: * *
520: * properties ::= TAG ANCHOR? | ANCHOR TAG?
521: * *************************
522: * block_content ::= block_collection | flow_collection | SCALAR
523: * ******
524: * flow_content ::= flow_collection | SCALAR
525: * ******
526: */
528: static int
529: yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530: int block, int indentless_sequence)
531: {
532: yaml_token_t *token;
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;
538: int implicit;
540: token = PEEK_TOKEN(parser);
541: if (!token) return 0;
543: if (token->type == YAML_ALIAS_TOKEN)
544: {
545: parser->state = POP(parser, parser->states);
546: ALIAS_EVENT_INIT(*event, token->data.alias.value,
547: token->start_mark, token->end_mark);
548: SKIP_TOKEN(parser);
549: return 1;
550: }
552: else
553: {
554: start_mark = end_mark = token->start_mark;
556: if (token->type == YAML_ANCHOR_TOKEN)
557: {
558: anchor = token->data.anchor.value;
559: start_mark = token->start_mark;
560: end_mark = token->end_mark;
561: SKIP_TOKEN(parser);
562: token = PEEK_TOKEN(parser);
563: if (!token) goto error;
564: if (token->type == YAML_TAG_TOKEN)
565: {
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;
570: SKIP_TOKEN(parser);
571: token = PEEK_TOKEN(parser);
572: if (!token) goto error;
573: }
574: }
575: else if (token->type == YAML_TAG_TOKEN)
576: {
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;
581: SKIP_TOKEN(parser);
582: token = PEEK_TOKEN(parser);
583: if (!token) goto error;
584: if (token->type == YAML_ANCHOR_TOKEN)
585: {
586: anchor = token->data.anchor.value;
587: end_mark = token->end_mark;
588: SKIP_TOKEN(parser);
589: token = PEEK_TOKEN(parser);
590: if (!token) goto error;
591: }
592: }
594: if (tag_handle) {
595: if (!*tag_handle) {
596: tag = tag_suffix;
597: yaml_free(tag_handle);
598: tag_handle = tag_suffix = NULL;
599: }
600: else {
601: yaml_tag_directive_t *tag_directive;
602: for (tag_directive = parser->tag_directives.start;
603: tag_directive != parser->tag_directives.top;
604: tag_directive ++) {
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);
609: if (!tag) {
610: parser->error = YAML_MEMORY_ERROR;
611: goto error;
612: }
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;
619: break;
620: }
621: }
622: if (!tag) {
623: yaml_parser_set_parser_error_context(parser,
624: "while parsing a node", start_mark,
625: "found undefined tag handle", tag_mark);
626: goto error;
627: }
628: }
629: }
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);
637: return 1;
638: }
639: else {
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)) {
646: plain_implicit = 1;
647: }
648: else if (!tag) {
649: quoted_implicit = 1;
650: }
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);
656: SKIP_TOKEN(parser);
657: return 1;
658: }
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);
664: return 1;
665: }
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);
671: return 1;
672: }
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);
678: return 1;
679: }
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);
685: return 1;
686: }
687: else if (anchor || tag) {
688: yaml_char_t *value = YAML_MALLOC(1);
689: if (!value) {
690: parser->error = YAML_MEMORY_ERROR;
691: goto error;
692: }
693: value[0] = '\0';
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);
698: return 1;
699: }
700: else {
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);
705: goto error;
706: }
707: }
708: }
710: error:
711: yaml_free(anchor);
712: yaml_free(tag_handle);
713: yaml_free(tag_suffix);
714: yaml_free(tag);
716: return 0;
717: }
719: /*
720: * Parse the productions:
721: * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722: * ******************** *********** * *********
723: */
725: static int
726: yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727: yaml_event_t *event, int first)
728: {
729: yaml_token_t *token;
731: if (first) {
732: token = PEEK_TOKEN(parser);
733: if (!PUSH(parser, parser->marks, token->start_mark))
734: return 0;
735: SKIP_TOKEN(parser);
736: }
738: token = PEEK_TOKEN(parser);
739: if (!token) return 0;
741: if (token->type == YAML_BLOCK_ENTRY_TOKEN)
742: {
743: yaml_mark_t mark = token->end_mark;
744: SKIP_TOKEN(parser);
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))
751: return 0;
752: return yaml_parser_parse_node(parser, event, 1, 0);
753: }
754: else {
755: parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756: return yaml_parser_process_empty_scalar(parser, event, mark);
757: }
758: }
760: else if (token->type == YAML_BLOCK_END_TOKEN)
761: {
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);
765: SKIP_TOKEN(parser);
766: return 1;
767: }
769: else
770: {
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);
774: }
775: }
777: /*
778: * Parse the productions:
779: * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
780: * *********** *
781: */
783: static int
784: yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
785: yaml_event_t *event)
786: {
787: yaml_token_t *token;
789: token = PEEK_TOKEN(parser);
790: if (!token) return 0;
792: if (token->type == YAML_BLOCK_ENTRY_TOKEN)
793: {
794: yaml_mark_t mark = token->end_mark;
795: SKIP_TOKEN(parser);
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))
804: return 0;
805: return yaml_parser_parse_node(parser, event, 1, 0);
806: }
807: else {
808: parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
809: return yaml_parser_process_empty_scalar(parser, event, mark);
810: }
811: }
813: else
814: {
815: parser->state = POP(parser, parser->states);
816: SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
817: return 1;
818: }
819: }
821: /*
822: * Parse the productions:
823: * block_mapping ::= BLOCK-MAPPING_START
824: * *******************
825: * ((KEY block_node_or_indentless_sequence?)?
826: * *** *
827: * (VALUE block_node_or_indentless_sequence?)?)*
828: *
829: * BLOCK-END
830: * *********
831: */
833: static int
834: yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
835: yaml_event_t *event, int first)
836: {
837: yaml_token_t *token;
839: if (first) {
840: token = PEEK_TOKEN(parser);
841: if (!PUSH(parser, parser->marks, token->start_mark))
842: return 0;
843: SKIP_TOKEN(parser);
844: }
846: token = PEEK_TOKEN(parser);
847: if (!token) return 0;
849: if (token->type == YAML_KEY_TOKEN)
850: {
851: yaml_mark_t mark = token->end_mark;
852: SKIP_TOKEN(parser);
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))
860: return 0;
861: return yaml_parser_parse_node(parser, event, 1, 1);
862: }
863: else {
864: parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
865: return yaml_parser_process_empty_scalar(parser, event, mark);
866: }
867: }
869: else if (token->type == YAML_BLOCK_END_TOKEN)
870: {
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);
874: SKIP_TOKEN(parser);
875: return 1;
876: }
878: else
879: {
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);
883: }
884: }
886: /*
887: * Parse the productions:
888: * block_mapping ::= BLOCK-MAPPING_START
889: *
890: * ((KEY block_node_or_indentless_sequence?)?
891: *
892: * (VALUE block_node_or_indentless_sequence?)?)*
893: * ***** *
894: * BLOCK-END
895: *
896: */
898: static int
899: yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
900: yaml_event_t *event)
901: {
902: yaml_token_t *token;
904: token = PEEK_TOKEN(parser);
905: if (!token) return 0;
907: if (token->type == YAML_VALUE_TOKEN)
908: {
909: yaml_mark_t mark = token->end_mark;
910: SKIP_TOKEN(parser);
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))
918: return 0;
919: return yaml_parser_parse_node(parser, event, 1, 1);
920: }
921: else {
922: parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
923: return yaml_parser_process_empty_scalar(parser, event, mark);
924: }
925: }
927: else
928: {
929: parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
930: return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
931: }
932: }
934: /*
935: * Parse the productions:
936: * flow_sequence ::= FLOW-SEQUENCE-START
937: * *******************
938: * (flow_sequence_entry FLOW-ENTRY)*
939: * * **********
940: * flow_sequence_entry?
941: * *
942: * FLOW-SEQUENCE-END
943: * *****************
944: * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
945: * *
946: */
948: static int
949: yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
950: yaml_event_t *event, int first)
951: {
952: yaml_token_t *token;
954: if (first) {
955: token = PEEK_TOKEN(parser);
956: if (!PUSH(parser, parser->marks, token->start_mark))
957: return 0;
958: SKIP_TOKEN(parser);
959: }
961: token = PEEK_TOKEN(parser);
962: if (!token) return 0;
964: if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
965: {
966: if (!first) {
967: if (token->type == YAML_FLOW_ENTRY_TOKEN) {
968: SKIP_TOKEN(parser);
969: token = PEEK_TOKEN(parser);
970: if (!token) return 0;
971: }
972: else {
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);
976: }
977: }
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);
984: SKIP_TOKEN(parser);
985: return 1;
986: }
988: else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
989: if (!PUSH(parser, parser->states,
990: YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
991: return 0;
992: return yaml_parser_parse_node(parser, event, 0, 0);
993: }
994: }
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);
999: SKIP_TOKEN(parser);
1000: return 1;
1001: }
1003: /*
1004: * Parse the productions:
1005: * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1006: * *** *
1007: */
1009: static int
1010: yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1011: yaml_event_t *event)
1012: {
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))
1022: return 0;
1023: return yaml_parser_parse_node(parser, event, 0, 0);
1024: }
1025: else {
1026: yaml_mark_t mark = token->end_mark;
1027: SKIP_TOKEN(parser);
1028: parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1029: return yaml_parser_process_empty_scalar(parser, event, mark);
1030: }
1031: }
1033: /*
1034: * Parse the productions:
1035: * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1036: * ***** *
1037: */
1039: static int
1040: yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1041: yaml_event_t *event)
1042: {
1043: yaml_token_t *token;
1045: token = PEEK_TOKEN(parser);
1046: if (!token) return 0;
1048: if (token->type == YAML_VALUE_TOKEN) {
1049: SKIP_TOKEN(parser);
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))
1056: return 0;
1057: return yaml_parser_parse_node(parser, event, 0, 0);
1058: }
1059: }
1060: parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1061: return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1062: }
1064: /*
1065: * Parse the productions:
1066: * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1067: * *
1068: */
1070: static int
1071: yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1072: yaml_event_t *event)
1073: {
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);
1082: return 1;
1083: }
1085: /*
1086: * Parse the productions:
1087: * flow_mapping ::= FLOW-MAPPING-START
1088: * ******************
1089: * (flow_mapping_entry FLOW-ENTRY)*
1090: * * **********
1091: * flow_mapping_entry?
1092: * ******************
1093: * FLOW-MAPPING-END
1094: * ****************
1095: * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1096: * * *** *
1097: */
1099: static int
1100: yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1101: yaml_event_t *event, int first)
1102: {
1103: yaml_token_t *token;
1105: if (first) {
1106: token = PEEK_TOKEN(parser);
1107: if (!PUSH(parser, parser->marks, token->start_mark))
1108: return 0;
1109: SKIP_TOKEN(parser);
1110: }
1112: token = PEEK_TOKEN(parser);
1113: if (!token) return 0;
1115: if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1116: {
1117: if (!first) {
1118: if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1119: SKIP_TOKEN(parser);
1120: token = PEEK_TOKEN(parser);
1121: if (!token) return 0;
1122: }
1123: else {
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);
1127: }
1128: }
1130: if (token->type == YAML_KEY_TOKEN) {
1131: SKIP_TOKEN(parser);
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))
1139: return 0;
1140: return yaml_parser_parse_node(parser, event, 0, 0);
1141: }
1142: else {
1143: parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1144: return yaml_parser_process_empty_scalar(parser, event,
1145: token->start_mark);
1146: }
1147: }
1148: else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1149: if (!PUSH(parser, parser->states,
1150: YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1151: return 0;
1152: return yaml_parser_parse_node(parser, event, 0, 0);
1153: }
1154: }
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);
1159: SKIP_TOKEN(parser);
1160: return 1;
1161: }
1163: /*
1164: * Parse the productions:
1165: * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1166: * * ***** *
1167: */
1169: static int
1170: yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1171: yaml_event_t *event, int empty)
1172: {
1173: yaml_token_t *token;
1175: token = PEEK_TOKEN(parser);
1176: if (!token) return 0;
1178: if (empty) {
1179: parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1180: return yaml_parser_process_empty_scalar(parser, event,
1181: token->start_mark);
1182: }
1184: if (token->type == YAML_VALUE_TOKEN) {
1185: SKIP_TOKEN(parser);
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))
1192: return 0;
1193: return yaml_parser_parse_node(parser, event, 0, 0);
1194: }
1195: }
1197: parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1198: return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1199: }
1201: /*
1202: * Generate an empty scalar event.
1203: */
1205: static int
1206: yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1207: yaml_mark_t mark)
1208: {
1209: yaml_char_t *value;
1211: value = YAML_MALLOC(1);
1212: if (!value) {
1213: parser->error = YAML_MEMORY_ERROR;
1214: return 0;
1215: }
1216: value[0] = '\0';
1218: SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1219: 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1221: return 1;
1222: }
1224: /*
1225: * Parse directives.
1226: */
1228: static int
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)
1233: {
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:"},
1237: {NULL, NULL}
1238: };
1239: yaml_tag_directive_t *default_tag_directive;
1240: yaml_version_directive_t *version_directive = NULL;
1241: struct {
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*))
1249: goto error;
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)
1256: {
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);
1261: goto error;
1262: }
1263: if (token->data.version_directive.major != 1
1264: || (
1265: token->data.version_directive.minor != 1
1266: && token->data.version_directive.minor != 2
1267: )) {
1268: yaml_parser_set_parser_error(parser,
1269: "found incompatible YAML document", token->start_mark);
1270: goto error;
1271: }
1272: version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
1273: if (!version_directive) {
1274: parser->error = YAML_MEMORY_ERROR;
1275: goto error;
1276: }
1277: version_directive->major = token->data.version_directive.major;
1278: version_directive->minor = token->data.version_directive.minor;
1279: }
1281: else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1282: yaml_tag_directive_t value;
1283: value.handle = token->data.tag_directive.handle;
1284: value.prefix = token->data.tag_directive.prefix;
1286: if (!yaml_parser_append_tag_directive(parser, value, 0,
1287: token->start_mark))
1288: goto error;
1289: if (!PUSH(parser, tag_directives, value))
1290: goto error;
1291: }
1293: SKIP_TOKEN(parser);
1294: token = PEEK_TOKEN(parser);
1295: if (!token) goto error;
1296: }
1298: for (default_tag_directive = default_tag_directives;
1299: default_tag_directive->handle; default_tag_directive++) {
1300: if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1301: token->start_mark))
1302: goto error;
1303: }
1305: if (version_directive_ref) {
1306: *version_directive_ref = version_directive;
1307: }
1308: if (tag_directives_start_ref) {
1309: if (STACK_EMPTY(parser, tag_directives)) {
1310: *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1311: STACK_DEL(parser, tag_directives);
1312: }
1313: else {
1314: *tag_directives_start_ref = tag_directives.start;
1315: *tag_directives_end_ref = tag_directives.top;
1316: }
1317: }
1318: else {
1319: STACK_DEL(parser, tag_directives);
1320: }
1322: if (!version_directive_ref)
1323: yaml_free(version_directive);
1324: return 1;
1326: error:
1327: yaml_free(version_directive);
1328: while (!STACK_EMPTY(parser, tag_directives)) {
1329: yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1330: yaml_free(tag_directive.handle);
1331: yaml_free(tag_directive.prefix);
1332: }
1333: STACK_DEL(parser, tag_directives);
1334: return 0;
1335: }
1337: /*
1338: * Append a tag directive to the directives stack.
1339: */
1341: static int
1342: yaml_parser_append_tag_directive(yaml_parser_t *parser,
1343: yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1344: {
1345: yaml_tag_directive_t *tag_directive;
1346: yaml_tag_directive_t copy = { NULL, NULL };
1348: for (tag_directive = parser->tag_directives.start;
1349: tag_directive != parser->tag_directives.top; tag_directive ++) {
1350: if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1351: if (allow_duplicates)
1352: return 1;
1353: return yaml_parser_set_parser_error(parser,
1354: "found duplicate %TAG directive", mark);
1355: }
1356: }
1358: copy.handle = yaml_strdup(value.handle);
1359: copy.prefix = yaml_strdup(value.prefix);
1360: if (!copy.handle || !copy.prefix) {
1361: parser->error = YAML_MEMORY_ERROR;
1362: goto error;
1363: }
1365: if (!PUSH(parser, parser->tag_directives, copy))
1366: goto error;
1368: return 1;
1370: error:
1371: yaml_free(copy.handle);
1372: yaml_free(copy.prefix);
1373: return 0;
1374: }