parserc.go (40822B)
1 // 2 // Copyright (c) 2011-2019 Canonical Ltd 3 // Copyright (c) 2006-2010 Kirill Simonov 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy of 6 // this software and associated documentation files (the "Software"), to deal in 7 // the Software without restriction, including without limitation the rights to 8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 // of the Software, and to permit persons to whom the Software is furnished to do 10 // so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 // SOFTWARE. 22 23 package yaml 24 25 import ( 26 "bytes" 27 ) 28 29 // The parser implements the following grammar: 30 // 31 // stream ::= STREAM-START implicit_document? explicit_document* STREAM-END 32 // implicit_document ::= block_node DOCUMENT-END* 33 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 34 // block_node_or_indentless_sequence ::= 35 // ALIAS 36 // | properties (block_content | indentless_block_sequence)? 37 // | block_content 38 // | indentless_block_sequence 39 // block_node ::= ALIAS 40 // | properties block_content? 41 // | block_content 42 // flow_node ::= ALIAS 43 // | properties flow_content? 44 // | flow_content 45 // properties ::= TAG ANCHOR? | ANCHOR TAG? 46 // block_content ::= block_collection | flow_collection | SCALAR 47 // flow_content ::= flow_collection | SCALAR 48 // block_collection ::= block_sequence | block_mapping 49 // flow_collection ::= flow_sequence | flow_mapping 50 // block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 51 // indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 52 // block_mapping ::= BLOCK-MAPPING_START 53 // ((KEY block_node_or_indentless_sequence?)? 54 // (VALUE block_node_or_indentless_sequence?)?)* 55 // BLOCK-END 56 // flow_sequence ::= FLOW-SEQUENCE-START 57 // (flow_sequence_entry FLOW-ENTRY)* 58 // flow_sequence_entry? 59 // FLOW-SEQUENCE-END 60 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 61 // flow_mapping ::= FLOW-MAPPING-START 62 // (flow_mapping_entry FLOW-ENTRY)* 63 // flow_mapping_entry? 64 // FLOW-MAPPING-END 65 // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 66 67 // Peek the next token in the token queue. 68 func peek_token(parser *yaml_parser_t) *yaml_token_t { 69 if parser.token_available || yaml_parser_fetch_more_tokens(parser) { 70 token := &parser.tokens[parser.tokens_head] 71 yaml_parser_unfold_comments(parser, token) 72 return token 73 } 74 return nil 75 } 76 77 // yaml_parser_unfold_comments walks through the comments queue and joins all 78 // comments behind the position of the provided token into the respective 79 // top-level comment slices in the parser. 80 func yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) { 81 for parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index { 82 comment := &parser.comments[parser.comments_head] 83 if len(comment.head) > 0 { 84 if token.typ == yaml_BLOCK_END_TOKEN { 85 // No heads on ends, so keep comment.head for a follow up token. 86 break 87 } 88 if len(parser.head_comment) > 0 { 89 parser.head_comment = append(parser.head_comment, '\n') 90 } 91 parser.head_comment = append(parser.head_comment, comment.head...) 92 } 93 if len(comment.foot) > 0 { 94 if len(parser.foot_comment) > 0 { 95 parser.foot_comment = append(parser.foot_comment, '\n') 96 } 97 parser.foot_comment = append(parser.foot_comment, comment.foot...) 98 } 99 if len(comment.line) > 0 { 100 if len(parser.line_comment) > 0 { 101 parser.line_comment = append(parser.line_comment, '\n') 102 } 103 parser.line_comment = append(parser.line_comment, comment.line...) 104 } 105 *comment = yaml_comment_t{} 106 parser.comments_head++ 107 } 108 } 109 110 // Remove the next token from the queue (must be called after peek_token). 111 func skip_token(parser *yaml_parser_t) { 112 parser.token_available = false 113 parser.tokens_parsed++ 114 parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN 115 parser.tokens_head++ 116 } 117 118 // Get the next event. 119 func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool { 120 // Erase the event object. 121 *event = yaml_event_t{} 122 123 // No events after the end of the stream or error. 124 if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE { 125 return true 126 } 127 128 // Generate the next event. 129 return yaml_parser_state_machine(parser, event) 130 } 131 132 // Set parser error. 133 func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool { 134 parser.error = yaml_PARSER_ERROR 135 parser.problem = problem 136 parser.problem_mark = problem_mark 137 return false 138 } 139 140 func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool { 141 parser.error = yaml_PARSER_ERROR 142 parser.context = context 143 parser.context_mark = context_mark 144 parser.problem = problem 145 parser.problem_mark = problem_mark 146 return false 147 } 148 149 // State dispatcher. 150 func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool { 151 //trace("yaml_parser_state_machine", "state:", parser.state.String()) 152 153 switch parser.state { 154 case yaml_PARSE_STREAM_START_STATE: 155 return yaml_parser_parse_stream_start(parser, event) 156 157 case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE: 158 return yaml_parser_parse_document_start(parser, event, true) 159 160 case yaml_PARSE_DOCUMENT_START_STATE: 161 return yaml_parser_parse_document_start(parser, event, false) 162 163 case yaml_PARSE_DOCUMENT_CONTENT_STATE: 164 return yaml_parser_parse_document_content(parser, event) 165 166 case yaml_PARSE_DOCUMENT_END_STATE: 167 return yaml_parser_parse_document_end(parser, event) 168 169 case yaml_PARSE_BLOCK_NODE_STATE: 170 return yaml_parser_parse_node(parser, event, true, false) 171 172 case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: 173 return yaml_parser_parse_node(parser, event, true, true) 174 175 case yaml_PARSE_FLOW_NODE_STATE: 176 return yaml_parser_parse_node(parser, event, false, false) 177 178 case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: 179 return yaml_parser_parse_block_sequence_entry(parser, event, true) 180 181 case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: 182 return yaml_parser_parse_block_sequence_entry(parser, event, false) 183 184 case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: 185 return yaml_parser_parse_indentless_sequence_entry(parser, event) 186 187 case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: 188 return yaml_parser_parse_block_mapping_key(parser, event, true) 189 190 case yaml_PARSE_BLOCK_MAPPING_KEY_STATE: 191 return yaml_parser_parse_block_mapping_key(parser, event, false) 192 193 case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE: 194 return yaml_parser_parse_block_mapping_value(parser, event) 195 196 case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: 197 return yaml_parser_parse_flow_sequence_entry(parser, event, true) 198 199 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE: 200 return yaml_parser_parse_flow_sequence_entry(parser, event, false) 201 202 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: 203 return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event) 204 205 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: 206 return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event) 207 208 case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: 209 return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event) 210 211 case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: 212 return yaml_parser_parse_flow_mapping_key(parser, event, true) 213 214 case yaml_PARSE_FLOW_MAPPING_KEY_STATE: 215 return yaml_parser_parse_flow_mapping_key(parser, event, false) 216 217 case yaml_PARSE_FLOW_MAPPING_VALUE_STATE: 218 return yaml_parser_parse_flow_mapping_value(parser, event, false) 219 220 case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: 221 return yaml_parser_parse_flow_mapping_value(parser, event, true) 222 223 default: 224 panic("invalid parser state") 225 } 226 } 227 228 // Parse the production: 229 // stream ::= STREAM-START implicit_document? explicit_document* STREAM-END 230 // ************ 231 func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { 232 token := peek_token(parser) 233 if token == nil { 234 return false 235 } 236 if token.typ != yaml_STREAM_START_TOKEN { 237 return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark) 238 } 239 parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE 240 *event = yaml_event_t{ 241 typ: yaml_STREAM_START_EVENT, 242 start_mark: token.start_mark, 243 end_mark: token.end_mark, 244 encoding: token.encoding, 245 } 246 skip_token(parser) 247 return true 248 } 249 250 // Parse the productions: 251 // implicit_document ::= block_node DOCUMENT-END* 252 // * 253 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 254 // ************************* 255 func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { 256 257 token := peek_token(parser) 258 if token == nil { 259 return false 260 } 261 262 // Parse extra document end indicators. 263 if !implicit { 264 for token.typ == yaml_DOCUMENT_END_TOKEN { 265 skip_token(parser) 266 token = peek_token(parser) 267 if token == nil { 268 return false 269 } 270 } 271 } 272 273 if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && 274 token.typ != yaml_TAG_DIRECTIVE_TOKEN && 275 token.typ != yaml_DOCUMENT_START_TOKEN && 276 token.typ != yaml_STREAM_END_TOKEN { 277 // Parse an implicit document. 278 if !yaml_parser_process_directives(parser, nil, nil) { 279 return false 280 } 281 parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) 282 parser.state = yaml_PARSE_BLOCK_NODE_STATE 283 284 var head_comment []byte 285 if len(parser.head_comment) > 0 { 286 // [Go] Scan the header comment backwards, and if an empty line is found, break 287 // the header so the part before the last empty line goes into the 288 // document header, while the bottom of it goes into a follow up event. 289 for i := len(parser.head_comment) - 1; i > 0; i-- { 290 if parser.head_comment[i] == '\n' { 291 if i == len(parser.head_comment)-1 { 292 head_comment = parser.head_comment[:i] 293 parser.head_comment = parser.head_comment[i+1:] 294 break 295 } else if parser.head_comment[i-1] == '\n' { 296 head_comment = parser.head_comment[:i-1] 297 parser.head_comment = parser.head_comment[i+1:] 298 break 299 } 300 } 301 } 302 } 303 304 *event = yaml_event_t{ 305 typ: yaml_DOCUMENT_START_EVENT, 306 start_mark: token.start_mark, 307 end_mark: token.end_mark, 308 309 head_comment: head_comment, 310 } 311 312 } else if token.typ != yaml_STREAM_END_TOKEN { 313 // Parse an explicit document. 314 var version_directive *yaml_version_directive_t 315 var tag_directives []yaml_tag_directive_t 316 start_mark := token.start_mark 317 if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { 318 return false 319 } 320 token = peek_token(parser) 321 if token == nil { 322 return false 323 } 324 if token.typ != yaml_DOCUMENT_START_TOKEN { 325 yaml_parser_set_parser_error(parser, 326 "did not find expected <document start>", token.start_mark) 327 return false 328 } 329 parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) 330 parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE 331 end_mark := token.end_mark 332 333 *event = yaml_event_t{ 334 typ: yaml_DOCUMENT_START_EVENT, 335 start_mark: start_mark, 336 end_mark: end_mark, 337 version_directive: version_directive, 338 tag_directives: tag_directives, 339 implicit: false, 340 } 341 skip_token(parser) 342 343 } else { 344 // Parse the stream end. 345 parser.state = yaml_PARSE_END_STATE 346 *event = yaml_event_t{ 347 typ: yaml_STREAM_END_EVENT, 348 start_mark: token.start_mark, 349 end_mark: token.end_mark, 350 } 351 skip_token(parser) 352 } 353 354 return true 355 } 356 357 // Parse the productions: 358 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 359 // *********** 360 // 361 func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { 362 token := peek_token(parser) 363 if token == nil { 364 return false 365 } 366 367 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || 368 token.typ == yaml_TAG_DIRECTIVE_TOKEN || 369 token.typ == yaml_DOCUMENT_START_TOKEN || 370 token.typ == yaml_DOCUMENT_END_TOKEN || 371 token.typ == yaml_STREAM_END_TOKEN { 372 parser.state = parser.states[len(parser.states)-1] 373 parser.states = parser.states[:len(parser.states)-1] 374 return yaml_parser_process_empty_scalar(parser, event, 375 token.start_mark) 376 } 377 return yaml_parser_parse_node(parser, event, true, false) 378 } 379 380 // Parse the productions: 381 // implicit_document ::= block_node DOCUMENT-END* 382 // ************* 383 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 384 // 385 func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { 386 token := peek_token(parser) 387 if token == nil { 388 return false 389 } 390 391 start_mark := token.start_mark 392 end_mark := token.start_mark 393 394 implicit := true 395 if token.typ == yaml_DOCUMENT_END_TOKEN { 396 end_mark = token.end_mark 397 skip_token(parser) 398 implicit = false 399 } 400 401 parser.tag_directives = parser.tag_directives[:0] 402 403 parser.state = yaml_PARSE_DOCUMENT_START_STATE 404 *event = yaml_event_t{ 405 typ: yaml_DOCUMENT_END_EVENT, 406 start_mark: start_mark, 407 end_mark: end_mark, 408 implicit: implicit, 409 } 410 yaml_parser_set_event_comments(parser, event) 411 if len(event.head_comment) > 0 && len(event.foot_comment) == 0 { 412 event.foot_comment = event.head_comment 413 event.head_comment = nil 414 } 415 return true 416 } 417 418 func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) { 419 event.head_comment = parser.head_comment 420 event.line_comment = parser.line_comment 421 event.foot_comment = parser.foot_comment 422 parser.head_comment = nil 423 parser.line_comment = nil 424 parser.foot_comment = nil 425 parser.tail_comment = nil 426 parser.stem_comment = nil 427 } 428 429 // Parse the productions: 430 // block_node_or_indentless_sequence ::= 431 // ALIAS 432 // ***** 433 // | properties (block_content | indentless_block_sequence)? 434 // ********** * 435 // | block_content | indentless_block_sequence 436 // * 437 // block_node ::= ALIAS 438 // ***** 439 // | properties block_content? 440 // ********** * 441 // | block_content 442 // * 443 // flow_node ::= ALIAS 444 // ***** 445 // | properties flow_content? 446 // ********** * 447 // | flow_content 448 // * 449 // properties ::= TAG ANCHOR? | ANCHOR TAG? 450 // ************************* 451 // block_content ::= block_collection | flow_collection | SCALAR 452 // ****** 453 // flow_content ::= flow_collection | SCALAR 454 // ****** 455 func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { 456 //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() 457 458 token := peek_token(parser) 459 if token == nil { 460 return false 461 } 462 463 if token.typ == yaml_ALIAS_TOKEN { 464 parser.state = parser.states[len(parser.states)-1] 465 parser.states = parser.states[:len(parser.states)-1] 466 *event = yaml_event_t{ 467 typ: yaml_ALIAS_EVENT, 468 start_mark: token.start_mark, 469 end_mark: token.end_mark, 470 anchor: token.value, 471 } 472 yaml_parser_set_event_comments(parser, event) 473 skip_token(parser) 474 return true 475 } 476 477 start_mark := token.start_mark 478 end_mark := token.start_mark 479 480 var tag_token bool 481 var tag_handle, tag_suffix, anchor []byte 482 var tag_mark yaml_mark_t 483 if token.typ == yaml_ANCHOR_TOKEN { 484 anchor = token.value 485 start_mark = token.start_mark 486 end_mark = token.end_mark 487 skip_token(parser) 488 token = peek_token(parser) 489 if token == nil { 490 return false 491 } 492 if token.typ == yaml_TAG_TOKEN { 493 tag_token = true 494 tag_handle = token.value 495 tag_suffix = token.suffix 496 tag_mark = token.start_mark 497 end_mark = token.end_mark 498 skip_token(parser) 499 token = peek_token(parser) 500 if token == nil { 501 return false 502 } 503 } 504 } else if token.typ == yaml_TAG_TOKEN { 505 tag_token = true 506 tag_handle = token.value 507 tag_suffix = token.suffix 508 start_mark = token.start_mark 509 tag_mark = token.start_mark 510 end_mark = token.end_mark 511 skip_token(parser) 512 token = peek_token(parser) 513 if token == nil { 514 return false 515 } 516 if token.typ == yaml_ANCHOR_TOKEN { 517 anchor = token.value 518 end_mark = token.end_mark 519 skip_token(parser) 520 token = peek_token(parser) 521 if token == nil { 522 return false 523 } 524 } 525 } 526 527 var tag []byte 528 if tag_token { 529 if len(tag_handle) == 0 { 530 tag = tag_suffix 531 tag_suffix = nil 532 } else { 533 for i := range parser.tag_directives { 534 if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { 535 tag = append([]byte(nil), parser.tag_directives[i].prefix...) 536 tag = append(tag, tag_suffix...) 537 break 538 } 539 } 540 if len(tag) == 0 { 541 yaml_parser_set_parser_error_context(parser, 542 "while parsing a node", start_mark, 543 "found undefined tag handle", tag_mark) 544 return false 545 } 546 } 547 } 548 549 implicit := len(tag) == 0 550 if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { 551 end_mark = token.end_mark 552 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 553 *event = yaml_event_t{ 554 typ: yaml_SEQUENCE_START_EVENT, 555 start_mark: start_mark, 556 end_mark: end_mark, 557 anchor: anchor, 558 tag: tag, 559 implicit: implicit, 560 style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), 561 } 562 return true 563 } 564 if token.typ == yaml_SCALAR_TOKEN { 565 var plain_implicit, quoted_implicit bool 566 end_mark = token.end_mark 567 if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { 568 plain_implicit = true 569 } else if len(tag) == 0 { 570 quoted_implicit = true 571 } 572 parser.state = parser.states[len(parser.states)-1] 573 parser.states = parser.states[:len(parser.states)-1] 574 575 *event = yaml_event_t{ 576 typ: yaml_SCALAR_EVENT, 577 start_mark: start_mark, 578 end_mark: end_mark, 579 anchor: anchor, 580 tag: tag, 581 value: token.value, 582 implicit: plain_implicit, 583 quoted_implicit: quoted_implicit, 584 style: yaml_style_t(token.style), 585 } 586 yaml_parser_set_event_comments(parser, event) 587 skip_token(parser) 588 return true 589 } 590 if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { 591 // [Go] Some of the events below can be merged as they differ only on style. 592 end_mark = token.end_mark 593 parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE 594 *event = yaml_event_t{ 595 typ: yaml_SEQUENCE_START_EVENT, 596 start_mark: start_mark, 597 end_mark: end_mark, 598 anchor: anchor, 599 tag: tag, 600 implicit: implicit, 601 style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), 602 } 603 yaml_parser_set_event_comments(parser, event) 604 return true 605 } 606 if token.typ == yaml_FLOW_MAPPING_START_TOKEN { 607 end_mark = token.end_mark 608 parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE 609 *event = yaml_event_t{ 610 typ: yaml_MAPPING_START_EVENT, 611 start_mark: start_mark, 612 end_mark: end_mark, 613 anchor: anchor, 614 tag: tag, 615 implicit: implicit, 616 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 617 } 618 yaml_parser_set_event_comments(parser, event) 619 return true 620 } 621 if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { 622 end_mark = token.end_mark 623 parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE 624 *event = yaml_event_t{ 625 typ: yaml_SEQUENCE_START_EVENT, 626 start_mark: start_mark, 627 end_mark: end_mark, 628 anchor: anchor, 629 tag: tag, 630 implicit: implicit, 631 style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), 632 } 633 if parser.stem_comment != nil { 634 event.head_comment = parser.stem_comment 635 parser.stem_comment = nil 636 } 637 return true 638 } 639 if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { 640 end_mark = token.end_mark 641 parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE 642 *event = yaml_event_t{ 643 typ: yaml_MAPPING_START_EVENT, 644 start_mark: start_mark, 645 end_mark: end_mark, 646 anchor: anchor, 647 tag: tag, 648 implicit: implicit, 649 style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), 650 } 651 if parser.stem_comment != nil { 652 event.head_comment = parser.stem_comment 653 parser.stem_comment = nil 654 } 655 return true 656 } 657 if len(anchor) > 0 || len(tag) > 0 { 658 parser.state = parser.states[len(parser.states)-1] 659 parser.states = parser.states[:len(parser.states)-1] 660 661 *event = yaml_event_t{ 662 typ: yaml_SCALAR_EVENT, 663 start_mark: start_mark, 664 end_mark: end_mark, 665 anchor: anchor, 666 tag: tag, 667 implicit: implicit, 668 quoted_implicit: false, 669 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 670 } 671 return true 672 } 673 674 context := "while parsing a flow node" 675 if block { 676 context = "while parsing a block node" 677 } 678 yaml_parser_set_parser_error_context(parser, context, start_mark, 679 "did not find expected node content", token.start_mark) 680 return false 681 } 682 683 // Parse the productions: 684 // block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 685 // ******************** *********** * ********* 686 // 687 func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 688 if first { 689 token := peek_token(parser) 690 if token == nil { 691 return false 692 } 693 parser.marks = append(parser.marks, token.start_mark) 694 skip_token(parser) 695 } 696 697 token := peek_token(parser) 698 if token == nil { 699 return false 700 } 701 702 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 703 mark := token.end_mark 704 prior_head_len := len(parser.head_comment) 705 skip_token(parser) 706 yaml_parser_split_stem_comment(parser, prior_head_len) 707 token = peek_token(parser) 708 if token == nil { 709 return false 710 } 711 if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { 712 parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) 713 return yaml_parser_parse_node(parser, event, true, false) 714 } else { 715 parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE 716 return yaml_parser_process_empty_scalar(parser, event, mark) 717 } 718 } 719 if token.typ == yaml_BLOCK_END_TOKEN { 720 parser.state = parser.states[len(parser.states)-1] 721 parser.states = parser.states[:len(parser.states)-1] 722 parser.marks = parser.marks[:len(parser.marks)-1] 723 724 *event = yaml_event_t{ 725 typ: yaml_SEQUENCE_END_EVENT, 726 start_mark: token.start_mark, 727 end_mark: token.end_mark, 728 } 729 730 skip_token(parser) 731 return true 732 } 733 734 context_mark := parser.marks[len(parser.marks)-1] 735 parser.marks = parser.marks[:len(parser.marks)-1] 736 return yaml_parser_set_parser_error_context(parser, 737 "while parsing a block collection", context_mark, 738 "did not find expected '-' indicator", token.start_mark) 739 } 740 741 // Parse the productions: 742 // indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 743 // *********** * 744 func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { 745 token := peek_token(parser) 746 if token == nil { 747 return false 748 } 749 750 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 751 mark := token.end_mark 752 prior_head_len := len(parser.head_comment) 753 skip_token(parser) 754 yaml_parser_split_stem_comment(parser, prior_head_len) 755 token = peek_token(parser) 756 if token == nil { 757 return false 758 } 759 if token.typ != yaml_BLOCK_ENTRY_TOKEN && 760 token.typ != yaml_KEY_TOKEN && 761 token.typ != yaml_VALUE_TOKEN && 762 token.typ != yaml_BLOCK_END_TOKEN { 763 parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) 764 return yaml_parser_parse_node(parser, event, true, false) 765 } 766 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 767 return yaml_parser_process_empty_scalar(parser, event, mark) 768 } 769 parser.state = parser.states[len(parser.states)-1] 770 parser.states = parser.states[:len(parser.states)-1] 771 772 *event = yaml_event_t{ 773 typ: yaml_SEQUENCE_END_EVENT, 774 start_mark: token.start_mark, 775 end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? 776 } 777 return true 778 } 779 780 // Split stem comment from head comment. 781 // 782 // When a sequence or map is found under a sequence entry, the former head comment 783 // is assigned to the underlying sequence or map as a whole, not the individual 784 // sequence or map entry as would be expected otherwise. To handle this case the 785 // previous head comment is moved aside as the stem comment. 786 func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { 787 if stem_len == 0 { 788 return 789 } 790 791 token := peek_token(parser) 792 if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN { 793 return 794 } 795 796 parser.stem_comment = parser.head_comment[:stem_len] 797 if len(parser.head_comment) == stem_len { 798 parser.head_comment = nil 799 } else { 800 // Copy suffix to prevent very strange bugs if someone ever appends 801 // further bytes to the prefix in the stem_comment slice above. 802 parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...) 803 } 804 } 805 806 // Parse the productions: 807 // block_mapping ::= BLOCK-MAPPING_START 808 // ******************* 809 // ((KEY block_node_or_indentless_sequence?)? 810 // *** * 811 // (VALUE block_node_or_indentless_sequence?)?)* 812 // 813 // BLOCK-END 814 // ********* 815 // 816 func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 817 if first { 818 token := peek_token(parser) 819 if token == nil { 820 return false 821 } 822 parser.marks = append(parser.marks, token.start_mark) 823 skip_token(parser) 824 } 825 826 token := peek_token(parser) 827 if token == nil { 828 return false 829 } 830 831 // [Go] A tail comment was left from the prior mapping value processed. Emit an event 832 // as it needs to be processed with that value and not the following key. 833 if len(parser.tail_comment) > 0 { 834 *event = yaml_event_t{ 835 typ: yaml_TAIL_COMMENT_EVENT, 836 start_mark: token.start_mark, 837 end_mark: token.end_mark, 838 foot_comment: parser.tail_comment, 839 } 840 parser.tail_comment = nil 841 return true 842 } 843 844 if token.typ == yaml_KEY_TOKEN { 845 mark := token.end_mark 846 skip_token(parser) 847 token = peek_token(parser) 848 if token == nil { 849 return false 850 } 851 if token.typ != yaml_KEY_TOKEN && 852 token.typ != yaml_VALUE_TOKEN && 853 token.typ != yaml_BLOCK_END_TOKEN { 854 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) 855 return yaml_parser_parse_node(parser, event, true, true) 856 } else { 857 parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE 858 return yaml_parser_process_empty_scalar(parser, event, mark) 859 } 860 } else if token.typ == yaml_BLOCK_END_TOKEN { 861 parser.state = parser.states[len(parser.states)-1] 862 parser.states = parser.states[:len(parser.states)-1] 863 parser.marks = parser.marks[:len(parser.marks)-1] 864 *event = yaml_event_t{ 865 typ: yaml_MAPPING_END_EVENT, 866 start_mark: token.start_mark, 867 end_mark: token.end_mark, 868 } 869 yaml_parser_set_event_comments(parser, event) 870 skip_token(parser) 871 return true 872 } 873 874 context_mark := parser.marks[len(parser.marks)-1] 875 parser.marks = parser.marks[:len(parser.marks)-1] 876 return yaml_parser_set_parser_error_context(parser, 877 "while parsing a block mapping", context_mark, 878 "did not find expected key", token.start_mark) 879 } 880 881 // Parse the productions: 882 // block_mapping ::= BLOCK-MAPPING_START 883 // 884 // ((KEY block_node_or_indentless_sequence?)? 885 // 886 // (VALUE block_node_or_indentless_sequence?)?)* 887 // ***** * 888 // BLOCK-END 889 // 890 // 891 func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 892 token := peek_token(parser) 893 if token == nil { 894 return false 895 } 896 if token.typ == yaml_VALUE_TOKEN { 897 mark := token.end_mark 898 skip_token(parser) 899 token = peek_token(parser) 900 if token == nil { 901 return false 902 } 903 if token.typ != yaml_KEY_TOKEN && 904 token.typ != yaml_VALUE_TOKEN && 905 token.typ != yaml_BLOCK_END_TOKEN { 906 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) 907 return yaml_parser_parse_node(parser, event, true, true) 908 } 909 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 910 return yaml_parser_process_empty_scalar(parser, event, mark) 911 } 912 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 913 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 914 } 915 916 // Parse the productions: 917 // flow_sequence ::= FLOW-SEQUENCE-START 918 // ******************* 919 // (flow_sequence_entry FLOW-ENTRY)* 920 // * ********** 921 // flow_sequence_entry? 922 // * 923 // FLOW-SEQUENCE-END 924 // ***************** 925 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 926 // * 927 // 928 func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 929 if first { 930 token := peek_token(parser) 931 if token == nil { 932 return false 933 } 934 parser.marks = append(parser.marks, token.start_mark) 935 skip_token(parser) 936 } 937 token := peek_token(parser) 938 if token == nil { 939 return false 940 } 941 if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 942 if !first { 943 if token.typ == yaml_FLOW_ENTRY_TOKEN { 944 skip_token(parser) 945 token = peek_token(parser) 946 if token == nil { 947 return false 948 } 949 } else { 950 context_mark := parser.marks[len(parser.marks)-1] 951 parser.marks = parser.marks[:len(parser.marks)-1] 952 return yaml_parser_set_parser_error_context(parser, 953 "while parsing a flow sequence", context_mark, 954 "did not find expected ',' or ']'", token.start_mark) 955 } 956 } 957 958 if token.typ == yaml_KEY_TOKEN { 959 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE 960 *event = yaml_event_t{ 961 typ: yaml_MAPPING_START_EVENT, 962 start_mark: token.start_mark, 963 end_mark: token.end_mark, 964 implicit: true, 965 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 966 } 967 skip_token(parser) 968 return true 969 } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 970 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) 971 return yaml_parser_parse_node(parser, event, false, false) 972 } 973 } 974 975 parser.state = parser.states[len(parser.states)-1] 976 parser.states = parser.states[:len(parser.states)-1] 977 parser.marks = parser.marks[:len(parser.marks)-1] 978 979 *event = yaml_event_t{ 980 typ: yaml_SEQUENCE_END_EVENT, 981 start_mark: token.start_mark, 982 end_mark: token.end_mark, 983 } 984 yaml_parser_set_event_comments(parser, event) 985 986 skip_token(parser) 987 return true 988 } 989 990 // 991 // Parse the productions: 992 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 993 // *** * 994 // 995 func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { 996 token := peek_token(parser) 997 if token == nil { 998 return false 999 } 1000 if token.typ != yaml_VALUE_TOKEN && 1001 token.typ != yaml_FLOW_ENTRY_TOKEN && 1002 token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 1003 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) 1004 return yaml_parser_parse_node(parser, event, false, false) 1005 } 1006 mark := token.end_mark 1007 skip_token(parser) 1008 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE 1009 return yaml_parser_process_empty_scalar(parser, event, mark) 1010 } 1011 1012 // Parse the productions: 1013 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1014 // ***** * 1015 // 1016 func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 1017 token := peek_token(parser) 1018 if token == nil { 1019 return false 1020 } 1021 if token.typ == yaml_VALUE_TOKEN { 1022 skip_token(parser) 1023 token := peek_token(parser) 1024 if token == nil { 1025 return false 1026 } 1027 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 1028 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) 1029 return yaml_parser_parse_node(parser, event, false, false) 1030 } 1031 } 1032 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE 1033 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1034 } 1035 1036 // Parse the productions: 1037 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1038 // * 1039 // 1040 func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { 1041 token := peek_token(parser) 1042 if token == nil { 1043 return false 1044 } 1045 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE 1046 *event = yaml_event_t{ 1047 typ: yaml_MAPPING_END_EVENT, 1048 start_mark: token.start_mark, 1049 end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? 1050 } 1051 return true 1052 } 1053 1054 // Parse the productions: 1055 // flow_mapping ::= FLOW-MAPPING-START 1056 // ****************** 1057 // (flow_mapping_entry FLOW-ENTRY)* 1058 // * ********** 1059 // flow_mapping_entry? 1060 // ****************** 1061 // FLOW-MAPPING-END 1062 // **************** 1063 // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1064 // * *** * 1065 // 1066 func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 1067 if first { 1068 token := peek_token(parser) 1069 parser.marks = append(parser.marks, token.start_mark) 1070 skip_token(parser) 1071 } 1072 1073 token := peek_token(parser) 1074 if token == nil { 1075 return false 1076 } 1077 1078 if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1079 if !first { 1080 if token.typ == yaml_FLOW_ENTRY_TOKEN { 1081 skip_token(parser) 1082 token = peek_token(parser) 1083 if token == nil { 1084 return false 1085 } 1086 } else { 1087 context_mark := parser.marks[len(parser.marks)-1] 1088 parser.marks = parser.marks[:len(parser.marks)-1] 1089 return yaml_parser_set_parser_error_context(parser, 1090 "while parsing a flow mapping", context_mark, 1091 "did not find expected ',' or '}'", token.start_mark) 1092 } 1093 } 1094 1095 if token.typ == yaml_KEY_TOKEN { 1096 skip_token(parser) 1097 token = peek_token(parser) 1098 if token == nil { 1099 return false 1100 } 1101 if token.typ != yaml_VALUE_TOKEN && 1102 token.typ != yaml_FLOW_ENTRY_TOKEN && 1103 token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1104 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) 1105 return yaml_parser_parse_node(parser, event, false, false) 1106 } else { 1107 parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE 1108 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1109 } 1110 } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1111 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) 1112 return yaml_parser_parse_node(parser, event, false, false) 1113 } 1114 } 1115 1116 parser.state = parser.states[len(parser.states)-1] 1117 parser.states = parser.states[:len(parser.states)-1] 1118 parser.marks = parser.marks[:len(parser.marks)-1] 1119 *event = yaml_event_t{ 1120 typ: yaml_MAPPING_END_EVENT, 1121 start_mark: token.start_mark, 1122 end_mark: token.end_mark, 1123 } 1124 yaml_parser_set_event_comments(parser, event) 1125 skip_token(parser) 1126 return true 1127 } 1128 1129 // Parse the productions: 1130 // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1131 // * ***** * 1132 // 1133 func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { 1134 token := peek_token(parser) 1135 if token == nil { 1136 return false 1137 } 1138 if empty { 1139 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1140 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1141 } 1142 if token.typ == yaml_VALUE_TOKEN { 1143 skip_token(parser) 1144 token = peek_token(parser) 1145 if token == nil { 1146 return false 1147 } 1148 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1149 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) 1150 return yaml_parser_parse_node(parser, event, false, false) 1151 } 1152 } 1153 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1154 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1155 } 1156 1157 // Generate an empty scalar event. 1158 func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { 1159 *event = yaml_event_t{ 1160 typ: yaml_SCALAR_EVENT, 1161 start_mark: mark, 1162 end_mark: mark, 1163 value: nil, // Empty 1164 implicit: true, 1165 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 1166 } 1167 return true 1168 } 1169 1170 var default_tag_directives = []yaml_tag_directive_t{ 1171 {[]byte("!"), []byte("!")}, 1172 {[]byte("!!"), []byte("tag:yaml.org,2002:")}, 1173 } 1174 1175 // Parse directives. 1176 func yaml_parser_process_directives(parser *yaml_parser_t, 1177 version_directive_ref **yaml_version_directive_t, 1178 tag_directives_ref *[]yaml_tag_directive_t) bool { 1179 1180 var version_directive *yaml_version_directive_t 1181 var tag_directives []yaml_tag_directive_t 1182 1183 token := peek_token(parser) 1184 if token == nil { 1185 return false 1186 } 1187 1188 for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1189 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { 1190 if version_directive != nil { 1191 yaml_parser_set_parser_error(parser, 1192 "found duplicate %YAML directive", token.start_mark) 1193 return false 1194 } 1195 if token.major != 1 || token.minor != 1 { 1196 yaml_parser_set_parser_error(parser, 1197 "found incompatible YAML document", token.start_mark) 1198 return false 1199 } 1200 version_directive = &yaml_version_directive_t{ 1201 major: token.major, 1202 minor: token.minor, 1203 } 1204 } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1205 value := yaml_tag_directive_t{ 1206 handle: token.value, 1207 prefix: token.prefix, 1208 } 1209 if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { 1210 return false 1211 } 1212 tag_directives = append(tag_directives, value) 1213 } 1214 1215 skip_token(parser) 1216 token = peek_token(parser) 1217 if token == nil { 1218 return false 1219 } 1220 } 1221 1222 for i := range default_tag_directives { 1223 if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { 1224 return false 1225 } 1226 } 1227 1228 if version_directive_ref != nil { 1229 *version_directive_ref = version_directive 1230 } 1231 if tag_directives_ref != nil { 1232 *tag_directives_ref = tag_directives 1233 } 1234 return true 1235 } 1236 1237 // Append a tag directive to the directives stack. 1238 func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { 1239 for i := range parser.tag_directives { 1240 if bytes.Equal(value.handle, parser.tag_directives[i].handle) { 1241 if allow_duplicates { 1242 return true 1243 } 1244 return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) 1245 } 1246 } 1247 1248 // [Go] I suspect the copy is unnecessary. This was likely done 1249 // because there was no way to track ownership of the data. 1250 value_copy := yaml_tag_directive_t{ 1251 handle: make([]byte, len(value.handle)), 1252 prefix: make([]byte, len(value.prefix)), 1253 } 1254 copy(value_copy.handle, value.handle) 1255 copy(value_copy.prefix, value.prefix) 1256 parser.tag_directives = append(parser.tag_directives, value_copy) 1257 return true 1258 }