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