1247738Sbapt
2247738Sbapt/*
3247738Sbapt * The parser implements the following grammar:
4247738Sbapt *
5247738Sbapt * stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
6247738Sbapt * implicit_document    ::= block_node DOCUMENT-END*
7247738Sbapt * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
8247738Sbapt * block_node_or_indentless_sequence    ::=
9247738Sbapt *                          ALIAS
10247738Sbapt *                          | properties (block_content | indentless_block_sequence)?
11247738Sbapt *                          | block_content
12247738Sbapt *                          | indentless_block_sequence
13247738Sbapt * block_node           ::= ALIAS
14247738Sbapt *                          | properties block_content?
15247738Sbapt *                          | block_content
16247738Sbapt * flow_node            ::= ALIAS
17247738Sbapt *                          | properties flow_content?
18247738Sbapt *                          | flow_content
19247738Sbapt * properties           ::= TAG ANCHOR? | ANCHOR TAG?
20247738Sbapt * block_content        ::= block_collection | flow_collection | SCALAR
21247738Sbapt * flow_content         ::= flow_collection | SCALAR
22247738Sbapt * block_collection     ::= block_sequence | block_mapping
23247738Sbapt * flow_collection      ::= flow_sequence | flow_mapping
24247738Sbapt * block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
25247738Sbapt * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
26247738Sbapt * block_mapping        ::= BLOCK-MAPPING_START
27247738Sbapt *                          ((KEY block_node_or_indentless_sequence?)?
28247738Sbapt *                          (VALUE block_node_or_indentless_sequence?)?)*
29247738Sbapt *                          BLOCK-END
30247738Sbapt * flow_sequence        ::= FLOW-SEQUENCE-START
31247738Sbapt *                          (flow_sequence_entry FLOW-ENTRY)*
32247738Sbapt *                          flow_sequence_entry?
33247738Sbapt *                          FLOW-SEQUENCE-END
34247738Sbapt * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35247738Sbapt * flow_mapping         ::= FLOW-MAPPING-START
36247738Sbapt *                          (flow_mapping_entry FLOW-ENTRY)*
37247738Sbapt *                          flow_mapping_entry?
38247738Sbapt *                          FLOW-MAPPING-END
39247738Sbapt * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
40247738Sbapt */
41247738Sbapt
42247738Sbapt#include "yaml_private.h"
43247738Sbapt
44247738Sbapt/*
45247738Sbapt * Peek the next token in the token queue.
46247738Sbapt */
47247738Sbapt
48247738Sbapt#define PEEK_TOKEN(parser)                                                      \
49247738Sbapt    ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ?       \
50247738Sbapt        parser->tokens.head : NULL)
51247738Sbapt
52247738Sbapt/*
53247738Sbapt * Remove the next token from the queue (must be called after PEEK_TOKEN).
54247738Sbapt */
55247738Sbapt
56247738Sbapt#define SKIP_TOKEN(parser)                                                      \
57247738Sbapt    (parser->token_available = 0,                                               \
58247738Sbapt     parser->tokens_parsed ++,                                                  \
59247738Sbapt     parser->stream_end_produced =                                              \
60247738Sbapt        (parser->tokens.head->type == YAML_STREAM_END_TOKEN),                   \
61247738Sbapt     parser->tokens.head ++)
62247738Sbapt
63247738Sbapt/*
64247738Sbapt * Public API declarations.
65247738Sbapt */
66247738Sbapt
67247738SbaptYAML_DECLARE(int)
68247738Sbaptyaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
69247738Sbapt
70247738Sbapt/*
71247738Sbapt * Error handling.
72247738Sbapt */
73247738Sbapt
74247738Sbaptstatic int
75247738Sbaptyaml_parser_set_parser_error(yaml_parser_t *parser,
76247738Sbapt        const char *problem, yaml_mark_t problem_mark);
77247738Sbapt
78247738Sbaptstatic int
79247738Sbaptyaml_parser_set_parser_error_context(yaml_parser_t *parser,
80247738Sbapt        const char *context, yaml_mark_t context_mark,
81247738Sbapt        const char *problem, yaml_mark_t problem_mark);
82247738Sbapt
83247738Sbapt/*
84247738Sbapt * State functions.
85247738Sbapt */
86247738Sbapt
87247738Sbaptstatic int
88247738Sbaptyaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
89247738Sbapt
90247738Sbaptstatic int
91247738Sbaptyaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
92247738Sbapt
93247738Sbaptstatic int
94247738Sbaptyaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
95247738Sbapt        int implicit);
96247738Sbapt
97247738Sbaptstatic int
98247738Sbaptyaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
99247738Sbapt
100247738Sbaptstatic int
101247738Sbaptyaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
102247738Sbapt
103247738Sbaptstatic int
104247738Sbaptyaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105247738Sbapt        int block, int indentless_sequence);
106247738Sbapt
107247738Sbaptstatic int
108247738Sbaptyaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109247738Sbapt        yaml_event_t *event, int first);
110247738Sbapt
111247738Sbaptstatic int
112247738Sbaptyaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113247738Sbapt        yaml_event_t *event);
114247738Sbapt
115247738Sbaptstatic int
116247738Sbaptyaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117247738Sbapt        yaml_event_t *event, int first);
118247738Sbapt
119247738Sbaptstatic int
120247738Sbaptyaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121247738Sbapt        yaml_event_t *event);
122247738Sbapt
123247738Sbaptstatic int
124247738Sbaptyaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125247738Sbapt        yaml_event_t *event, int first);
126247738Sbapt
127247738Sbaptstatic int
128247738Sbaptyaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129247738Sbapt        yaml_event_t *event);
130247738Sbapt
131247738Sbaptstatic int
132247738Sbaptyaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133247738Sbapt        yaml_event_t *event);
134247738Sbapt
135247738Sbaptstatic int
136247738Sbaptyaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137247738Sbapt        yaml_event_t *event);
138247738Sbapt
139247738Sbaptstatic int
140247738Sbaptyaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141247738Sbapt        yaml_event_t *event, int first);
142247738Sbapt
143247738Sbaptstatic int
144247738Sbaptyaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145247738Sbapt        yaml_event_t *event, int empty);
146247738Sbapt
147247738Sbapt/*
148247738Sbapt * Utility functions.
149247738Sbapt */
150247738Sbapt
151247738Sbaptstatic int
152247738Sbaptyaml_parser_process_empty_scalar(yaml_parser_t *parser,
153247738Sbapt        yaml_event_t *event, yaml_mark_t mark);
154247738Sbapt
155247738Sbaptstatic int
156247738Sbaptyaml_parser_process_directives(yaml_parser_t *parser,
157247738Sbapt        yaml_version_directive_t **version_directive_ref,
158247738Sbapt        yaml_tag_directive_t **tag_directives_start_ref,
159247738Sbapt        yaml_tag_directive_t **tag_directives_end_ref);
160247738Sbapt
161247738Sbaptstatic int
162247738Sbaptyaml_parser_append_tag_directive(yaml_parser_t *parser,
163247738Sbapt        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
164247738Sbapt
165247738Sbapt/*
166247738Sbapt * Get the next event.
167247738Sbapt */
168247738Sbapt
169247738SbaptYAML_DECLARE(int)
170247738Sbaptyaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
171247738Sbapt{
172247738Sbapt    assert(parser);     /* Non-NULL parser object is expected. */
173247738Sbapt    assert(event);      /* Non-NULL event object is expected. */
174247738Sbapt
175247738Sbapt    /* Erase the event object. */
176247738Sbapt
177247738Sbapt    memset(event, 0, sizeof(yaml_event_t));
178247738Sbapt
179247738Sbapt    /* No events after the end of the stream or error. */
180247738Sbapt
181247738Sbapt    if (parser->stream_end_produced || parser->error ||
182247738Sbapt            parser->state == YAML_PARSE_END_STATE) {
183247738Sbapt        return 1;
184247738Sbapt    }
185247738Sbapt
186247738Sbapt    /* Generate the next event. */
187247738Sbapt
188247738Sbapt    return yaml_parser_state_machine(parser, event);
189247738Sbapt}
190247738Sbapt
191247738Sbapt/*
192247738Sbapt * Set parser error.
193247738Sbapt */
194247738Sbapt
195247738Sbaptstatic int
196247738Sbaptyaml_parser_set_parser_error(yaml_parser_t *parser,
197247738Sbapt        const char *problem, yaml_mark_t problem_mark)
198247738Sbapt{
199247738Sbapt    parser->error = YAML_PARSER_ERROR;
200247738Sbapt    parser->problem = problem;
201247738Sbapt    parser->problem_mark = problem_mark;
202247738Sbapt
203247738Sbapt    return 0;
204247738Sbapt}
205247738Sbapt
206247738Sbaptstatic int
207247738Sbaptyaml_parser_set_parser_error_context(yaml_parser_t *parser,
208247738Sbapt        const char *context, yaml_mark_t context_mark,
209247738Sbapt        const char *problem, yaml_mark_t problem_mark)
210247738Sbapt{
211247738Sbapt    parser->error = YAML_PARSER_ERROR;
212247738Sbapt    parser->context = context;
213247738Sbapt    parser->context_mark = context_mark;
214247738Sbapt    parser->problem = problem;
215247738Sbapt    parser->problem_mark = problem_mark;
216247738Sbapt
217247738Sbapt    return 0;
218247738Sbapt}
219247738Sbapt
220247738Sbapt
221247738Sbapt/*
222247738Sbapt * State dispatcher.
223247738Sbapt */
224247738Sbapt
225247738Sbaptstatic int
226247738Sbaptyaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
227247738Sbapt{
228247738Sbapt    switch (parser->state)
229247738Sbapt    {
230247738Sbapt        case YAML_PARSE_STREAM_START_STATE:
231247738Sbapt            return yaml_parser_parse_stream_start(parser, event);
232247738Sbapt
233247738Sbapt        case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
234247738Sbapt            return yaml_parser_parse_document_start(parser, event, 1);
235247738Sbapt
236247738Sbapt        case YAML_PARSE_DOCUMENT_START_STATE:
237247738Sbapt            return yaml_parser_parse_document_start(parser, event, 0);
238247738Sbapt
239247738Sbapt        case YAML_PARSE_DOCUMENT_CONTENT_STATE:
240247738Sbapt            return yaml_parser_parse_document_content(parser, event);
241247738Sbapt
242247738Sbapt        case YAML_PARSE_DOCUMENT_END_STATE:
243247738Sbapt            return yaml_parser_parse_document_end(parser, event);
244247738Sbapt
245247738Sbapt        case YAML_PARSE_BLOCK_NODE_STATE:
246247738Sbapt            return yaml_parser_parse_node(parser, event, 1, 0);
247247738Sbapt
248247738Sbapt        case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
249247738Sbapt            return yaml_parser_parse_node(parser, event, 1, 1);
250247738Sbapt
251247738Sbapt        case YAML_PARSE_FLOW_NODE_STATE:
252247738Sbapt            return yaml_parser_parse_node(parser, event, 0, 0);
253247738Sbapt
254247738Sbapt        case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
255247738Sbapt            return yaml_parser_parse_block_sequence_entry(parser, event, 1);
256247738Sbapt
257247738Sbapt        case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
258247738Sbapt            return yaml_parser_parse_block_sequence_entry(parser, event, 0);
259247738Sbapt
260247738Sbapt        case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
261247738Sbapt            return yaml_parser_parse_indentless_sequence_entry(parser, event);
262247738Sbapt
263247738Sbapt        case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
264247738Sbapt            return yaml_parser_parse_block_mapping_key(parser, event, 1);
265247738Sbapt
266247738Sbapt        case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
267247738Sbapt            return yaml_parser_parse_block_mapping_key(parser, event, 0);
268247738Sbapt
269247738Sbapt        case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
270247738Sbapt            return yaml_parser_parse_block_mapping_value(parser, event);
271247738Sbapt
272247738Sbapt        case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
273247738Sbapt            return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
274247738Sbapt
275247738Sbapt        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
276247738Sbapt            return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
277247738Sbapt
278247738Sbapt        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
279247738Sbapt            return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
280247738Sbapt
281247738Sbapt        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
282247738Sbapt            return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
283247738Sbapt
284247738Sbapt        case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
285247738Sbapt            return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
286247738Sbapt
287247738Sbapt        case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
288247738Sbapt            return yaml_parser_parse_flow_mapping_key(parser, event, 1);
289247738Sbapt
290247738Sbapt        case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
291247738Sbapt            return yaml_parser_parse_flow_mapping_key(parser, event, 0);
292247738Sbapt
293247738Sbapt        case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
294247738Sbapt            return yaml_parser_parse_flow_mapping_value(parser, event, 0);
295247738Sbapt
296247738Sbapt        case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
297247738Sbapt            return yaml_parser_parse_flow_mapping_value(parser, event, 1);
298247738Sbapt
299247738Sbapt        default:
300247738Sbapt            assert(1);      /* Invalid state. */
301247738Sbapt    }
302247738Sbapt
303247738Sbapt    return 0;
304247738Sbapt}
305247738Sbapt
306247738Sbapt/*
307247738Sbapt * Parse the production:
308247738Sbapt * stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
309247738Sbapt *              ************
310247738Sbapt */
311247738Sbapt
312247738Sbaptstatic int
313247738Sbaptyaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
314247738Sbapt{
315247738Sbapt    yaml_token_t *token;
316247738Sbapt
317247738Sbapt    token = PEEK_TOKEN(parser);
318247738Sbapt    if (!token) return 0;
319247738Sbapt
320247738Sbapt    if (token->type != YAML_STREAM_START_TOKEN) {
321247738Sbapt        return yaml_parser_set_parser_error(parser,
322247738Sbapt                "did not find expected <stream-start>", token->start_mark);
323247738Sbapt    }
324247738Sbapt
325247738Sbapt    parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
326247738Sbapt    STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
327247738Sbapt            token->start_mark, token->start_mark);
328247738Sbapt    SKIP_TOKEN(parser);
329247738Sbapt
330247738Sbapt    return 1;
331247738Sbapt}
332247738Sbapt
333247738Sbapt/*
334247738Sbapt * Parse the productions:
335247738Sbapt * implicit_document    ::= block_node DOCUMENT-END*
336247738Sbapt *                          *
337247738Sbapt * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
338247738Sbapt *                          *************************
339247738Sbapt */
340247738Sbapt
341247738Sbaptstatic int
342247738Sbaptyaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
343247738Sbapt        int implicit)
344247738Sbapt{
345247738Sbapt    yaml_token_t *token;
346247738Sbapt    yaml_version_directive_t *version_directive = NULL;
347247738Sbapt    struct {
348247738Sbapt        yaml_tag_directive_t *start;
349247738Sbapt        yaml_tag_directive_t *end;
350247738Sbapt    } tag_directives = { NULL, NULL };
351247738Sbapt
352247738Sbapt    token = PEEK_TOKEN(parser);
353247738Sbapt    if (!token) return 0;
354247738Sbapt
355247738Sbapt    /* Parse extra document end indicators. */
356247738Sbapt
357247738Sbapt    if (!implicit)
358247738Sbapt    {
359247738Sbapt        while (token->type == YAML_DOCUMENT_END_TOKEN) {
360247738Sbapt            SKIP_TOKEN(parser);
361247738Sbapt            token = PEEK_TOKEN(parser);
362247738Sbapt            if (!token) return 0;
363247738Sbapt        }
364247738Sbapt    }
365247738Sbapt
366247738Sbapt    /* Parse an implicit document. */
367247738Sbapt
368247738Sbapt    if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
369247738Sbapt            token->type != YAML_TAG_DIRECTIVE_TOKEN &&
370247738Sbapt            token->type != YAML_DOCUMENT_START_TOKEN &&
371247738Sbapt            token->type != YAML_STREAM_END_TOKEN)
372247738Sbapt    {
373247738Sbapt        if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
374247738Sbapt            return 0;
375247738Sbapt        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
376247738Sbapt            return 0;
377247738Sbapt        parser->state = YAML_PARSE_BLOCK_NODE_STATE;
378247738Sbapt        DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
379247738Sbapt                token->start_mark, token->start_mark);
380247738Sbapt        return 1;
381247738Sbapt    }
382247738Sbapt
383247738Sbapt    /* Parse an explicit document. */
384247738Sbapt
385247738Sbapt    else if (token->type != YAML_STREAM_END_TOKEN)
386247738Sbapt    {
387247738Sbapt        yaml_mark_t start_mark, end_mark;
388247738Sbapt        start_mark = token->start_mark;
389247738Sbapt        if (!yaml_parser_process_directives(parser, &version_directive,
390247738Sbapt                    &tag_directives.start, &tag_directives.end))
391247738Sbapt            return 0;
392247738Sbapt        token = PEEK_TOKEN(parser);
393247738Sbapt        if (!token) goto error;
394247738Sbapt        if (token->type != YAML_DOCUMENT_START_TOKEN) {
395247738Sbapt            yaml_parser_set_parser_error(parser,
396247738Sbapt                    "did not find expected <document start>", token->start_mark);
397247738Sbapt            goto error;
398247738Sbapt        }
399247738Sbapt        if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
400247738Sbapt            goto error;
401247738Sbapt        parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
402247738Sbapt        end_mark = token->end_mark;
403247738Sbapt        DOCUMENT_START_EVENT_INIT(*event, version_directive,
404247738Sbapt                tag_directives.start, tag_directives.end, 0,
405247738Sbapt                start_mark, end_mark);
406247738Sbapt        SKIP_TOKEN(parser);
407247738Sbapt        version_directive = NULL;
408247738Sbapt        tag_directives.start = tag_directives.end = NULL;
409247738Sbapt        return 1;
410247738Sbapt    }
411247738Sbapt
412247738Sbapt    /* Parse the stream end. */
413247738Sbapt
414247738Sbapt    else
415247738Sbapt    {
416247738Sbapt        parser->state = YAML_PARSE_END_STATE;
417247738Sbapt        STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
418247738Sbapt        SKIP_TOKEN(parser);
419247738Sbapt        return 1;
420247738Sbapt    }
421247738Sbapt
422247738Sbapterror:
423247738Sbapt    yaml_free(version_directive);
424247738Sbapt    while (tag_directives.start != tag_directives.end) {
425247738Sbapt        yaml_free(tag_directives.end[-1].handle);
426247738Sbapt        yaml_free(tag_directives.end[-1].prefix);
427247738Sbapt        tag_directives.end --;
428247738Sbapt    }
429247738Sbapt    yaml_free(tag_directives.start);
430247738Sbapt    return 0;
431247738Sbapt}
432247738Sbapt
433247738Sbapt/*
434247738Sbapt * Parse the productions:
435247738Sbapt * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436247738Sbapt *                                                    ***********
437247738Sbapt */
438247738Sbapt
439247738Sbaptstatic int
440247738Sbaptyaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441247738Sbapt{
442247738Sbapt    yaml_token_t *token;
443247738Sbapt
444247738Sbapt    token = PEEK_TOKEN(parser);
445247738Sbapt    if (!token) return 0;
446247738Sbapt
447247738Sbapt    if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
448247738Sbapt            token->type == YAML_TAG_DIRECTIVE_TOKEN ||
449247738Sbapt            token->type == YAML_DOCUMENT_START_TOKEN ||
450247738Sbapt            token->type == YAML_DOCUMENT_END_TOKEN ||
451247738Sbapt            token->type == YAML_STREAM_END_TOKEN) {
452247738Sbapt        parser->state = POP(parser, parser->states);
453247738Sbapt        return yaml_parser_process_empty_scalar(parser, event,
454247738Sbapt                token->start_mark);
455247738Sbapt    }
456247738Sbapt    else {
457247738Sbapt        return yaml_parser_parse_node(parser, event, 1, 0);
458247738Sbapt    }
459247738Sbapt}
460247738Sbapt
461247738Sbapt/*
462247738Sbapt * Parse the productions:
463247738Sbapt * implicit_document    ::= block_node DOCUMENT-END*
464247738Sbapt *                                     *************
465247738Sbapt * explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
466247738Sbapt *                                                                *************
467247738Sbapt */
468247738Sbapt
469247738Sbaptstatic int
470247738Sbaptyaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
471247738Sbapt{
472247738Sbapt    yaml_token_t *token;
473247738Sbapt    yaml_mark_t start_mark, end_mark;
474247738Sbapt    int implicit = 1;
475247738Sbapt
476247738Sbapt    token = PEEK_TOKEN(parser);
477247738Sbapt    if (!token) return 0;
478247738Sbapt
479247738Sbapt    start_mark = end_mark = token->start_mark;
480247738Sbapt
481247738Sbapt    if (token->type == YAML_DOCUMENT_END_TOKEN) {
482247738Sbapt        end_mark = token->end_mark;
483247738Sbapt        SKIP_TOKEN(parser);
484247738Sbapt        implicit = 0;
485247738Sbapt    }
486247738Sbapt
487247738Sbapt    while (!STACK_EMPTY(parser, parser->tag_directives)) {
488247738Sbapt        yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
489247738Sbapt        yaml_free(tag_directive.handle);
490247738Sbapt        yaml_free(tag_directive.prefix);
491247738Sbapt    }
492247738Sbapt
493247738Sbapt    parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494247738Sbapt    DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
495247738Sbapt
496247738Sbapt    return 1;
497247738Sbapt}
498247738Sbapt
499247738Sbapt/*
500247738Sbapt * Parse the productions:
501247738Sbapt * block_node_or_indentless_sequence    ::=
502247738Sbapt *                          ALIAS
503247738Sbapt *                          *****
504247738Sbapt *                          | properties (block_content | indentless_block_sequence)?
505247738Sbapt *                            **********  *
506247738Sbapt *                          | block_content | indentless_block_sequence
507247738Sbapt *                            *
508247738Sbapt * block_node           ::= ALIAS
509247738Sbapt *                          *****
510247738Sbapt *                          | properties block_content?
511247738Sbapt *                            ********** *
512247738Sbapt *                          | block_content
513247738Sbapt *                            *
514247738Sbapt * flow_node            ::= ALIAS
515247738Sbapt *                          *****
516247738Sbapt *                          | properties flow_content?
517247738Sbapt *                            ********** *
518247738Sbapt *                          | flow_content
519247738Sbapt *                            *
520247738Sbapt * properties           ::= TAG ANCHOR? | ANCHOR TAG?
521247738Sbapt *                          *************************
522247738Sbapt * block_content        ::= block_collection | flow_collection | SCALAR
523247738Sbapt *                                                               ******
524247738Sbapt * flow_content         ::= flow_collection | SCALAR
525247738Sbapt *                                            ******
526247738Sbapt */
527247738Sbapt
528247738Sbaptstatic int
529247738Sbaptyaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530247738Sbapt        int block, int indentless_sequence)
531247738Sbapt{
532247738Sbapt    yaml_token_t *token;
533247738Sbapt    yaml_char_t *anchor = NULL;
534247738Sbapt    yaml_char_t *tag_handle = NULL;
535247738Sbapt    yaml_char_t *tag_suffix = NULL;
536247738Sbapt    yaml_char_t *tag = NULL;
537247738Sbapt    yaml_mark_t start_mark, end_mark, tag_mark;
538247738Sbapt    int implicit;
539247738Sbapt
540247738Sbapt    token = PEEK_TOKEN(parser);
541247738Sbapt    if (!token) return 0;
542247738Sbapt
543247738Sbapt    if (token->type == YAML_ALIAS_TOKEN)
544247738Sbapt    {
545247738Sbapt        parser->state = POP(parser, parser->states);
546247738Sbapt        ALIAS_EVENT_INIT(*event, token->data.alias.value,
547247738Sbapt                token->start_mark, token->end_mark);
548247738Sbapt        SKIP_TOKEN(parser);
549247738Sbapt        return 1;
550247738Sbapt    }
551247738Sbapt
552247738Sbapt    else
553247738Sbapt    {
554247738Sbapt        start_mark = end_mark = token->start_mark;
555247738Sbapt
556247738Sbapt        if (token->type == YAML_ANCHOR_TOKEN)
557247738Sbapt        {
558247738Sbapt            anchor = token->data.anchor.value;
559247738Sbapt            start_mark = token->start_mark;
560247738Sbapt            end_mark = token->end_mark;
561247738Sbapt            SKIP_TOKEN(parser);
562247738Sbapt            token = PEEK_TOKEN(parser);
563247738Sbapt            if (!token) goto error;
564247738Sbapt            if (token->type == YAML_TAG_TOKEN)
565247738Sbapt            {
566247738Sbapt                tag_handle = token->data.tag.handle;
567247738Sbapt                tag_suffix = token->data.tag.suffix;
568247738Sbapt                tag_mark = token->start_mark;
569247738Sbapt                end_mark = token->end_mark;
570247738Sbapt                SKIP_TOKEN(parser);
571247738Sbapt                token = PEEK_TOKEN(parser);
572247738Sbapt                if (!token) goto error;
573247738Sbapt            }
574247738Sbapt        }
575247738Sbapt        else if (token->type == YAML_TAG_TOKEN)
576247738Sbapt        {
577247738Sbapt            tag_handle = token->data.tag.handle;
578247738Sbapt            tag_suffix = token->data.tag.suffix;
579247738Sbapt            start_mark = tag_mark = token->start_mark;
580247738Sbapt            end_mark = token->end_mark;
581247738Sbapt            SKIP_TOKEN(parser);
582247738Sbapt            token = PEEK_TOKEN(parser);
583247738Sbapt            if (!token) goto error;
584247738Sbapt            if (token->type == YAML_ANCHOR_TOKEN)
585247738Sbapt            {
586247738Sbapt                anchor = token->data.anchor.value;
587247738Sbapt                end_mark = token->end_mark;
588247738Sbapt                SKIP_TOKEN(parser);
589247738Sbapt                token = PEEK_TOKEN(parser);
590247738Sbapt                if (!token) goto error;
591247738Sbapt            }
592247738Sbapt        }
593247738Sbapt
594247738Sbapt        if (tag_handle) {
595247738Sbapt            if (!*tag_handle) {
596247738Sbapt                tag = tag_suffix;
597247738Sbapt                yaml_free(tag_handle);
598247738Sbapt                tag_handle = tag_suffix = NULL;
599247738Sbapt            }
600247738Sbapt            else {
601247738Sbapt                yaml_tag_directive_t *tag_directive;
602247738Sbapt                for (tag_directive = parser->tag_directives.start;
603247738Sbapt                        tag_directive != parser->tag_directives.top;
604247738Sbapt                        tag_directive ++) {
605247738Sbapt                    if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
606247738Sbapt                        size_t prefix_len = strlen((char *)tag_directive->prefix);
607247738Sbapt                        size_t suffix_len = strlen((char *)tag_suffix);
608247738Sbapt                        tag = yaml_malloc(prefix_len+suffix_len+1);
609247738Sbapt                        if (!tag) {
610247738Sbapt                            parser->error = YAML_MEMORY_ERROR;
611247738Sbapt                            goto error;
612247738Sbapt                        }
613247738Sbapt                        memcpy(tag, tag_directive->prefix, prefix_len);
614247738Sbapt                        memcpy(tag+prefix_len, tag_suffix, suffix_len);
615247738Sbapt                        tag[prefix_len+suffix_len] = '\0';
616247738Sbapt                        yaml_free(tag_handle);
617247738Sbapt                        yaml_free(tag_suffix);
618247738Sbapt                        tag_handle = tag_suffix = NULL;
619247738Sbapt                        break;
620247738Sbapt                    }
621247738Sbapt                }
622247738Sbapt                if (!tag) {
623247738Sbapt                    yaml_parser_set_parser_error_context(parser,
624247738Sbapt                            "while parsing a node", start_mark,
625247738Sbapt                            "found undefined tag handle", tag_mark);
626247738Sbapt                    goto error;
627247738Sbapt                }
628247738Sbapt            }
629247738Sbapt        }
630247738Sbapt
631247738Sbapt        implicit = (!tag || !*tag);
632247738Sbapt        if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
633247738Sbapt            end_mark = token->end_mark;
634247738Sbapt            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
635247738Sbapt            SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
636247738Sbapt                    YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
637247738Sbapt            return 1;
638247738Sbapt        }
639247738Sbapt        else {
640247738Sbapt            if (token->type == YAML_SCALAR_TOKEN) {
641247738Sbapt                int plain_implicit = 0;
642247738Sbapt                int quoted_implicit = 0;
643247738Sbapt                end_mark = token->end_mark;
644247738Sbapt                if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
645247738Sbapt                        || (tag && strcmp((char *)tag, "!") == 0)) {
646247738Sbapt                    plain_implicit = 1;
647247738Sbapt                }
648247738Sbapt                else if (!tag) {
649247738Sbapt                    quoted_implicit = 1;
650247738Sbapt                }
651247738Sbapt                parser->state = POP(parser, parser->states);
652247738Sbapt                SCALAR_EVENT_INIT(*event, anchor, tag,
653247738Sbapt                        token->data.scalar.value, token->data.scalar.length,
654247738Sbapt                        plain_implicit, quoted_implicit,
655247738Sbapt                        token->data.scalar.style, start_mark, end_mark);
656247738Sbapt                SKIP_TOKEN(parser);
657247738Sbapt                return 1;
658247738Sbapt            }
659247738Sbapt            else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
660247738Sbapt                end_mark = token->end_mark;
661247738Sbapt                parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
662247738Sbapt                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
663247738Sbapt                        YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
664247738Sbapt                return 1;
665247738Sbapt            }
666247738Sbapt            else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
667247738Sbapt                end_mark = token->end_mark;
668247738Sbapt                parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
669247738Sbapt                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
670247738Sbapt                        YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
671247738Sbapt                return 1;
672247738Sbapt            }
673247738Sbapt            else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
674247738Sbapt                end_mark = token->end_mark;
675247738Sbapt                parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
676247738Sbapt                SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
677247738Sbapt                        YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
678247738Sbapt                return 1;
679247738Sbapt            }
680247738Sbapt            else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
681247738Sbapt                end_mark = token->end_mark;
682247738Sbapt                parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
683247738Sbapt                MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
684247738Sbapt                        YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
685247738Sbapt                return 1;
686247738Sbapt            }
687247738Sbapt            else if (anchor || tag) {
688247738Sbapt                yaml_char_t *value = yaml_malloc(1);
689247738Sbapt                if (!value) {
690247738Sbapt                    parser->error = YAML_MEMORY_ERROR;
691247738Sbapt                    goto error;
692247738Sbapt                }
693247738Sbapt                value[0] = '\0';
694247738Sbapt                parser->state = POP(parser, parser->states);
695247738Sbapt                SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
696247738Sbapt                        implicit, 0, YAML_PLAIN_SCALAR_STYLE,
697247738Sbapt                        start_mark, end_mark);
698247738Sbapt                return 1;
699247738Sbapt            }
700247738Sbapt            else {
701247738Sbapt                yaml_parser_set_parser_error_context(parser,
702247738Sbapt                        (block ? "while parsing a block node"
703247738Sbapt                         : "while parsing a flow node"), start_mark,
704247738Sbapt                        "did not find expected node content", token->start_mark);
705247738Sbapt                goto error;
706247738Sbapt            }
707247738Sbapt        }
708247738Sbapt    }
709247738Sbapt
710247738Sbapterror:
711247738Sbapt    yaml_free(anchor);
712247738Sbapt    yaml_free(tag_handle);
713247738Sbapt    yaml_free(tag_suffix);
714247738Sbapt    yaml_free(tag);
715247738Sbapt
716247738Sbapt    return 0;
717247738Sbapt}
718247738Sbapt
719247738Sbapt/*
720247738Sbapt * Parse the productions:
721247738Sbapt * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722247738Sbapt *                    ********************  *********** *             *********
723247738Sbapt */
724247738Sbapt
725247738Sbaptstatic int
726247738Sbaptyaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727247738Sbapt        yaml_event_t *event, int first)
728247738Sbapt{
729247738Sbapt    yaml_token_t *token;
730247738Sbapt
731247738Sbapt    if (first) {
732247738Sbapt        token = PEEK_TOKEN(parser);
733247738Sbapt        if (!PUSH(parser, parser->marks, token->start_mark))
734247738Sbapt            return 0;
735247738Sbapt        SKIP_TOKEN(parser);
736247738Sbapt    }
737247738Sbapt
738247738Sbapt    token = PEEK_TOKEN(parser);
739247738Sbapt    if (!token) return 0;
740247738Sbapt
741247738Sbapt    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
742247738Sbapt    {
743247738Sbapt        yaml_mark_t mark = token->end_mark;
744247738Sbapt        SKIP_TOKEN(parser);
745247738Sbapt        token = PEEK_TOKEN(parser);
746247738Sbapt        if (!token) return 0;
747247738Sbapt        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
748247738Sbapt                token->type != YAML_BLOCK_END_TOKEN) {
749247738Sbapt            if (!PUSH(parser, parser->states,
750247738Sbapt                        YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
751247738Sbapt                return 0;
752247738Sbapt            return yaml_parser_parse_node(parser, event, 1, 0);
753247738Sbapt        }
754247738Sbapt        else {
755247738Sbapt            parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756247738Sbapt            return yaml_parser_process_empty_scalar(parser, event, mark);
757247738Sbapt        }
758247738Sbapt    }
759247738Sbapt
760247738Sbapt    else if (token->type == YAML_BLOCK_END_TOKEN)
761247738Sbapt    {
762247738Sbapt        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
763247738Sbapt        parser->state = POP(parser, parser->states);
764247738Sbapt        dummy_mark = POP(parser, parser->marks);
765247738Sbapt        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
766247738Sbapt        SKIP_TOKEN(parser);
767247738Sbapt        return 1;
768247738Sbapt    }
769247738Sbapt
770247738Sbapt    else
771247738Sbapt    {
772247738Sbapt        return yaml_parser_set_parser_error_context(parser,
773247738Sbapt                "while parsing a block collection", POP(parser, parser->marks),
774247738Sbapt                "did not find expected '-' indicator", token->start_mark);
775247738Sbapt    }
776247738Sbapt}
777247738Sbapt
778247738Sbapt/*
779247738Sbapt * Parse the productions:
780247738Sbapt * indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
781247738Sbapt *                           *********** *
782247738Sbapt */
783247738Sbapt
784247738Sbaptstatic int
785247738Sbaptyaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
786247738Sbapt        yaml_event_t *event)
787247738Sbapt{
788247738Sbapt    yaml_token_t *token;
789247738Sbapt
790247738Sbapt    token = PEEK_TOKEN(parser);
791247738Sbapt    if (!token) return 0;
792247738Sbapt
793247738Sbapt    if (token->type == YAML_BLOCK_ENTRY_TOKEN)
794247738Sbapt    {
795247738Sbapt        yaml_mark_t mark = token->end_mark;
796247738Sbapt        SKIP_TOKEN(parser);
797247738Sbapt        token = PEEK_TOKEN(parser);
798247738Sbapt        if (!token) return 0;
799247738Sbapt        if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
800247738Sbapt                token->type != YAML_KEY_TOKEN &&
801247738Sbapt                token->type != YAML_VALUE_TOKEN &&
802247738Sbapt                token->type != YAML_BLOCK_END_TOKEN) {
803247738Sbapt            if (!PUSH(parser, parser->states,
804247738Sbapt                        YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
805247738Sbapt                return 0;
806247738Sbapt            return yaml_parser_parse_node(parser, event, 1, 0);
807247738Sbapt        }
808247738Sbapt        else {
809247738Sbapt            parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
810247738Sbapt            return yaml_parser_process_empty_scalar(parser, event, mark);
811247738Sbapt        }
812247738Sbapt    }
813247738Sbapt
814247738Sbapt    else
815247738Sbapt    {
816247738Sbapt        parser->state = POP(parser, parser->states);
817247738Sbapt        SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
818247738Sbapt        return 1;
819247738Sbapt    }
820247738Sbapt}
821247738Sbapt
822247738Sbapt/*
823247738Sbapt * Parse the productions:
824247738Sbapt * block_mapping        ::= BLOCK-MAPPING_START
825247738Sbapt *                          *******************
826247738Sbapt *                          ((KEY block_node_or_indentless_sequence?)?
827247738Sbapt *                            *** *
828247738Sbapt *                          (VALUE block_node_or_indentless_sequence?)?)*
829247738Sbapt *
830247738Sbapt *                          BLOCK-END
831247738Sbapt *                          *********
832247738Sbapt */
833247738Sbapt
834247738Sbaptstatic int
835247738Sbaptyaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
836247738Sbapt        yaml_event_t *event, int first)
837247738Sbapt{
838247738Sbapt    yaml_token_t *token;
839247738Sbapt
840247738Sbapt    if (first) {
841247738Sbapt        token = PEEK_TOKEN(parser);
842247738Sbapt        if (!PUSH(parser, parser->marks, token->start_mark))
843247738Sbapt            return 0;
844247738Sbapt        SKIP_TOKEN(parser);
845247738Sbapt    }
846247738Sbapt
847247738Sbapt    token = PEEK_TOKEN(parser);
848247738Sbapt    if (!token) return 0;
849247738Sbapt
850247738Sbapt    if (token->type == YAML_KEY_TOKEN)
851247738Sbapt    {
852247738Sbapt        yaml_mark_t mark = token->end_mark;
853247738Sbapt        SKIP_TOKEN(parser);
854247738Sbapt        token = PEEK_TOKEN(parser);
855247738Sbapt        if (!token) return 0;
856247738Sbapt        if (token->type != YAML_KEY_TOKEN &&
857247738Sbapt                token->type != YAML_VALUE_TOKEN &&
858247738Sbapt                token->type != YAML_BLOCK_END_TOKEN) {
859247738Sbapt            if (!PUSH(parser, parser->states,
860247738Sbapt                        YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
861247738Sbapt                return 0;
862247738Sbapt            return yaml_parser_parse_node(parser, event, 1, 1);
863247738Sbapt        }
864247738Sbapt        else {
865247738Sbapt            parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
866247738Sbapt            return yaml_parser_process_empty_scalar(parser, event, mark);
867247738Sbapt        }
868247738Sbapt    }
869247738Sbapt
870247738Sbapt    else if (token->type == YAML_BLOCK_END_TOKEN)
871247738Sbapt    {
872247738Sbapt        yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
873247738Sbapt        parser->state = POP(parser, parser->states);
874247738Sbapt        dummy_mark = POP(parser, parser->marks);
875247738Sbapt        MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
876247738Sbapt        SKIP_TOKEN(parser);
877247738Sbapt        return 1;
878247738Sbapt    }
879247738Sbapt
880247738Sbapt    else
881247738Sbapt    {
882247738Sbapt        return yaml_parser_set_parser_error_context(parser,
883247738Sbapt                "while parsing a block mapping", POP(parser, parser->marks),
884247738Sbapt                "did not find expected key", token->start_mark);
885247738Sbapt    }
886247738Sbapt}
887247738Sbapt
888247738Sbapt/*
889247738Sbapt * Parse the productions:
890247738Sbapt * block_mapping        ::= BLOCK-MAPPING_START
891247738Sbapt *
892247738Sbapt *                          ((KEY block_node_or_indentless_sequence?)?
893247738Sbapt *
894247738Sbapt *                          (VALUE block_node_or_indentless_sequence?)?)*
895247738Sbapt *                           ***** *
896247738Sbapt *                          BLOCK-END
897247738Sbapt *
898247738Sbapt */
899247738Sbapt
900247738Sbaptstatic int
901247738Sbaptyaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
902247738Sbapt        yaml_event_t *event)
903247738Sbapt{
904247738Sbapt    yaml_token_t *token;
905247738Sbapt
906247738Sbapt    token = PEEK_TOKEN(parser);
907247738Sbapt    if (!token) return 0;
908247738Sbapt
909247738Sbapt    if (token->type == YAML_VALUE_TOKEN)
910247738Sbapt    {
911247738Sbapt        yaml_mark_t mark = token->end_mark;
912247738Sbapt        SKIP_TOKEN(parser);
913247738Sbapt        token = PEEK_TOKEN(parser);
914247738Sbapt        if (!token) return 0;
915247738Sbapt        if (token->type != YAML_KEY_TOKEN &&
916247738Sbapt                token->type != YAML_VALUE_TOKEN &&
917247738Sbapt                token->type != YAML_BLOCK_END_TOKEN) {
918247738Sbapt            if (!PUSH(parser, parser->states,
919247738Sbapt                        YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
920247738Sbapt                return 0;
921247738Sbapt            return yaml_parser_parse_node(parser, event, 1, 1);
922247738Sbapt        }
923247738Sbapt        else {
924247738Sbapt            parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
925247738Sbapt            return yaml_parser_process_empty_scalar(parser, event, mark);
926247738Sbapt        }
927247738Sbapt    }
928247738Sbapt
929247738Sbapt    else
930247738Sbapt    {
931247738Sbapt        parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
932247738Sbapt        return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
933247738Sbapt    }
934247738Sbapt}
935247738Sbapt
936247738Sbapt/*
937247738Sbapt * Parse the productions:
938247738Sbapt * flow_sequence        ::= FLOW-SEQUENCE-START
939247738Sbapt *                          *******************
940247738Sbapt *                          (flow_sequence_entry FLOW-ENTRY)*
941247738Sbapt *                           *                   **********
942247738Sbapt *                          flow_sequence_entry?
943247738Sbapt *                          *
944247738Sbapt *                          FLOW-SEQUENCE-END
945247738Sbapt *                          *****************
946247738Sbapt * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
947247738Sbapt *                          *
948247738Sbapt */
949247738Sbapt
950247738Sbaptstatic int
951247738Sbaptyaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
952247738Sbapt        yaml_event_t *event, int first)
953247738Sbapt{
954247738Sbapt    yaml_token_t *token;
955247738Sbapt    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
956247738Sbapt
957247738Sbapt    if (first) {
958247738Sbapt        token = PEEK_TOKEN(parser);
959247738Sbapt        if (!PUSH(parser, parser->marks, token->start_mark))
960247738Sbapt            return 0;
961247738Sbapt        SKIP_TOKEN(parser);
962247738Sbapt    }
963247738Sbapt
964247738Sbapt    token = PEEK_TOKEN(parser);
965247738Sbapt    if (!token) return 0;
966247738Sbapt
967247738Sbapt    if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
968247738Sbapt    {
969247738Sbapt        if (!first) {
970247738Sbapt            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
971247738Sbapt                SKIP_TOKEN(parser);
972247738Sbapt                token = PEEK_TOKEN(parser);
973247738Sbapt                if (!token) return 0;
974247738Sbapt            }
975247738Sbapt            else {
976247738Sbapt                return yaml_parser_set_parser_error_context(parser,
977247738Sbapt                        "while parsing a flow sequence", POP(parser, parser->marks),
978247738Sbapt                        "did not find expected ',' or ']'", token->start_mark);
979247738Sbapt            }
980247738Sbapt        }
981247738Sbapt
982247738Sbapt        if (token->type == YAML_KEY_TOKEN) {
983247738Sbapt            parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
984247738Sbapt            MAPPING_START_EVENT_INIT(*event, NULL, NULL,
985247738Sbapt                    1, YAML_FLOW_MAPPING_STYLE,
986247738Sbapt                    token->start_mark, token->end_mark);
987247738Sbapt            SKIP_TOKEN(parser);
988247738Sbapt            return 1;
989247738Sbapt        }
990247738Sbapt
991247738Sbapt        else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
992247738Sbapt            if (!PUSH(parser, parser->states,
993247738Sbapt                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
994247738Sbapt                return 0;
995247738Sbapt            return yaml_parser_parse_node(parser, event, 0, 0);
996247738Sbapt        }
997247738Sbapt    }
998247738Sbapt
999247738Sbapt    parser->state = POP(parser, parser->states);
1000247738Sbapt    dummy_mark = POP(parser, parser->marks);
1001247738Sbapt    SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1002247738Sbapt    SKIP_TOKEN(parser);
1003247738Sbapt    return 1;
1004247738Sbapt}
1005247738Sbapt
1006247738Sbapt/*
1007247738Sbapt * Parse the productions:
1008247738Sbapt * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1009247738Sbapt *                                      *** *
1010247738Sbapt */
1011247738Sbapt
1012247738Sbaptstatic int
1013247738Sbaptyaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1014247738Sbapt        yaml_event_t *event)
1015247738Sbapt{
1016247738Sbapt    yaml_token_t *token;
1017247738Sbapt
1018247738Sbapt    token = PEEK_TOKEN(parser);
1019247738Sbapt    if (!token) return 0;
1020247738Sbapt
1021247738Sbapt    if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1022247738Sbapt            && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1023247738Sbapt        if (!PUSH(parser, parser->states,
1024247738Sbapt                    YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1025247738Sbapt            return 0;
1026247738Sbapt        return yaml_parser_parse_node(parser, event, 0, 0);
1027247738Sbapt    }
1028247738Sbapt    else {
1029247738Sbapt        yaml_mark_t mark = token->end_mark;
1030247738Sbapt        SKIP_TOKEN(parser);
1031247738Sbapt        parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1032247738Sbapt        return yaml_parser_process_empty_scalar(parser, event, mark);
1033247738Sbapt    }
1034247738Sbapt}
1035247738Sbapt
1036247738Sbapt/*
1037247738Sbapt * Parse the productions:
1038247738Sbapt * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1039247738Sbapt *                                                      ***** *
1040247738Sbapt */
1041247738Sbapt
1042247738Sbaptstatic int
1043247738Sbaptyaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1044247738Sbapt        yaml_event_t *event)
1045247738Sbapt{
1046247738Sbapt    yaml_token_t *token;
1047247738Sbapt
1048247738Sbapt    token = PEEK_TOKEN(parser);
1049247738Sbapt    if (!token) return 0;
1050247738Sbapt
1051247738Sbapt    if (token->type == YAML_VALUE_TOKEN) {
1052247738Sbapt        SKIP_TOKEN(parser);
1053247738Sbapt        token = PEEK_TOKEN(parser);
1054247738Sbapt        if (!token) return 0;
1055247738Sbapt        if (token->type != YAML_FLOW_ENTRY_TOKEN
1056247738Sbapt                && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1057247738Sbapt            if (!PUSH(parser, parser->states,
1058247738Sbapt                        YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1059247738Sbapt                return 0;
1060247738Sbapt            return yaml_parser_parse_node(parser, event, 0, 0);
1061247738Sbapt        }
1062247738Sbapt    }
1063247738Sbapt    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1064247738Sbapt    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1065247738Sbapt}
1066247738Sbapt
1067247738Sbapt/*
1068247738Sbapt * Parse the productions:
1069247738Sbapt * flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1070247738Sbapt *                                                                      *
1071247738Sbapt */
1072247738Sbapt
1073247738Sbaptstatic int
1074247738Sbaptyaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1075247738Sbapt        yaml_event_t *event)
1076247738Sbapt{
1077247738Sbapt    yaml_token_t *token;
1078247738Sbapt
1079247738Sbapt    token = PEEK_TOKEN(parser);
1080247738Sbapt    if (!token) return 0;
1081247738Sbapt
1082247738Sbapt    parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1083247738Sbapt
1084247738Sbapt    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1085247738Sbapt    return 1;
1086247738Sbapt}
1087247738Sbapt
1088247738Sbapt/*
1089247738Sbapt * Parse the productions:
1090247738Sbapt * flow_mapping         ::= FLOW-MAPPING-START
1091247738Sbapt *                          ******************
1092247738Sbapt *                          (flow_mapping_entry FLOW-ENTRY)*
1093247738Sbapt *                           *                  **********
1094247738Sbapt *                          flow_mapping_entry?
1095247738Sbapt *                          ******************
1096247738Sbapt *                          FLOW-MAPPING-END
1097247738Sbapt *                          ****************
1098247738Sbapt * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1099247738Sbapt *                          *           *** *
1100247738Sbapt */
1101247738Sbapt
1102247738Sbaptstatic int
1103247738Sbaptyaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1104247738Sbapt        yaml_event_t *event, int first)
1105247738Sbapt{
1106247738Sbapt    yaml_token_t *token;
1107247738Sbapt    yaml_mark_t dummy_mark;     /* Used to eliminate a compiler warning. */
1108247738Sbapt
1109247738Sbapt    if (first) {
1110247738Sbapt        token = PEEK_TOKEN(parser);
1111247738Sbapt        if (!PUSH(parser, parser->marks, token->start_mark))
1112247738Sbapt            return 0;
1113247738Sbapt        SKIP_TOKEN(parser);
1114247738Sbapt    }
1115247738Sbapt
1116247738Sbapt    token = PEEK_TOKEN(parser);
1117247738Sbapt    if (!token) return 0;
1118247738Sbapt
1119247738Sbapt    if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1120247738Sbapt    {
1121247738Sbapt        if (!first) {
1122247738Sbapt            if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1123247738Sbapt                SKIP_TOKEN(parser);
1124247738Sbapt                token = PEEK_TOKEN(parser);
1125247738Sbapt                if (!token) return 0;
1126247738Sbapt            }
1127247738Sbapt            else {
1128247738Sbapt                return yaml_parser_set_parser_error_context(parser,
1129247738Sbapt                        "while parsing a flow mapping", POP(parser, parser->marks),
1130247738Sbapt                        "did not find expected ',' or '}'", token->start_mark);
1131247738Sbapt            }
1132247738Sbapt        }
1133247738Sbapt
1134247738Sbapt        if (token->type == YAML_KEY_TOKEN) {
1135247738Sbapt            SKIP_TOKEN(parser);
1136247738Sbapt            token = PEEK_TOKEN(parser);
1137247738Sbapt            if (!token) return 0;
1138247738Sbapt            if (token->type != YAML_VALUE_TOKEN
1139247738Sbapt                    && token->type != YAML_FLOW_ENTRY_TOKEN
1140247738Sbapt                    && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1141247738Sbapt                if (!PUSH(parser, parser->states,
1142247738Sbapt                            YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1143247738Sbapt                    return 0;
1144247738Sbapt                return yaml_parser_parse_node(parser, event, 0, 0);
1145247738Sbapt            }
1146247738Sbapt            else {
1147247738Sbapt                parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1148247738Sbapt                return yaml_parser_process_empty_scalar(parser, event,
1149247738Sbapt                        token->start_mark);
1150247738Sbapt            }
1151247738Sbapt        }
1152247738Sbapt        else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1153247738Sbapt            if (!PUSH(parser, parser->states,
1154247738Sbapt                        YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1155247738Sbapt                return 0;
1156247738Sbapt            return yaml_parser_parse_node(parser, event, 0, 0);
1157247738Sbapt        }
1158247738Sbapt    }
1159247738Sbapt
1160247738Sbapt    parser->state = POP(parser, parser->states);
1161247738Sbapt    dummy_mark = POP(parser, parser->marks);
1162247738Sbapt    MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1163247738Sbapt    SKIP_TOKEN(parser);
1164247738Sbapt    return 1;
1165247738Sbapt}
1166247738Sbapt
1167247738Sbapt/*
1168247738Sbapt * Parse the productions:
1169247738Sbapt * flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1170247738Sbapt *                                   *                  ***** *
1171247738Sbapt */
1172247738Sbapt
1173247738Sbaptstatic int
1174247738Sbaptyaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1175247738Sbapt        yaml_event_t *event, int empty)
1176247738Sbapt{
1177247738Sbapt    yaml_token_t *token;
1178247738Sbapt
1179247738Sbapt    token = PEEK_TOKEN(parser);
1180247738Sbapt    if (!token) return 0;
1181247738Sbapt
1182247738Sbapt    if (empty) {
1183247738Sbapt        parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1184247738Sbapt        return yaml_parser_process_empty_scalar(parser, event,
1185247738Sbapt                token->start_mark);
1186247738Sbapt    }
1187247738Sbapt
1188247738Sbapt    if (token->type == YAML_VALUE_TOKEN) {
1189247738Sbapt        SKIP_TOKEN(parser);
1190247738Sbapt        token = PEEK_TOKEN(parser);
1191247738Sbapt        if (!token) return 0;
1192247738Sbapt        if (token->type != YAML_FLOW_ENTRY_TOKEN
1193247738Sbapt                && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1194247738Sbapt            if (!PUSH(parser, parser->states,
1195247738Sbapt                        YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1196247738Sbapt                return 0;
1197247738Sbapt            return yaml_parser_parse_node(parser, event, 0, 0);
1198247738Sbapt        }
1199247738Sbapt    }
1200247738Sbapt
1201247738Sbapt    parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1202247738Sbapt    return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1203247738Sbapt}
1204247738Sbapt
1205247738Sbapt/*
1206247738Sbapt * Generate an empty scalar event.
1207247738Sbapt */
1208247738Sbapt
1209247738Sbaptstatic int
1210247738Sbaptyaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1211247738Sbapt        yaml_mark_t mark)
1212247738Sbapt{
1213247738Sbapt    yaml_char_t *value;
1214247738Sbapt
1215247738Sbapt    value = yaml_malloc(1);
1216247738Sbapt    if (!value) {
1217247738Sbapt        parser->error = YAML_MEMORY_ERROR;
1218247738Sbapt        return 0;
1219247738Sbapt    }
1220247738Sbapt    value[0] = '\0';
1221247738Sbapt
1222247738Sbapt    SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1223247738Sbapt            1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1224247738Sbapt
1225247738Sbapt    return 1;
1226247738Sbapt}
1227247738Sbapt
1228247738Sbapt/*
1229247738Sbapt * Parse directives.
1230247738Sbapt */
1231247738Sbapt
1232247738Sbaptstatic int
1233247738Sbaptyaml_parser_process_directives(yaml_parser_t *parser,
1234247738Sbapt        yaml_version_directive_t **version_directive_ref,
1235247738Sbapt        yaml_tag_directive_t **tag_directives_start_ref,
1236247738Sbapt        yaml_tag_directive_t **tag_directives_end_ref)
1237247738Sbapt{
1238247738Sbapt    yaml_tag_directive_t default_tag_directives[] = {
1239247738Sbapt        {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1240247738Sbapt        {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1241247738Sbapt        {NULL, NULL}
1242247738Sbapt    };
1243247738Sbapt    yaml_tag_directive_t *default_tag_directive;
1244247738Sbapt    yaml_version_directive_t *version_directive = NULL;
1245247738Sbapt    struct {
1246247738Sbapt        yaml_tag_directive_t *start;
1247247738Sbapt        yaml_tag_directive_t *end;
1248247738Sbapt        yaml_tag_directive_t *top;
1249247738Sbapt    } tag_directives = { NULL, NULL, NULL };
1250247738Sbapt    yaml_token_t *token;
1251247738Sbapt
1252247738Sbapt    if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE))
1253247738Sbapt        goto error;
1254247738Sbapt
1255247738Sbapt    token = PEEK_TOKEN(parser);
1256247738Sbapt    if (!token) goto error;
1257247738Sbapt
1258247738Sbapt    while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1259247738Sbapt            token->type == YAML_TAG_DIRECTIVE_TOKEN)
1260247738Sbapt    {
1261247738Sbapt        if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1262247738Sbapt            if (version_directive) {
1263247738Sbapt                yaml_parser_set_parser_error(parser,
1264247738Sbapt                        "found duplicate %YAML directive", token->start_mark);
1265247738Sbapt                goto error;
1266247738Sbapt            }
1267247738Sbapt            if (token->data.version_directive.major != 1
1268247738Sbapt                    || token->data.version_directive.minor != 1) {
1269247738Sbapt                yaml_parser_set_parser_error(parser,
1270247738Sbapt                        "found incompatible YAML document", token->start_mark);
1271247738Sbapt                goto error;
1272247738Sbapt            }
1273247738Sbapt            version_directive = yaml_malloc(sizeof(yaml_version_directive_t));
1274247738Sbapt            if (!version_directive) {
1275247738Sbapt                parser->error = YAML_MEMORY_ERROR;
1276247738Sbapt                goto error;
1277247738Sbapt            }
1278247738Sbapt            version_directive->major = token->data.version_directive.major;
1279247738Sbapt            version_directive->minor = token->data.version_directive.minor;
1280247738Sbapt        }
1281247738Sbapt
1282247738Sbapt        else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1283247738Sbapt            yaml_tag_directive_t value;
1284247738Sbapt            value.handle = token->data.tag_directive.handle;
1285247738Sbapt            value.prefix = token->data.tag_directive.prefix;
1286247738Sbapt
1287247738Sbapt            if (!yaml_parser_append_tag_directive(parser, value, 0,
1288247738Sbapt                        token->start_mark))
1289247738Sbapt                goto error;
1290247738Sbapt            if (!PUSH(parser, tag_directives, value))
1291247738Sbapt                goto error;
1292247738Sbapt        }
1293247738Sbapt
1294247738Sbapt        SKIP_TOKEN(parser);
1295247738Sbapt        token = PEEK_TOKEN(parser);
1296247738Sbapt        if (!token) goto error;
1297247738Sbapt    }
1298247738Sbapt
1299247738Sbapt    for (default_tag_directive = default_tag_directives;
1300247738Sbapt            default_tag_directive->handle; default_tag_directive++) {
1301247738Sbapt        if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1302247738Sbapt                    token->start_mark))
1303247738Sbapt            goto error;
1304247738Sbapt    }
1305247738Sbapt
1306247738Sbapt    if (version_directive_ref) {
1307247738Sbapt        *version_directive_ref = version_directive;
1308247738Sbapt    }
1309247738Sbapt    if (tag_directives_start_ref) {
1310247738Sbapt        if (STACK_EMPTY(parser, tag_directives)) {
1311247738Sbapt            *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1312247738Sbapt            STACK_DEL(parser, tag_directives);
1313247738Sbapt        }
1314247738Sbapt        else {
1315247738Sbapt            *tag_directives_start_ref = tag_directives.start;
1316247738Sbapt            *tag_directives_end_ref = tag_directives.top;
1317247738Sbapt        }
1318247738Sbapt    }
1319247738Sbapt    else {
1320247738Sbapt        STACK_DEL(parser, tag_directives);
1321247738Sbapt    }
1322247738Sbapt
1323247738Sbapt    return 1;
1324247738Sbapt
1325247738Sbapterror:
1326247738Sbapt    yaml_free(version_directive);
1327247738Sbapt    while (!STACK_EMPTY(parser, tag_directives)) {
1328247738Sbapt        yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1329247738Sbapt        yaml_free(tag_directive.handle);
1330247738Sbapt        yaml_free(tag_directive.prefix);
1331247738Sbapt    }
1332247738Sbapt    STACK_DEL(parser, tag_directives);
1333247738Sbapt    return 0;
1334247738Sbapt}
1335247738Sbapt
1336247738Sbapt/*
1337247738Sbapt * Append a tag directive to the directives stack.
1338247738Sbapt */
1339247738Sbapt
1340247738Sbaptstatic int
1341247738Sbaptyaml_parser_append_tag_directive(yaml_parser_t *parser,
1342247738Sbapt        yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1343247738Sbapt{
1344247738Sbapt    yaml_tag_directive_t *tag_directive;
1345247738Sbapt    yaml_tag_directive_t copy = { NULL, NULL };
1346247738Sbapt
1347247738Sbapt    for (tag_directive = parser->tag_directives.start;
1348247738Sbapt            tag_directive != parser->tag_directives.top; tag_directive ++) {
1349247738Sbapt        if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1350247738Sbapt            if (allow_duplicates)
1351247738Sbapt                return 1;
1352247738Sbapt            return yaml_parser_set_parser_error(parser,
1353247738Sbapt                    "found duplicate %TAG directive", mark);
1354247738Sbapt        }
1355247738Sbapt    }
1356247738Sbapt
1357247738Sbapt    copy.handle = yaml_strdup(value.handle);
1358247738Sbapt    copy.prefix = yaml_strdup(value.prefix);
1359247738Sbapt    if (!copy.handle || !copy.prefix) {
1360247738Sbapt        parser->error = YAML_MEMORY_ERROR;
1361247738Sbapt        goto error;
1362247738Sbapt    }
1363247738Sbapt
1364247738Sbapt    if (!PUSH(parser, parser->tag_directives, copy))
1365247738Sbapt        goto error;
1366247738Sbapt
1367247738Sbapt    return 1;
1368247738Sbapt
1369247738Sbapterror:
1370247738Sbapt    yaml_free(copy.handle);
1371247738Sbapt    yaml_free(copy.prefix);
1372247738Sbapt    return 0;
1373247738Sbapt}
1374247738Sbapt
1375