source: libyaml/trunk/src/parser.c @ 208

Revision 208, 47.4 KB checked in by xi, 8 years ago (diff)

Refactor internal and external API.

RevLine 
[201]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
[208]42#include "yaml_private.h"
[201]43
[208]44/*
45 * Event initializers.
46 */
[201]47
[208]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))
[201]53
[208]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)))
109
[201]110/*
[208]111 * Peek the next token in the token queue.
[201]112 */
113
[208]114#define PEEK_TOKEN(parser)                                                      \
115    ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
116        parser->tokens.head : NULL)
[201]117
[208]118/*
119 * Remove the next token from the queue (must be called after PEEK_TOKEN).
120 */
[201]121
[208]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
[201]129/*
[208]130 * Public API declarations.
131 */
132
133YAML_DECLARE(int)
134yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
135
136/*
[202]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/*
[208]150 * State functions.
[202]151 */
152
153static int
[208]154yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
[202]155
156static int
[208]157yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
[203]158
159static int
[208]160yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
161        int implicit);
[202]162
163static int
[208]164yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
[202]165
[208]166static int
167yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
[201]168
[208]169static int
170yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
[201]171        int block, int indentless_sequence);
172
[208]173static int
174yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
175        yaml_event_t *event, int first);
[201]176
[208]177static int
178yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
179        yaml_event_t *event);
[201]180
[208]181static int
182yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
183        yaml_event_t *event, int first);
[201]184
[208]185static int
186yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
187        yaml_event_t *event);
[201]188
[208]189static int
190yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
191        yaml_event_t *event, int first);
[201]192
[208]193static int
194yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
195        yaml_event_t *event);
[201]196
[208]197static int
198yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
199        yaml_event_t *event);
[201]200
[208]201static int
202yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
203        yaml_event_t *event);
[201]204
[208]205static int
206yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
207        yaml_event_t *event, int first);
[201]208
[208]209static int
210yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
211        yaml_event_t *event, int empty);
[201]212
213/*
[202]214 * Utility functions.
215 */
216
[208]217static int
218yaml_parser_process_empty_scalar(yaml_parser_t *parser,
219        yaml_event_t *event, yaml_mark_t mark);
[202]220
221static int
[208]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);
[202]226
[208]227static int
228yaml_parser_append_tag_directive(yaml_parser_t *parser,
229        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
230
[202]231/*
[208]232 * Get the next event.
[201]233 */
234
[208]235YAML_DECLARE(int)
236yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
[201]237{
[208]238    assert(parser);     /* Non-NULL parser object is expected. */
239    assert(event);      /* Non-NULL event object is expected. */
[201]240
[208]241    /* No events after the end of the stream or error. */
[201]242
[208]243    if (parser->stream_end_produced || parser->error ||
244            parser->state == YAML_PARSE_END_STATE) {
245        memset(event, 0, sizeof(yaml_event_t));
[201]246
[208]247        return 1;
[201]248    }
249
[208]250    /* Generate the next event. */
[201]251
[208]252    return yaml_parser_state_machine(parser, event);
[201]253}
254
255/*
[202]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
[203]284
285/*
[208]286 * State dispatcher.
[203]287 */
288
289static int
[208]290yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
[203]291{
[201]292    switch (parser->state)
293    {
294        case YAML_PARSE_STREAM_START_STATE:
[208]295            return yaml_parser_parse_stream_start(parser, event);
[201]296
297        case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
[208]298            return yaml_parser_parse_document_start(parser, event, 1);
[201]299
300        case YAML_PARSE_DOCUMENT_START_STATE:
[208]301            return yaml_parser_parse_document_start(parser, event, 0);
[201]302
303        case YAML_PARSE_DOCUMENT_CONTENT_STATE:
[208]304            return yaml_parser_parse_document_content(parser, event);
[201]305
306        case YAML_PARSE_DOCUMENT_END_STATE:
[208]307            return yaml_parser_parse_document_end(parser, event);
[201]308
309        case YAML_PARSE_BLOCK_NODE_STATE:
[208]310            return yaml_parser_parse_node(parser, event, 1, 0);
[201]311
312        case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
[208]313            return yaml_parser_parse_node(parser, event, 1, 1);
[201]314
315        case YAML_PARSE_FLOW_NODE_STATE:
[208]316            return yaml_parser_parse_node(parser, event, 0, 0);
[201]317
318        case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
[208]319            return yaml_parser_parse_block_sequence_entry(parser, event, 1);
[201]320
321        case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
[208]322            return yaml_parser_parse_block_sequence_entry(parser, event, 0);
[201]323
324        case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
[208]325            return yaml_parser_parse_indentless_sequence_entry(parser, event);
[201]326
327        case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
[208]328            return yaml_parser_parse_block_mapping_key(parser, event, 1);
[201]329
330        case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
[208]331            return yaml_parser_parse_block_mapping_key(parser, event, 0);
[201]332
333        case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
[208]334            return yaml_parser_parse_block_mapping_value(parser, event);
[201]335
336        case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
[208]337            return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
[201]338
339        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
[208]340            return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
[201]341
342        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
[208]343            return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
[201]344
345        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
[208]346            return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
[201]347
348        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
[208]349            return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
[201]350
351        case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
[208]352            return yaml_parser_parse_flow_mapping_key(parser, event, 1);
[201]353
354        case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
[208]355            return yaml_parser_parse_flow_mapping_key(parser, event, 0);
[201]356
357        case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
[208]358            return yaml_parser_parse_flow_mapping_value(parser, event, 0);
[201]359
360        case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
[208]361            return yaml_parser_parse_flow_mapping_value(parser, event, 1);
362
363        default:
364            assert(1);      /* Invalid state. */
[201]365    }
366}
367
[202]368/*
369 * Parse the production:
370 * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
371 *              ************
372 */
373
[208]374static int
375yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
[202]376{
377    yaml_token_t *token;
378
[208]379    token = PEEK_TOKEN(parser);
380    if (!token) return 0;
[202]381
[208]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);
[202]385    }
386
387    parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
[208]388    STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
389            token->start_mark, token->start_mark);
390    SKIP_TOKEN(parser);
[202]391
[208]392    return 1;
[202]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
[208]403static int
404yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
405        int implicit)
[202]406{
407    yaml_token_t *token;
[208]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 };
[202]413
[208]414    token = PEEK_TOKEN(parser);
415    if (!token) return 0;
[202]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    {
[208]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;
[202]428        parser->state = YAML_PARSE_BLOCK_NODE_STATE;
[208]429        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
[202]430                token->start_mark, token->start_mark);
[208]431        return 1;
[202]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;
[208]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;
[202]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);
[208]448            goto error;
[202]449        }
[208]450        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
451            goto error;
[202]452        parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
[208]453        end_mark = token->end_mark;
454        DOCUMENT_START_EVENT_INIT(*event, version_directive,
455                tag_directives.start, tag_directives.end, 0,
[202]456                start_mark, end_mark);
[208]457        SKIP_TOKEN(parser);
458        version_directive = NULL;
459        tag_directives.start = tag_directives.end = NULL;
460        return 1;
[202]461    }
462
463    /* Parse the stream end. */
464
465    else
466    {
467        parser->state = YAML_PARSE_END_STATE;
[208]468        STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
469        SKIP_TOKEN(parser);
470        return 1;
[202]471    }
[208]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;
[202]482}
483
484/*
485 * Parse the productions:
486 * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
487 *                                                    ***********
488 */
489
[208]490static int
491yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
[202]492{
493    yaml_token_t *token;
494
[208]495    token = PEEK_TOKEN(parser);
496    if (!token) return 0;
[202]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) {
[208]503        parser->state = POP(parser, parser->states);
504        return yaml_parser_process_empty_scalar(parser, event,
505                token->start_mark);
[202]506    }
507    else {
[208]508        return yaml_parser_parse_node(parser, event, 1, 0);
[202]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
[208]520static int
521yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
[202]522{
523    yaml_token_t *token;
524    yaml_mark_t start_mark, end_mark;
525    int implicit = 1;
526
[208]527    token = PEEK_TOKEN(parser);
528    if (!token) return 0;
[202]529
530    start_mark = end_mark = token->start_mark;
531
532    while (token->type == YAML_DOCUMENT_END_TOKEN) {
533        end_mark = token->end_mark;
[208]534        SKIP_TOKEN(parser);
535        token = PEEK_TOKEN(parser);
536        if (!token) return 0;
[202]537        implicit = 0;
538    }
539
[208]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);
[203]544    }
545
546    parser->state = YAML_PARSE_DOCUMENT_START_STATE;
[208]547    DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
[203]548
[208]549    return 1;
[202]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
[208]581static int
582yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
[202]583        int block, int indentless_sequence)
584{
585    yaml_token_t *token;
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
[208]593    token = PEEK_TOKEN(parser);
594    if (!token) return 0;
[202]595
596    if (token->type == YAML_ALIAS_TOKEN)
597    {
[208]598        parser->state = POP(parser, parser->states);
599        ALIAS_EVENT_INIT(*event, token->data.alias.value,
[202]600                token->start_mark, token->end_mark);
[208]601        SKIP_TOKEN(parser);
602        return 1;
[202]603    }
604
605    else
606    {
607        start_mark = end_mark = token->start_mark;
608
609        if (token->type == YAML_ANCHOR_TOKEN)
610        {
611            anchor = token->data.anchor.value;
612            start_mark = token->start_mark;
613            end_mark = token->end_mark;
[208]614            SKIP_TOKEN(parser);
615            token = PEEK_TOKEN(parser);
[202]616            if (!token) goto error;
617            if (token->type == YAML_TAG_TOKEN)
618            {
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;
[208]623                SKIP_TOKEN(parser);
624                token = PEEK_TOKEN(parser);
[202]625                if (!token) goto error;
626            }
627        }
628        else if (token->type == YAML_TAG_TOKEN)
629        {
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;
[208]634            SKIP_TOKEN(parser);
635            token = PEEK_TOKEN(parser);
[202]636            if (!token) goto error;
637            if (token->type == YAML_ANCHOR_TOKEN)
638            {
639                anchor = token->data.anchor.value;
640                end_mark = token->end_mark;
[208]641                SKIP_TOKEN(parser);
642                token = PEEK_TOKEN(parser);
[202]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 {
[208]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);
[202]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                        }
[208]666                        memcpy(tag, tag_directive->prefix, prefix_len);
[202]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                }
[208]675                if (!tag) {
[202]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;
[208]688            SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]689                    YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
[208]690            return 1;
[202]691        }
692        else {
693            if (token->type == YAML_SCALAR_TOKEN) {
694                int plain_implicit = 0;
695                int quoted_implicit = 0;
696                end_mark = token->end_mark;
697                if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
[203]698                        || (tag && strcmp((char *)tag, "!") == 0)) {
[202]699                    plain_implicit = 1;
700                }
701                else if (!tag) {
702                    quoted_implicit = 1;
703                }
[208]704                parser->state = POP(parser, parser->states);
705                SCALAR_EVENT_INIT(*event, anchor, tag,
[202]706                        token->data.scalar.value, token->data.scalar.length,
707                        plain_implicit, quoted_implicit,
708                        token->data.scalar.style, start_mark, end_mark);
[208]709                SKIP_TOKEN(parser);
710                return 1;
[202]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;
[208]715                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]716                        YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
[208]717                return 1;
[202]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;
[208]722                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]723                        YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
[208]724                return 1;
[202]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;
[208]729                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]730                        YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
[208]731                return 1;
[202]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;
[208]736                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
[202]737                        YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
[208]738                return 1;
[202]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';
[208]747                parser->state = POP(parser, parser->states);
748                SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
[202]749                        implicit, 0, YAML_PLAIN_SCALAR_STYLE,
750                        start_mark, end_mark);
[208]751                return 1;
[202]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            }
760        }
761    }
762
763error:
764    yaml_free(anchor);
765    yaml_free(tag_handle);
766    yaml_free(tag_suffix);
767    yaml_free(tag);
768
[208]769    return 0;
[202]770}
771
772/*
773 * Parse the productions:
774 * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
775 *                    ********************  *********** *             *********
776 */
777
[208]778static int
779yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
780        yaml_event_t *event, int first)
[202]781{
782    yaml_token_t *token;
783
784    if (first) {
[208]785        token = PEEK_TOKEN(parser);
786        if (!PUSH(parser, parser->marks, token->start_mark))
787            return 0;
788        SKIP_TOKEN(parser);
[202]789    }
790
[208]791    token = PEEK_TOKEN(parser);
792    if (!token) return 0;
[202]793
794    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
795    {
796        yaml_mark_t mark = token->end_mark;
[208]797        SKIP_TOKEN(parser);
798        token = PEEK_TOKEN(parser);
799        if (!token) return 0;
[202]800        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
801                token->type != YAML_BLOCK_END_TOKEN) {
[208]802            if (!PUSH(parser, parser->states,
[202]803                        YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
[208]804                return 0;
805            return yaml_parser_parse_node(parser, event, 1, 0);
[202]806        }
807        else {
808            parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
[208]809            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]810        }
811    }
812
813    else if (token->type == YAML_BLOCK_END_TOKEN)
814    {
[208]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;
[202]820    }
821
822    else
823    {
[208]824        return yaml_parser_set_parser_error_context(parser,
825                "while parsing a block collection", POP(parser, parser->marks),
[202]826                "did not found expected '-' indicator", token->start_mark);
827    }
828}
829
830/*
831 * Parse the productions:
832 * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
833 *                           *********** *
834 */
835
[208]836static int
837yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
838        yaml_event_t *event)
[202]839{
840    yaml_token_t *token;
841
[208]842    token = PEEK_TOKEN(parser);
843    if (!token) return 0;
[202]844
845    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
846    {
847        yaml_mark_t mark = token->end_mark;
[208]848        SKIP_TOKEN(parser);
849        token = PEEK_TOKEN(parser);
850        if (!token) return 0;
[202]851        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
[208]852                token->type != YAML_KEY_TOKEN &&
853                token->type != YAML_VALUE_TOKEN &&
[202]854                token->type != YAML_BLOCK_END_TOKEN) {
[208]855            if (!PUSH(parser, parser->states,
[202]856                        YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
[208]857                return 0;
858            return yaml_parser_parse_node(parser, event, 1, 0);
[202]859        }
860        else {
861            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
[208]862            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]863        }
864    }
865
866    else
867    {
[208]868        parser->state = POP(parser, parser->states);
869        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
870        return 1;
[202]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
[208]886static int
887yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
888        yaml_event_t *event, int first)
[202]889{
890    yaml_token_t *token;
891
892    if (first) {
[208]893        token = PEEK_TOKEN(parser);
894        if (!PUSH(parser, parser->marks, token->start_mark))
895            return 0;
896        SKIP_TOKEN(parser);
[202]897    }
898
[208]899    token = PEEK_TOKEN(parser);
900    if (!token) return 0;
[202]901
902    if (token->type == YAML_KEY_TOKEN)
903    {
904        yaml_mark_t mark = token->end_mark;
[208]905        SKIP_TOKEN(parser);
906        token = PEEK_TOKEN(parser);
907        if (!token) return 0;
[202]908        if (token->type != YAML_KEY_TOKEN &&
909                token->type != YAML_VALUE_TOKEN &&
910                token->type != YAML_BLOCK_END_TOKEN) {
[208]911            if (!PUSH(parser, parser->states,
[202]912                        YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
[208]913                return 0;
914            return yaml_parser_parse_node(parser, event, 1, 1);
[202]915        }
916        else {
917            parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
[208]918            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]919        }
920    }
921
922    else if (token->type == YAML_BLOCK_END_TOKEN)
923    {
[208]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;
[202]929    }
930
931    else
932    {
[208]933        return yaml_parser_set_parser_error_context(parser,
934                "while parsing a block mapping", POP(parser, parser->marks),
[202]935                "did not found expected key", token->start_mark);
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
[208]951static int
952yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
953        yaml_event_t *event)
[202]954{
955    yaml_token_t *token;
956
[208]957    token = PEEK_TOKEN(parser);
958    if (!token) return 0;
[202]959
960    if (token->type == YAML_VALUE_TOKEN)
961    {
962        yaml_mark_t mark = token->end_mark;
[208]963        SKIP_TOKEN(parser);
964        token = PEEK_TOKEN(parser);
965        if (!token) return 0;
[202]966        if (token->type != YAML_KEY_TOKEN &&
967                token->type != YAML_VALUE_TOKEN &&
968                token->type != YAML_BLOCK_END_TOKEN) {
[208]969            if (!PUSH(parser, parser->states,
[202]970                        YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
[208]971                return 0;
972            return yaml_parser_parse_node(parser, event, 1, 1);
[202]973        }
974        else {
975            parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
[208]976            return yaml_parser_process_empty_scalar(parser, event, mark);
[202]977        }
978    }
979
980    else
981    {
982        parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
[208]983        return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
[202]984    }
985}
986
[203]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
[208]1001static int
1002yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
1003        yaml_event_t *event, int first)
[203]1004{
1005    yaml_token_t *token;
[202]1006
[203]1007    if (first) {
[208]1008        token = PEEK_TOKEN(parser);
1009        if (!PUSH(parser, parser->marks, token->start_mark))
1010            return 0;
1011        SKIP_TOKEN(parser);
[203]1012    }
1013
[208]1014    token = PEEK_TOKEN(parser);
1015    if (!token) return 0;
[203]1016
1017    if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
1018    {
1019        if (!first) {
1020            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
[208]1021                SKIP_TOKEN(parser);
1022                token = PEEK_TOKEN(parser);
1023                if (!token) return 0;
[203]1024            }
1025            else {
[208]1026                return yaml_parser_set_parser_error_context(parser,
1027                        "while parsing a flow sequence", POP(parser, parser->marks),
[203]1028                        "did not found expected ',' or ']'", token->start_mark);
1029            }
1030        }
1031
1032        if (token->type == YAML_KEY_TOKEN) {
1033            parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
[208]1034            MAPPING_START_EVENT_INIT(*event, NULL, NULL,
[203]1035                    1, YAML_FLOW_MAPPING_STYLE,
1036                    token->start_mark, token->end_mark);
[208]1037            SKIP_TOKEN(parser);
1038            return 1;
[203]1039        }
1040
1041        else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
[208]1042            if (!PUSH(parser, parser->states,
[203]1043                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
[208]1044                return 0;
1045            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1046        }
1047    }
1048
[208]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;
[203]1054}
1055
1056/*
1057 * Parse the productions:
1058 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1059 *                                      *** *
1060 */
1061
[208]1062static int
1063yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1064        yaml_event_t *event)
[203]1065{
1066    yaml_token_t *token;
[202]1067
[208]1068    token = PEEK_TOKEN(parser);
1069    if (!token) return 0;
[203]1070
1071    if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1072            && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
[208]1073        if (!PUSH(parser, parser->states,
[203]1074                    YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
[208]1075            return 0;
1076        return yaml_parser_parse_node(parser, event, 0, 0);
[203]1077    }
1078    else {
[208]1079        yaml_mark_t mark = token->end_mark;
1080        SKIP_TOKEN(parser);
[203]1081        parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
[208]1082        return yaml_parser_process_empty_scalar(parser, event, mark);
[203]1083    }
1084}
1085
1086/*
1087 * Parse the productions:
1088 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1089 *                                                      ***** *
1090 */
1091
[208]1092static int
1093yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1094        yaml_event_t *event)
[203]1095{
1096    yaml_token_t *token;
[202]1097
[208]1098    token = PEEK_TOKEN(parser);
1099    if (!token) return 0;
[203]1100
1101    if (token->type == YAML_VALUE_TOKEN) {
[208]1102        SKIP_TOKEN(parser);
1103        token = PEEK_TOKEN(parser);
1104        if (!token) return 0;
[203]1105        if (token->type != YAML_FLOW_ENTRY_TOKEN
1106                && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
[208]1107            if (!PUSH(parser, parser->states,
[203]1108                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
[208]1109                return 0;
1110            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1111        }
1112    }
1113    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
[208]1114    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
[203]1115}
1116
1117/*
1118 * Parse the productions:
1119 * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1120 *                                                                      *
1121 */
1122
[208]1123static int
1124yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1125        yaml_event_t *event)
[203]1126{
1127    yaml_token_t *token;
[202]1128
[208]1129    token = PEEK_TOKEN(parser);
1130    if (!token) return 0;
[203]1131
1132    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1133
[208]1134    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1135    return 1;
[203]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 */
1151
[208]1152static int
1153yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1154        yaml_event_t *event, int first)
[203]1155{
1156    yaml_token_t *token;
[202]1157
[203]1158    if (first) {
[208]1159        token = PEEK_TOKEN(parser);
1160        if (!PUSH(parser, parser->marks, token->start_mark))
1161            return 0;
1162        SKIP_TOKEN(parser);
[203]1163    }
1164
[208]1165    token = PEEK_TOKEN(parser);
1166    if (!token) return 0;
[203]1167
1168    if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1169    {
1170        if (!first) {
1171            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
[208]1172                SKIP_TOKEN(parser);
1173                token = PEEK_TOKEN(parser);
1174                if (!token) return 0;
[203]1175            }
1176            else {
[208]1177                return yaml_parser_set_parser_error_context(parser,
1178                        "while parsing a flow mapping", POP(parser, parser->marks),
[203]1179                        "did not found expected ',' or '}'", token->start_mark);
1180            }
1181        }
1182
1183        if (token->type == YAML_KEY_TOKEN) {
[208]1184            SKIP_TOKEN(parser);
1185            token = PEEK_TOKEN(parser);
1186            if (!token) return 0;
[203]1187            if (token->type != YAML_VALUE_TOKEN
1188                    && token->type != YAML_FLOW_ENTRY_TOKEN
1189                    && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
[208]1190                if (!PUSH(parser, parser->states,
[203]1191                            YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
[208]1192                    return 0;
1193                return yaml_parser_parse_node(parser, event, 0, 0);
[203]1194            }
1195            else {
1196                parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
[208]1197                return yaml_parser_process_empty_scalar(parser, event,
1198                        token->start_mark);
[203]1199            }
1200        }
1201        else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
[208]1202            if (!PUSH(parser, parser->states,
[203]1203                        YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
[208]1204                return 0;
1205            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1206        }
1207    }
1208
[208]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;
[203]1214}
1215
1216/*
1217 * Parse the productions:
1218 * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1219 *                                   *                  ***** *
1220 */
1221
[208]1222static int
1223yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1224        yaml_event_t *event, int empty)
[203]1225{
1226    yaml_token_t *token;
[202]1227
[208]1228    token = PEEK_TOKEN(parser);
1229    if (!token) return 0;
[203]1230
1231    if (empty) {
1232        parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
[208]1233        return yaml_parser_process_empty_scalar(parser, event,
1234                token->start_mark);
[203]1235    }
1236
1237    if (token->type == YAML_VALUE_TOKEN) {
[208]1238        SKIP_TOKEN(parser);
1239        token = PEEK_TOKEN(parser);
1240        if (!token) return 0;
[203]1241        if (token->type != YAML_FLOW_ENTRY_TOKEN
1242                && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
[208]1243            if (!PUSH(parser, parser->states,
[203]1244                        YAML_PARSE_FLOW_MAPPING_KEY_STATE))
[208]1245                return 0;
1246            return yaml_parser_parse_node(parser, event, 0, 0);
[203]1247        }
1248    }
1249
1250    parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
[208]1251    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
[203]1252}
1253
1254/*
1255 * Generate an empty scalar event.
1256 */
1257
[208]1258static int
1259yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1260        yaml_mark_t mark)
[203]1261{
1262    yaml_char_t *value;
1263
1264    value = yaml_malloc(1);
1265    if (!value) {
1266        parser->error = YAML_MEMORY_ERROR;
[208]1267        return 0;
[203]1268    }
1269    value[0] = '\0';
1270
[208]1271    SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
[203]1272            1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1273
[208]1274    return 1;
[203]1275}
1276
1277/*
1278 * Parse directives.
1279 */
1280
1281static int
[208]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)
[203]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    };
1292    yaml_tag_directive_t *default_tag_directive;
[208]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 };
[203]1299    yaml_token_t *token;
1300
[208]1301    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1302        goto error;
[203]1303
[208]1304    token = PEEK_TOKEN(parser);
1305    if (!token) goto error;
1306
[203]1307    while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1308            token->type == YAML_TAG_DIRECTIVE_TOKEN)
1309    {
1310        if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
[208]1311            if (version_directive) {
1312                yaml_parser_set_parser_error(parser,
[203]1313                        "found duplicate %YAML directive", token->start_mark);
[208]1314                goto error;
[203]1315            }
1316            if (token->data.version_directive.major != 1
1317                    && token->data.version_directive.minor != 1) {
[208]1318                yaml_parser_set_parser_error(parser,
[203]1319                        "found incompatible YAML document", token->start_mark);
[208]1320                goto error;
[203]1321            }
[208]1322            version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1323            if (!version_directive) {
[203]1324                parser->error = YAML_MEMORY_ERROR;
[208]1325                goto error;
[203]1326            }
[208]1327            version_directive->major = token->data.version_directive.major;
1328            version_directive->minor = token->data.version_directive.minor;
[203]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            };
[208]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;
[203]1341        }
1342
[208]1343        SKIP_TOKEN(parser);
1344        token = PEEK_TOKEN(parser);
1345        if (!token) goto error;
1346    }
1347   
[203]1348    for (default_tag_directive = default_tag_directives;
1349            default_tag_directive->handle; default_tag_directive++) {
[208]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;
[203]1361        }
[208]1362        else {
1363            *tag_directives_start_ref = tag_directives.start;
1364            *tag_directives_end_ref = tag_directives.end;
[203]1365        }
1366    }
[208]1367
[203]1368    return 1;
[208]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;
[203]1379}
1380
[208]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;
1415}
1416
Note: See TracBrowser for help on using the repository browser.