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