]> andersk Git - libyaml.git/blame - src/parser.c
Add Emitter definitions and implement the Writer.
[libyaml.git] / src / parser.c
CommitLineData
1eb01be7
KS
1
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 */
41
625fcfe9 42#include "yaml_private.h"
1eb01be7 43
1eb01be7 44/*
625fcfe9 45 * Peek the next token in the token queue.
1eb01be7
KS
46 */
47
625fcfe9
KS
48#define PEEK_TOKEN(parser) \
49 ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
50 parser->tokens.head : NULL)
1eb01be7 51
625fcfe9
KS
52/*
53 * Remove the next token from the queue (must be called after PEEK_TOKEN).
54 */
55
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 ++)
62
63/*
64 * Public API declarations.
65 */
66
67YAML_DECLARE(int)
68yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
1eb01be7 69
52fba2c6
KS
70/*
71 * Error handling.
72 */
73
74static int
75yaml_parser_set_parser_error(yaml_parser_t *parser,
76 const char *problem, yaml_mark_t problem_mark);
77
78static int
79yaml_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);
82
83/*
625fcfe9 84 * State functions.
52fba2c6
KS
85 */
86
87static int
625fcfe9 88yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
52fba2c6 89
ab01bac8 90static int
625fcfe9 91yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
ab01bac8 92
52fba2c6 93static int
625fcfe9
KS
94yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
95 int implicit);
52fba2c6
KS
96
97static int
625fcfe9 98yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
1eb01be7 99
625fcfe9
KS
100static int
101yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
1eb01be7 102
625fcfe9
KS
103static int
104yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
1eb01be7
KS
105 int block, int indentless_sequence);
106
625fcfe9
KS
107static int
108yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109 yaml_event_t *event, int first);
1eb01be7 110
625fcfe9
KS
111static int
112yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113 yaml_event_t *event);
1eb01be7 114
625fcfe9
KS
115static int
116yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117 yaml_event_t *event, int first);
1eb01be7 118
625fcfe9
KS
119static int
120yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121 yaml_event_t *event);
1eb01be7 122
625fcfe9
KS
123static int
124yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125 yaml_event_t *event, int first);
1eb01be7 126
625fcfe9
KS
127static int
128yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129 yaml_event_t *event);
1eb01be7 130
625fcfe9
KS
131static int
132yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133 yaml_event_t *event);
1eb01be7 134
625fcfe9
KS
135static int
136yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137 yaml_event_t *event);
1eb01be7 138
625fcfe9
KS
139static int
140yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141 yaml_event_t *event, int first);
1eb01be7 142
625fcfe9
KS
143static int
144yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145 yaml_event_t *event, int empty);
1eb01be7 146
52fba2c6
KS
147/*
148 * Utility functions.
149 */
150
625fcfe9
KS
151static int
152yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153 yaml_event_t *event, yaml_mark_t mark);
52fba2c6
KS
154
155static int
625fcfe9
KS
156yaml_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);
160
161static int
162yaml_parser_append_tag_directive(yaml_parser_t *parser,
163 yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
52fba2c6 164
1eb01be7 165/*
625fcfe9 166 * Get the next event.
1eb01be7
KS
167 */
168
625fcfe9
KS
169YAML_DECLARE(int)
170yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
1eb01be7 171{
625fcfe9
KS
172 assert(parser); /* Non-NULL parser object is expected. */
173 assert(event); /* Non-NULL event object is expected. */
1eb01be7 174
625fcfe9 175 /* No events after the end of the stream or error. */
1eb01be7 176
625fcfe9
KS
177 if (parser->stream_end_produced || parser->error ||
178 parser->state == YAML_PARSE_END_STATE) {
179 memset(event, 0, sizeof(yaml_event_t));
1eb01be7 180
625fcfe9 181 return 1;
1eb01be7
KS
182 }
183
625fcfe9 184 /* Generate the next event. */
1eb01be7 185
625fcfe9 186 return yaml_parser_state_machine(parser, event);
1eb01be7
KS
187}
188
52fba2c6
KS
189/*
190 * Set parser error.
191 */
192
193static int
194yaml_parser_set_parser_error(yaml_parser_t *parser,
195 const char *problem, yaml_mark_t problem_mark)
196{
197 parser->error = YAML_PARSER_ERROR;
198 parser->problem = problem;
199 parser->problem_mark = problem_mark;
200
201 return 0;
202}
203
204static int
205yaml_parser_set_parser_error_context(yaml_parser_t *parser,
206 const char *context, yaml_mark_t context_mark,
207 const char *problem, yaml_mark_t problem_mark)
208{
209 parser->error = YAML_PARSER_ERROR;
210 parser->context = context;
211 parser->context_mark = context_mark;
212 parser->problem = problem;
213 parser->problem_mark = problem_mark;
214
215 return 0;
216}
217
52fba2c6 218
1eb01be7
KS
219/*
220 * State dispatcher.
221 */
222
625fcfe9
KS
223static int
224yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
1eb01be7 225{
1eb01be7
KS
226 switch (parser->state)
227 {
228 case YAML_PARSE_STREAM_START_STATE:
625fcfe9 229 return yaml_parser_parse_stream_start(parser, event);
1eb01be7
KS
230
231 case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
625fcfe9 232 return yaml_parser_parse_document_start(parser, event, 1);
1eb01be7
KS
233
234 case YAML_PARSE_DOCUMENT_START_STATE:
625fcfe9 235 return yaml_parser_parse_document_start(parser, event, 0);
1eb01be7
KS
236
237 case YAML_PARSE_DOCUMENT_CONTENT_STATE:
625fcfe9 238 return yaml_parser_parse_document_content(parser, event);
1eb01be7
KS
239
240 case YAML_PARSE_DOCUMENT_END_STATE:
625fcfe9 241 return yaml_parser_parse_document_end(parser, event);
1eb01be7
KS
242
243 case YAML_PARSE_BLOCK_NODE_STATE:
625fcfe9 244 return yaml_parser_parse_node(parser, event, 1, 0);
1eb01be7
KS
245
246 case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
625fcfe9 247 return yaml_parser_parse_node(parser, event, 1, 1);
1eb01be7
KS
248
249 case YAML_PARSE_FLOW_NODE_STATE:
625fcfe9 250 return yaml_parser_parse_node(parser, event, 0, 0);
1eb01be7
KS
251
252 case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
625fcfe9 253 return yaml_parser_parse_block_sequence_entry(parser, event, 1);
1eb01be7
KS
254
255 case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
625fcfe9 256 return yaml_parser_parse_block_sequence_entry(parser, event, 0);
1eb01be7
KS
257
258 case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
625fcfe9 259 return yaml_parser_parse_indentless_sequence_entry(parser, event);
1eb01be7
KS
260
261 case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
625fcfe9 262 return yaml_parser_parse_block_mapping_key(parser, event, 1);
1eb01be7
KS
263
264 case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
625fcfe9 265 return yaml_parser_parse_block_mapping_key(parser, event, 0);
1eb01be7
KS
266
267 case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
625fcfe9 268 return yaml_parser_parse_block_mapping_value(parser, event);
1eb01be7
KS
269
270 case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
625fcfe9 271 return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
1eb01be7
KS
272
273 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
625fcfe9 274 return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
1eb01be7
KS
275
276 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
625fcfe9 277 return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
1eb01be7
KS
278
279 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
625fcfe9 280 return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
1eb01be7
KS
281
282 case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
625fcfe9 283 return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
1eb01be7
KS
284
285 case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
625fcfe9 286 return yaml_parser_parse_flow_mapping_key(parser, event, 1);
1eb01be7
KS
287
288 case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
625fcfe9 289 return yaml_parser_parse_flow_mapping_key(parser, event, 0);
1eb01be7
KS
290
291 case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
625fcfe9 292 return yaml_parser_parse_flow_mapping_value(parser, event, 0);
1eb01be7
KS
293
294 case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
625fcfe9
KS
295 return yaml_parser_parse_flow_mapping_value(parser, event, 1);
296
297 default:
298 assert(1); /* Invalid state. */
1eb01be7 299 }
54815ffd
KS
300
301 return 0;
1eb01be7
KS
302}
303
52fba2c6
KS
304/*
305 * Parse the production:
306 * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
307 * ************
308 */
309
625fcfe9
KS
310static int
311yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
52fba2c6
KS
312{
313 yaml_token_t *token;
52fba2c6 314
625fcfe9
KS
315 token = PEEK_TOKEN(parser);
316 if (!token) return 0;
52fba2c6 317
625fcfe9
KS
318 if (token->type != YAML_STREAM_START_TOKEN) {
319 return yaml_parser_set_parser_error(parser,
320 "did not found expected <stream-start>", token->start_mark);
52fba2c6
KS
321 }
322
323 parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
625fcfe9
KS
324 STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
325 token->start_mark, token->start_mark);
326 SKIP_TOKEN(parser);
52fba2c6 327
625fcfe9 328 return 1;
52fba2c6
KS
329}
330
331/*
332 * Parse the productions:
333 * implicit_document ::= block_node DOCUMENT-END*
334 * *
335 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
336 * *************************
337 */
338
625fcfe9
KS
339static int
340yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
341 int implicit)
52fba2c6
KS
342{
343 yaml_token_t *token;
625fcfe9
KS
344 yaml_version_directive_t *version_directive = NULL;
345 struct {
346 yaml_tag_directive_t *start;
347 yaml_tag_directive_t *end;
348 } tag_directives = { NULL, NULL };
52fba2c6 349
625fcfe9
KS
350 token = PEEK_TOKEN(parser);
351 if (!token) return 0;
52fba2c6
KS
352
353 /* Parse an implicit document. */
354
355 if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
356 token->type != YAML_TAG_DIRECTIVE_TOKEN &&
357 token->type != YAML_DOCUMENT_START_TOKEN &&
358 token->type != YAML_STREAM_END_TOKEN)
359 {
625fcfe9
KS
360 if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
361 return 0;
362 if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
363 return 0;
52fba2c6 364 parser->state = YAML_PARSE_BLOCK_NODE_STATE;
625fcfe9 365 DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
52fba2c6 366 token->start_mark, token->start_mark);
625fcfe9 367 return 1;
52fba2c6
KS
368 }
369
370 /* Parse an explicit document. */
371
372 else if (token->type != YAML_STREAM_END_TOKEN)
373 {
374 yaml_mark_t start_mark, end_mark;
375 start_mark = token->start_mark;
625fcfe9
KS
376 if (!yaml_parser_process_directives(parser, &version_directive,
377 &tag_directives.start, &tag_directives.end))
378 return 0;
379 token = PEEK_TOKEN(parser);
380 if (!token) goto error;
52fba2c6
KS
381 if (token->type != YAML_DOCUMENT_START_TOKEN) {
382 yaml_parser_set_parser_error(parser,
383 "did not found expected <document start>", token->start_mark);
625fcfe9 384 goto error;
52fba2c6 385 }
625fcfe9
KS
386 if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
387 goto error;
52fba2c6 388 parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
625fcfe9
KS
389 end_mark = token->end_mark;
390 DOCUMENT_START_EVENT_INIT(*event, version_directive,
391 tag_directives.start, tag_directives.end, 0,
52fba2c6 392 start_mark, end_mark);
625fcfe9
KS
393 SKIP_TOKEN(parser);
394 version_directive = NULL;
395 tag_directives.start = tag_directives.end = NULL;
396 return 1;
52fba2c6
KS
397 }
398
399 /* Parse the stream end. */
400
401 else
402 {
52fba2c6 403 parser->state = YAML_PARSE_END_STATE;
625fcfe9
KS
404 STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
405 SKIP_TOKEN(parser);
406 return 1;
52fba2c6 407 }
625fcfe9
KS
408
409error:
410 yaml_free(version_directive);
411 while (tag_directives.start != tag_directives.end) {
412 yaml_free(tag_directives.end[-1].handle);
413 yaml_free(tag_directives.end[-1].prefix);
414 tag_directives.end --;
415 }
416 yaml_free(tag_directives.start);
417 return 0;
52fba2c6
KS
418}
419
420/*
421 * Parse the productions:
422 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
423 * ***********
424 */
425
625fcfe9
KS
426static int
427yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
52fba2c6
KS
428{
429 yaml_token_t *token;
430
625fcfe9
KS
431 token = PEEK_TOKEN(parser);
432 if (!token) return 0;
52fba2c6
KS
433
434 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
435 token->type == YAML_TAG_DIRECTIVE_TOKEN ||
436 token->type == YAML_DOCUMENT_START_TOKEN ||
437 token->type == YAML_DOCUMENT_END_TOKEN ||
438 token->type == YAML_STREAM_END_TOKEN) {
625fcfe9
KS
439 parser->state = POP(parser, parser->states);
440 return yaml_parser_process_empty_scalar(parser, event,
441 token->start_mark);
52fba2c6
KS
442 }
443 else {
625fcfe9 444 return yaml_parser_parse_node(parser, event, 1, 0);
52fba2c6
KS
445 }
446}
447
448/*
449 * Parse the productions:
450 * implicit_document ::= block_node DOCUMENT-END*
451 * *************
452 * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
453 * *************
454 */
455
625fcfe9
KS
456static int
457yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
52fba2c6
KS
458{
459 yaml_token_t *token;
52fba2c6
KS
460 yaml_mark_t start_mark, end_mark;
461 int implicit = 1;
462
625fcfe9
KS
463 token = PEEK_TOKEN(parser);
464 if (!token) return 0;
52fba2c6
KS
465
466 start_mark = end_mark = token->start_mark;
467
468 while (token->type == YAML_DOCUMENT_END_TOKEN) {
469 end_mark = token->end_mark;
625fcfe9
KS
470 SKIP_TOKEN(parser);
471 token = PEEK_TOKEN(parser);
472 if (!token) return 0;
52fba2c6
KS
473 implicit = 0;
474 }
475
625fcfe9
KS
476 while (!STACK_EMPTY(parser, parser->tag_directives)) {
477 yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
478 yaml_free(tag_directive.handle);
479 yaml_free(tag_directive.prefix);
ab01bac8 480 }
ab01bac8 481
ab01bac8 482 parser->state = YAML_PARSE_DOCUMENT_START_STATE;
625fcfe9 483 DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
ab01bac8 484
625fcfe9 485 return 1;
52fba2c6
KS
486}
487
488/*
489 * Parse the productions:
490 * block_node_or_indentless_sequence ::=
491 * ALIAS
492 * *****
493 * | properties (block_content | indentless_block_sequence)?
494 * ********** *
495 * | block_content | indentless_block_sequence
496 * *
497 * block_node ::= ALIAS
498 * *****
499 * | properties block_content?
500 * ********** *
501 * | block_content
502 * *
503 * flow_node ::= ALIAS
504 * *****
505 * | properties flow_content?
506 * ********** *
507 * | flow_content
508 * *
509 * properties ::= TAG ANCHOR? | ANCHOR TAG?
510 * *************************
511 * block_content ::= block_collection | flow_collection | SCALAR
512 * ******
513 * flow_content ::= flow_collection | SCALAR
514 * ******
515 */
516
625fcfe9
KS
517static int
518yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
52fba2c6
KS
519 int block, int indentless_sequence)
520{
521 yaml_token_t *token;
52fba2c6
KS
522 yaml_char_t *anchor = NULL;
523 yaml_char_t *tag_handle = NULL;
524 yaml_char_t *tag_suffix = NULL;
525 yaml_char_t *tag = NULL;
526 yaml_mark_t start_mark, end_mark, tag_mark;
527 int implicit;
528
625fcfe9
KS
529 token = PEEK_TOKEN(parser);
530 if (!token) return 0;
52fba2c6
KS
531
532 if (token->type == YAML_ALIAS_TOKEN)
533 {
625fcfe9
KS
534 parser->state = POP(parser, parser->states);
535 ALIAS_EVENT_INIT(*event, token->data.alias.value,
52fba2c6 536 token->start_mark, token->end_mark);
625fcfe9
KS
537 SKIP_TOKEN(parser);
538 return 1;
52fba2c6
KS
539 }
540
541 else
542 {
543 start_mark = end_mark = token->start_mark;
544
545 if (token->type == YAML_ANCHOR_TOKEN)
546 {
52fba2c6
KS
547 anchor = token->data.anchor.value;
548 start_mark = token->start_mark;
549 end_mark = token->end_mark;
625fcfe9
KS
550 SKIP_TOKEN(parser);
551 token = PEEK_TOKEN(parser);
52fba2c6
KS
552 if (!token) goto error;
553 if (token->type == YAML_TAG_TOKEN)
554 {
52fba2c6
KS
555 tag_handle = token->data.tag.handle;
556 tag_suffix = token->data.tag.suffix;
557 tag_mark = token->start_mark;
558 end_mark = token->end_mark;
625fcfe9
KS
559 SKIP_TOKEN(parser);
560 token = PEEK_TOKEN(parser);
52fba2c6
KS
561 if (!token) goto error;
562 }
563 }
564 else if (token->type == YAML_TAG_TOKEN)
565 {
52fba2c6
KS
566 tag_handle = token->data.tag.handle;
567 tag_suffix = token->data.tag.suffix;
568 start_mark = tag_mark = token->start_mark;
569 end_mark = token->end_mark;
625fcfe9
KS
570 SKIP_TOKEN(parser);
571 token = PEEK_TOKEN(parser);
52fba2c6
KS
572 if (!token) goto error;
573 if (token->type == YAML_ANCHOR_TOKEN)
574 {
52fba2c6
KS
575 anchor = token->data.anchor.value;
576 end_mark = token->end_mark;
625fcfe9
KS
577 SKIP_TOKEN(parser);
578 token = PEEK_TOKEN(parser);
52fba2c6
KS
579 if (!token) goto error;
580 }
581 }
582
583 if (tag_handle) {
584 if (!*tag_handle) {
585 tag = tag_suffix;
586 yaml_free(tag_handle);
587 tag_handle = tag_suffix = NULL;
588 }
589 else {
625fcfe9
KS
590 yaml_tag_directive_t *tag_directive;
591 for (tag_directive = parser->tag_directives.start;
592 tag_directive != parser->tag_directives.top;
593 tag_directive ++) {
594 if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
595 size_t prefix_len = strlen((char *)tag_directive->prefix);
52fba2c6
KS
596 size_t suffix_len = strlen((char *)tag_suffix);
597 tag = yaml_malloc(prefix_len+suffix_len+1);
598 if (!tag) {
599 parser->error = YAML_MEMORY_ERROR;
600 goto error;
601 }
625fcfe9 602 memcpy(tag, tag_directive->prefix, prefix_len);
52fba2c6
KS
603 memcpy(tag+prefix_len, tag_suffix, suffix_len);
604 tag[prefix_len+suffix_len] = '\0';
605 yaml_free(tag_handle);
606 yaml_free(tag_suffix);
607 tag_handle = tag_suffix = NULL;
608 break;
609 }
610 }
625fcfe9 611 if (!tag) {
52fba2c6
KS
612 yaml_parser_set_parser_error_context(parser,
613 "while parsing a node", start_mark,
614 "found undefined tag handle", tag_mark);
615 goto error;
616 }
617 }
618 }
619
620 implicit = (!tag || !*tag);
621 if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
622 end_mark = token->end_mark;
623 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
625fcfe9 624 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
52fba2c6 625 YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
625fcfe9 626 return 1;
52fba2c6
KS
627 }
628 else {
629 if (token->type == YAML_SCALAR_TOKEN) {
630 int plain_implicit = 0;
631 int quoted_implicit = 0;
52fba2c6
KS
632 end_mark = token->end_mark;
633 if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
ab01bac8 634 || (tag && strcmp((char *)tag, "!") == 0)) {
52fba2c6
KS
635 plain_implicit = 1;
636 }
637 else if (!tag) {
638 quoted_implicit = 1;
639 }
625fcfe9
KS
640 parser->state = POP(parser, parser->states);
641 SCALAR_EVENT_INIT(*event, anchor, tag,
52fba2c6
KS
642 token->data.scalar.value, token->data.scalar.length,
643 plain_implicit, quoted_implicit,
644 token->data.scalar.style, start_mark, end_mark);
625fcfe9
KS
645 SKIP_TOKEN(parser);
646 return 1;
52fba2c6
KS
647 }
648 else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
649 end_mark = token->end_mark;
650 parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
625fcfe9 651 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
52fba2c6 652 YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
625fcfe9 653 return 1;
52fba2c6
KS
654 }
655 else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
656 end_mark = token->end_mark;
657 parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
625fcfe9 658 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
52fba2c6 659 YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
625fcfe9 660 return 1;
52fba2c6
KS
661 }
662 else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
663 end_mark = token->end_mark;
664 parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
625fcfe9 665 SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
52fba2c6 666 YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
625fcfe9 667 return 1;
52fba2c6
KS
668 }
669 else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
670 end_mark = token->end_mark;
671 parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
625fcfe9 672 MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
52fba2c6 673 YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
625fcfe9 674 return 1;
52fba2c6
KS
675 }
676 else if (anchor || tag) {
677 yaml_char_t *value = yaml_malloc(1);
678 if (!value) {
679 parser->error = YAML_MEMORY_ERROR;
680 goto error;
681 }
682 value[0] = '\0';
625fcfe9
KS
683 parser->state = POP(parser, parser->states);
684 SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
52fba2c6
KS
685 implicit, 0, YAML_PLAIN_SCALAR_STYLE,
686 start_mark, end_mark);
625fcfe9 687 return 1;
52fba2c6
KS
688 }
689 else {
690 yaml_parser_set_parser_error_context(parser,
691 (block ? "while parsing a block node"
692 : "while parsing a flow node"), start_mark,
693 "did not found expected node content", token->start_mark);
694 goto error;
695 }
52fba2c6
KS
696 }
697 }
698
699error:
700 yaml_free(anchor);
701 yaml_free(tag_handle);
702 yaml_free(tag_suffix);
703 yaml_free(tag);
704
625fcfe9 705 return 0;
52fba2c6
KS
706}
707
708/*
709 * Parse the productions:
710 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
711 * ******************** *********** * *********
712 */
713
625fcfe9
KS
714static int
715yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
716 yaml_event_t *event, int first)
52fba2c6
KS
717{
718 yaml_token_t *token;
52fba2c6
KS
719
720 if (first) {
625fcfe9
KS
721 token = PEEK_TOKEN(parser);
722 if (!PUSH(parser, parser->marks, token->start_mark))
723 return 0;
724 SKIP_TOKEN(parser);
52fba2c6
KS
725 }
726
625fcfe9
KS
727 token = PEEK_TOKEN(parser);
728 if (!token) return 0;
52fba2c6
KS
729
730 if (token->type == YAML_BLOCK_ENTRY_TOKEN)
731 {
732 yaml_mark_t mark = token->end_mark;
625fcfe9
KS
733 SKIP_TOKEN(parser);
734 token = PEEK_TOKEN(parser);
735 if (!token) return 0;
52fba2c6
KS
736 if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
737 token->type != YAML_BLOCK_END_TOKEN) {
625fcfe9 738 if (!PUSH(parser, parser->states,
52fba2c6 739 YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
625fcfe9
KS
740 return 0;
741 return yaml_parser_parse_node(parser, event, 1, 0);
52fba2c6
KS
742 }
743 else {
744 parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
625fcfe9 745 return yaml_parser_process_empty_scalar(parser, event, mark);
52fba2c6
KS
746 }
747 }
748
749 else if (token->type == YAML_BLOCK_END_TOKEN)
750 {
625fcfe9
KS
751 parser->state = POP(parser, parser->states);
752 POP(parser, parser->marks);
753 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
754 SKIP_TOKEN(parser);
755 return 1;
52fba2c6
KS
756 }
757
758 else
759 {
625fcfe9
KS
760 return yaml_parser_set_parser_error_context(parser,
761 "while parsing a block collection", POP(parser, parser->marks),
52fba2c6 762 "did not found expected '-' indicator", token->start_mark);
52fba2c6
KS
763 }
764}
765
766/*
767 * Parse the productions:
768 * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
769 * *********** *
770 */
771
625fcfe9
KS
772static int
773yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
774 yaml_event_t *event)
52fba2c6
KS
775{
776 yaml_token_t *token;
52fba2c6 777
625fcfe9
KS
778 token = PEEK_TOKEN(parser);
779 if (!token) return 0;
52fba2c6
KS
780
781 if (token->type == YAML_BLOCK_ENTRY_TOKEN)
782 {
783 yaml_mark_t mark = token->end_mark;
625fcfe9
KS
784 SKIP_TOKEN(parser);
785 token = PEEK_TOKEN(parser);
786 if (!token) return 0;
52fba2c6 787 if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
625fcfe9
KS
788 token->type != YAML_KEY_TOKEN &&
789 token->type != YAML_VALUE_TOKEN &&
52fba2c6 790 token->type != YAML_BLOCK_END_TOKEN) {
625fcfe9 791 if (!PUSH(parser, parser->states,
52fba2c6 792 YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
625fcfe9
KS
793 return 0;
794 return yaml_parser_parse_node(parser, event, 1, 0);
52fba2c6
KS
795 }
796 else {
797 parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
625fcfe9 798 return yaml_parser_process_empty_scalar(parser, event, mark);
52fba2c6
KS
799 }
800 }
801
802 else
803 {
625fcfe9
KS
804 parser->state = POP(parser, parser->states);
805 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
806 return 1;
52fba2c6
KS
807 }
808}
809
810/*
811 * Parse the productions:
812 * block_mapping ::= BLOCK-MAPPING_START
813 * *******************
814 * ((KEY block_node_or_indentless_sequence?)?
815 * *** *
816 * (VALUE block_node_or_indentless_sequence?)?)*
817 *
818 * BLOCK-END
819 * *********
820 */
821
625fcfe9
KS
822static int
823yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
824 yaml_event_t *event, int first)
52fba2c6
KS
825{
826 yaml_token_t *token;
52fba2c6
KS
827
828 if (first) {
625fcfe9
KS
829 token = PEEK_TOKEN(parser);
830 if (!PUSH(parser, parser->marks, token->start_mark))
831 return 0;
832 SKIP_TOKEN(parser);
52fba2c6
KS
833 }
834
625fcfe9
KS
835 token = PEEK_TOKEN(parser);
836 if (!token) return 0;
52fba2c6
KS
837
838 if (token->type == YAML_KEY_TOKEN)
839 {
840 yaml_mark_t mark = token->end_mark;
625fcfe9
KS
841 SKIP_TOKEN(parser);
842 token = PEEK_TOKEN(parser);
843 if (!token) return 0;
52fba2c6
KS
844 if (token->type != YAML_KEY_TOKEN &&
845 token->type != YAML_VALUE_TOKEN &&
846 token->type != YAML_BLOCK_END_TOKEN) {
625fcfe9 847 if (!PUSH(parser, parser->states,
52fba2c6 848 YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
625fcfe9
KS
849 return 0;
850 return yaml_parser_parse_node(parser, event, 1, 1);
52fba2c6
KS
851 }
852 else {
853 parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
625fcfe9 854 return yaml_parser_process_empty_scalar(parser, event, mark);
52fba2c6
KS
855 }
856 }
857
858 else if (token->type == YAML_BLOCK_END_TOKEN)
859 {
625fcfe9
KS
860 parser->state = POP(parser, parser->states);
861 POP(parser, parser->marks);
862 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
863 SKIP_TOKEN(parser);
864 return 1;
52fba2c6
KS
865 }
866
867 else
868 {
625fcfe9
KS
869 return yaml_parser_set_parser_error_context(parser,
870 "while parsing a block mapping", POP(parser, parser->marks),
52fba2c6 871 "did not found expected key", token->start_mark);
52fba2c6
KS
872 }
873}
874
875/*
876 * Parse the productions:
877 * block_mapping ::= BLOCK-MAPPING_START
878 *
879 * ((KEY block_node_or_indentless_sequence?)?
880 *
881 * (VALUE block_node_or_indentless_sequence?)?)*
882 * ***** *
883 * BLOCK-END
884 *
885 */
886
625fcfe9
KS
887static int
888yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
889 yaml_event_t *event)
52fba2c6
KS
890{
891 yaml_token_t *token;
52fba2c6 892
625fcfe9
KS
893 token = PEEK_TOKEN(parser);
894 if (!token) return 0;
52fba2c6
KS
895
896 if (token->type == YAML_VALUE_TOKEN)
897 {
898 yaml_mark_t mark = token->end_mark;
625fcfe9
KS
899 SKIP_TOKEN(parser);
900 token = PEEK_TOKEN(parser);
901 if (!token) return 0;
52fba2c6
KS
902 if (token->type != YAML_KEY_TOKEN &&
903 token->type != YAML_VALUE_TOKEN &&
904 token->type != YAML_BLOCK_END_TOKEN) {
625fcfe9 905 if (!PUSH(parser, parser->states,
52fba2c6 906 YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
625fcfe9
KS
907 return 0;
908 return yaml_parser_parse_node(parser, event, 1, 1);
52fba2c6
KS
909 }
910 else {
911 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
625fcfe9 912 return yaml_parser_process_empty_scalar(parser, event, mark);
52fba2c6
KS
913 }
914 }
915
916 else
917 {
918 parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
625fcfe9 919 return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
52fba2c6
KS
920 }
921}
922
ab01bac8
KS
923/*
924 * Parse the productions:
925 * flow_sequence ::= FLOW-SEQUENCE-START
926 * *******************
927 * (flow_sequence_entry FLOW-ENTRY)*
928 * * **********
929 * flow_sequence_entry?
930 * *
931 * FLOW-SEQUENCE-END
932 * *****************
933 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
934 * *
935 */
936
625fcfe9
KS
937static int
938yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
939 yaml_event_t *event, int first)
ab01bac8
KS
940{
941 yaml_token_t *token;
ab01bac8
KS
942
943 if (first) {
625fcfe9
KS
944 token = PEEK_TOKEN(parser);
945 if (!PUSH(parser, parser->marks, token->start_mark))
946 return 0;
947 SKIP_TOKEN(parser);
ab01bac8
KS
948 }
949
625fcfe9
KS
950 token = PEEK_TOKEN(parser);
951 if (!token) return 0;
ab01bac8
KS
952
953 if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
954 {
955 if (!first) {
956 if (token->type == YAML_FLOW_ENTRY_TOKEN) {
625fcfe9
KS
957 SKIP_TOKEN(parser);
958 token = PEEK_TOKEN(parser);
959 if (!token) return 0;
ab01bac8
KS
960 }
961 else {
625fcfe9
KS
962 return yaml_parser_set_parser_error_context(parser,
963 "while parsing a flow sequence", POP(parser, parser->marks),
ab01bac8 964 "did not found expected ',' or ']'", token->start_mark);
ab01bac8
KS
965 }
966 }
967
968 if (token->type == YAML_KEY_TOKEN) {
ab01bac8 969 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
625fcfe9 970 MAPPING_START_EVENT_INIT(*event, NULL, NULL,
ab01bac8
KS
971 1, YAML_FLOW_MAPPING_STYLE,
972 token->start_mark, token->end_mark);
625fcfe9
KS
973 SKIP_TOKEN(parser);
974 return 1;
ab01bac8
KS
975 }
976
977 else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
625fcfe9 978 if (!PUSH(parser, parser->states,
ab01bac8 979 YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
625fcfe9
KS
980 return 0;
981 return yaml_parser_parse_node(parser, event, 0, 0);
ab01bac8
KS
982 }
983 }
984
625fcfe9
KS
985 parser->state = POP(parser, parser->states);
986 POP(parser, parser->marks);
987 SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
988 SKIP_TOKEN(parser);
989 return 1;
ab01bac8
KS
990}
991
992/*
993 * Parse the productions:
994 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
995 * *** *
996 */
52fba2c6 997
625fcfe9
KS
998static int
999yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1000 yaml_event_t *event)
ab01bac8
KS
1001{
1002 yaml_token_t *token;
ab01bac8 1003
625fcfe9
KS
1004 token = PEEK_TOKEN(parser);
1005 if (!token) return 0;
ab01bac8
KS
1006
1007 if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1008 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
625fcfe9 1009 if (!PUSH(parser, parser->states,
ab01bac8 1010 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
625fcfe9
KS
1011 return 0;
1012 return yaml_parser_parse_node(parser, event, 0, 0);
ab01bac8
KS
1013 }
1014 else {
625fcfe9
KS
1015 yaml_mark_t mark = token->end_mark;
1016 SKIP_TOKEN(parser);
ab01bac8 1017 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
625fcfe9 1018 return yaml_parser_process_empty_scalar(parser, event, mark);
ab01bac8
KS
1019 }
1020}
1021
1022/*
1023 * Parse the productions:
1024 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1025 * ***** *
1026 */
52fba2c6 1027
625fcfe9
KS
1028static int
1029yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1030 yaml_event_t *event)
ab01bac8
KS
1031{
1032 yaml_token_t *token;
1033
625fcfe9
KS
1034 token = PEEK_TOKEN(parser);
1035 if (!token) return 0;
ab01bac8
KS
1036
1037 if (token->type == YAML_VALUE_TOKEN) {
625fcfe9
KS
1038 SKIP_TOKEN(parser);
1039 token = PEEK_TOKEN(parser);
1040 if (!token) return 0;
ab01bac8
KS
1041 if (token->type != YAML_FLOW_ENTRY_TOKEN
1042 && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
625fcfe9 1043 if (!PUSH(parser, parser->states,
ab01bac8 1044 YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
625fcfe9
KS
1045 return 0;
1046 return yaml_parser_parse_node(parser, event, 0, 0);
ab01bac8
KS
1047 }
1048 }
1049 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
625fcfe9 1050 return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
ab01bac8
KS
1051}
1052
1053/*
1054 * Parse the productions:
1055 * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1056 * *
1057 */
52fba2c6 1058
625fcfe9
KS
1059static int
1060yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1061 yaml_event_t *event)
ab01bac8
KS
1062{
1063 yaml_token_t *token;
1064
625fcfe9
KS
1065 token = PEEK_TOKEN(parser);
1066 if (!token) return 0;
ab01bac8
KS
1067
1068 parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1069
625fcfe9
KS
1070 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1071 return 1;
ab01bac8
KS
1072}
1073
1074/*
1075 * Parse the productions:
1076 * flow_mapping ::= FLOW-MAPPING-START
1077 * ******************
1078 * (flow_mapping_entry FLOW-ENTRY)*
1079 * * **********
1080 * flow_mapping_entry?
1081 * ******************
1082 * FLOW-MAPPING-END
1083 * ****************
1084 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1085 * * *** *
1086 */
52fba2c6 1087
625fcfe9
KS
1088static int
1089yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1090 yaml_event_t *event, int first)
ab01bac8
KS
1091{
1092 yaml_token_t *token;
ab01bac8
KS
1093
1094 if (first) {
625fcfe9
KS
1095 token = PEEK_TOKEN(parser);
1096 if (!PUSH(parser, parser->marks, token->start_mark))
1097 return 0;
1098 SKIP_TOKEN(parser);
ab01bac8
KS
1099 }
1100
625fcfe9
KS
1101 token = PEEK_TOKEN(parser);
1102 if (!token) return 0;
ab01bac8
KS
1103
1104 if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1105 {
1106 if (!first) {
1107 if (token->type == YAML_FLOW_ENTRY_TOKEN) {
625fcfe9
KS
1108 SKIP_TOKEN(parser);
1109 token = PEEK_TOKEN(parser);
1110 if (!token) return 0;
ab01bac8
KS
1111 }
1112 else {
625fcfe9
KS
1113 return yaml_parser_set_parser_error_context(parser,
1114 "while parsing a flow mapping", POP(parser, parser->marks),
ab01bac8 1115 "did not found expected ',' or '}'", token->start_mark);
ab01bac8
KS
1116 }
1117 }
1118
1119 if (token->type == YAML_KEY_TOKEN) {
625fcfe9
KS
1120 SKIP_TOKEN(parser);
1121 token = PEEK_TOKEN(parser);
1122 if (!token) return 0;
ab01bac8
KS
1123 if (token->type != YAML_VALUE_TOKEN
1124 && token->type != YAML_FLOW_ENTRY_TOKEN
1125 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
625fcfe9 1126 if (!PUSH(parser, parser->states,
ab01bac8 1127 YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
625fcfe9
KS
1128 return 0;
1129 return yaml_parser_parse_node(parser, event, 0, 0);
ab01bac8
KS
1130 }
1131 else {
1132 parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
625fcfe9
KS
1133 return yaml_parser_process_empty_scalar(parser, event,
1134 token->start_mark);
ab01bac8
KS
1135 }
1136 }
1137 else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
625fcfe9 1138 if (!PUSH(parser, parser->states,
ab01bac8 1139 YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
625fcfe9
KS
1140 return 0;
1141 return yaml_parser_parse_node(parser, event, 0, 0);
ab01bac8
KS
1142 }
1143 }
1144
625fcfe9
KS
1145 parser->state = POP(parser, parser->states);
1146 POP(parser, parser->marks);
1147 MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1148 SKIP_TOKEN(parser);
1149 return 1;
ab01bac8
KS
1150}
1151
1152/*
1153 * Parse the productions:
1154 * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1155 * * ***** *
1156 */
52fba2c6 1157
625fcfe9
KS
1158static int
1159yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1160 yaml_event_t *event, int empty)
ab01bac8
KS
1161{
1162 yaml_token_t *token;
ab01bac8 1163
625fcfe9
KS
1164 token = PEEK_TOKEN(parser);
1165 if (!token) return 0;
ab01bac8
KS
1166
1167 if (empty) {
1168 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
625fcfe9
KS
1169 return yaml_parser_process_empty_scalar(parser, event,
1170 token->start_mark);
ab01bac8
KS
1171 }
1172
1173 if (token->type == YAML_VALUE_TOKEN) {
625fcfe9
KS
1174 SKIP_TOKEN(parser);
1175 token = PEEK_TOKEN(parser);
1176 if (!token) return 0;
ab01bac8
KS
1177 if (token->type != YAML_FLOW_ENTRY_TOKEN
1178 && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
625fcfe9 1179 if (!PUSH(parser, parser->states,
ab01bac8 1180 YAML_PARSE_FLOW_MAPPING_KEY_STATE))
625fcfe9
KS
1181 return 0;
1182 return yaml_parser_parse_node(parser, event, 0, 0);
ab01bac8
KS
1183 }
1184 }
1185
1186 parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
625fcfe9 1187 return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
ab01bac8
KS
1188}
1189
1190/*
1191 * Generate an empty scalar event.
1192 */
1193
625fcfe9
KS
1194static int
1195yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1196 yaml_mark_t mark)
ab01bac8 1197{
ab01bac8
KS
1198 yaml_char_t *value;
1199
1200 value = yaml_malloc(1);
1201 if (!value) {
1202 parser->error = YAML_MEMORY_ERROR;
625fcfe9 1203 return 0;
ab01bac8
KS
1204 }
1205 value[0] = '\0';
1206
625fcfe9 1207 SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
ab01bac8 1208 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
ab01bac8 1209
625fcfe9 1210 return 1;
ab01bac8
KS
1211}
1212
1213/*
1214 * Parse directives.
1215 */
1216
1217static int
625fcfe9
KS
1218yaml_parser_process_directives(yaml_parser_t *parser,
1219 yaml_version_directive_t **version_directive_ref,
1220 yaml_tag_directive_t **tag_directives_start_ref,
1221 yaml_tag_directive_t **tag_directives_end_ref)
ab01bac8
KS
1222{
1223 yaml_tag_directive_t default_tag_directives[] = {
1224 {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1225 {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1226 {NULL, NULL}
1227 };
ab01bac8 1228 yaml_tag_directive_t *default_tag_directive;
625fcfe9
KS
1229 yaml_version_directive_t *version_directive = NULL;
1230 struct {
1231 yaml_tag_directive_t *start;
1232 yaml_tag_directive_t *end;
1233 yaml_tag_directive_t *top;
1234 } tag_directives = { NULL, NULL, NULL };
ab01bac8
KS
1235 yaml_token_t *token;
1236
625fcfe9
KS
1237 if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1238 goto error;
1239
1240 token = PEEK_TOKEN(parser);
1241 if (!token) goto error;
ab01bac8
KS
1242
1243 while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1244 token->type == YAML_TAG_DIRECTIVE_TOKEN)
1245 {
1246 if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
625fcfe9
KS
1247 if (version_directive) {
1248 yaml_parser_set_parser_error(parser,
ab01bac8 1249 "found duplicate %YAML directive", token->start_mark);
625fcfe9 1250 goto error;
ab01bac8
KS
1251 }
1252 if (token->data.version_directive.major != 1
1253 && token->data.version_directive.minor != 1) {
625fcfe9 1254 yaml_parser_set_parser_error(parser,
ab01bac8 1255 "found incompatible YAML document", token->start_mark);
625fcfe9 1256 goto error;
ab01bac8 1257 }
625fcfe9
KS
1258 version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1259 if (!version_directive) {
ab01bac8 1260 parser->error = YAML_MEMORY_ERROR;
625fcfe9 1261 goto error;
ab01bac8 1262 }
625fcfe9
KS
1263 version_directive->major = token->data.version_directive.major;
1264 version_directive->minor = token->data.version_directive.minor;
ab01bac8
KS
1265 }
1266
1267 else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1268 yaml_tag_directive_t value = {
1269 token->data.tag_directive.handle,
1270 token->data.tag_directive.prefix
1271 };
625fcfe9
KS
1272 if (!yaml_parser_append_tag_directive(parser, value, 0,
1273 token->start_mark))
1274 goto error;
1275 if (!PUSH(parser, tag_directives, value))
1276 goto error;
ab01bac8 1277 }
ab01bac8 1278
625fcfe9
KS
1279 SKIP_TOKEN(parser);
1280 token = PEEK_TOKEN(parser);
1281 if (!token) goto error;
1282 }
1283
ab01bac8
KS
1284 for (default_tag_directive = default_tag_directives;
1285 default_tag_directive->handle; default_tag_directive++) {
625fcfe9
KS
1286 if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1287 token->start_mark))
1288 goto error;
1289 }
1290
1291 if (version_directive_ref) {
1292 *version_directive_ref = version_directive;
1293 }
1294 if (tag_directives_start_ref) {
1295 if (STACK_EMPTY(parser, tag_directives)) {
1296 *tag_directives_start_ref = *tag_directives_end_ref = NULL;
54815ffd 1297 STACK_DEL(parser, tag_directives);
ab01bac8 1298 }
625fcfe9
KS
1299 else {
1300 *tag_directives_start_ref = tag_directives.start;
54815ffd 1301 *tag_directives_end_ref = tag_directives.top;
ab01bac8
KS
1302 }
1303 }
54815ffd
KS
1304 else {
1305 STACK_DEL(parser, tag_directives);
1306 }
625fcfe9 1307
ab01bac8 1308 return 1;
625fcfe9
KS
1309
1310error:
1311 yaml_free(version_directive);
1312 while (!STACK_EMPTY(parser, tag_directives)) {
1313 yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1314 yaml_free(tag_directive.handle);
1315 yaml_free(tag_directive.prefix);
1316 }
1317 STACK_DEL(parser, tag_directives);
1318 return 0;
1319}
1320
1321static int
1322yaml_parser_append_tag_directive(yaml_parser_t *parser,
1323 yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1324{
1325 yaml_tag_directive_t *tag_directive;
1326 yaml_tag_directive_t copy = { NULL, NULL };
625fcfe9
KS
1327
1328 for (tag_directive = parser->tag_directives.start;
1329 tag_directive != parser->tag_directives.top; tag_directive ++) {
1330 if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1331 if (allow_duplicates)
1332 return 1;
1333 return yaml_parser_set_parser_error(parser,
1334 "found duplicate %TAG directive", mark);
1335 }
1336 }
1337
1338 copy.handle = (yaml_char_t *)yaml_strdup((char *)value.handle);
1339 copy.prefix = (yaml_char_t *)yaml_strdup((char *)value.prefix);
1340 if (!copy.handle || !copy.prefix) {
1341 parser->error = YAML_MEMORY_ERROR;
1342 goto error;
1343 }
1344
1345 if (!PUSH(parser, parser->tag_directives, copy))
1346 goto error;
1347
1348 return 1;
1349
1350error:
1351 yaml_free(copy.handle);
1352 yaml_free(copy.prefix);
1353 return 0;
ab01bac8 1354}
52fba2c6 1355
This page took 0.253511 seconds and 5 git commands to generate.