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