gitee.com/quant1x/pkg@v0.2.8/yaml/parserc.go (about) 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 // ************ 232 func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { 233 token := peek_token(parser) 234 if token == nil { 235 return false 236 } 237 if token.typ != yaml_STREAM_START_TOKEN { 238 return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark) 239 } 240 parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE 241 *event = yaml_event_t{ 242 typ: yaml_STREAM_START_EVENT, 243 start_mark: token.start_mark, 244 end_mark: token.end_mark, 245 encoding: token.encoding, 246 } 247 skip_token(parser) 248 return true 249 } 250 251 // Parse the productions: 252 // implicit_document ::= block_node DOCUMENT-END* 253 // 254 // * 255 // 256 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 257 // 258 // ************************* 259 func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { 260 261 token := peek_token(parser) 262 if token == nil { 263 return false 264 } 265 266 // Parse extra document end indicators. 267 if !implicit { 268 for token.typ == yaml_DOCUMENT_END_TOKEN { 269 skip_token(parser) 270 token = peek_token(parser) 271 if token == nil { 272 return false 273 } 274 } 275 } 276 277 if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN && 278 token.typ != yaml_TAG_DIRECTIVE_TOKEN && 279 token.typ != yaml_DOCUMENT_START_TOKEN && 280 token.typ != yaml_STREAM_END_TOKEN { 281 // Parse an implicit document. 282 if !yaml_parser_process_directives(parser, nil, nil) { 283 return false 284 } 285 parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) 286 parser.state = yaml_PARSE_BLOCK_NODE_STATE 287 288 var head_comment []byte 289 if len(parser.head_comment) > 0 { 290 // [Go] Scan the header comment backwards, and if an empty line is found, break 291 // the header so the part before the last empty line goes into the 292 // document header, while the bottom of it goes into a follow up event. 293 for i := len(parser.head_comment) - 1; i > 0; i-- { 294 if parser.head_comment[i] == '\n' { 295 if i == len(parser.head_comment)-1 { 296 head_comment = parser.head_comment[:i] 297 parser.head_comment = parser.head_comment[i+1:] 298 break 299 } else if parser.head_comment[i-1] == '\n' { 300 head_comment = parser.head_comment[:i-1] 301 parser.head_comment = parser.head_comment[i+1:] 302 break 303 } 304 } 305 } 306 } 307 308 *event = yaml_event_t{ 309 typ: yaml_DOCUMENT_START_EVENT, 310 start_mark: token.start_mark, 311 end_mark: token.end_mark, 312 313 head_comment: head_comment, 314 } 315 316 } else if token.typ != yaml_STREAM_END_TOKEN { 317 // Parse an explicit document. 318 var version_directive *yaml_version_directive_t 319 var tag_directives []yaml_tag_directive_t 320 start_mark := token.start_mark 321 if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) { 322 return false 323 } 324 token = peek_token(parser) 325 if token == nil { 326 return false 327 } 328 if token.typ != yaml_DOCUMENT_START_TOKEN { 329 yaml_parser_set_parser_error(parser, 330 "did not find expected <document start>", token.start_mark) 331 return false 332 } 333 parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE) 334 parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE 335 end_mark := token.end_mark 336 337 *event = yaml_event_t{ 338 typ: yaml_DOCUMENT_START_EVENT, 339 start_mark: start_mark, 340 end_mark: end_mark, 341 version_directive: version_directive, 342 tag_directives: tag_directives, 343 implicit: false, 344 } 345 skip_token(parser) 346 347 } else { 348 // Parse the stream end. 349 parser.state = yaml_PARSE_END_STATE 350 *event = yaml_event_t{ 351 typ: yaml_STREAM_END_EVENT, 352 start_mark: token.start_mark, 353 end_mark: token.end_mark, 354 } 355 skip_token(parser) 356 } 357 358 return true 359 } 360 361 // Parse the productions: 362 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 363 // 364 // *********** 365 func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { 366 token := peek_token(parser) 367 if token == nil { 368 return false 369 } 370 371 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN || 372 token.typ == yaml_TAG_DIRECTIVE_TOKEN || 373 token.typ == yaml_DOCUMENT_START_TOKEN || 374 token.typ == yaml_DOCUMENT_END_TOKEN || 375 token.typ == yaml_STREAM_END_TOKEN { 376 parser.state = parser.states[len(parser.states)-1] 377 parser.states = parser.states[:len(parser.states)-1] 378 return yaml_parser_process_empty_scalar(parser, event, 379 token.start_mark) 380 } 381 return yaml_parser_parse_node(parser, event, true, false) 382 } 383 384 // Parse the productions: 385 // implicit_document ::= block_node DOCUMENT-END* 386 // 387 // ************* 388 // 389 // explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* 390 func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { 391 token := peek_token(parser) 392 if token == nil { 393 return false 394 } 395 396 start_mark := token.start_mark 397 end_mark := token.start_mark 398 399 implicit := true 400 if token.typ == yaml_DOCUMENT_END_TOKEN { 401 end_mark = token.end_mark 402 skip_token(parser) 403 implicit = false 404 } 405 406 parser.tag_directives = parser.tag_directives[:0] 407 408 parser.state = yaml_PARSE_DOCUMENT_START_STATE 409 *event = yaml_event_t{ 410 typ: yaml_DOCUMENT_END_EVENT, 411 start_mark: start_mark, 412 end_mark: end_mark, 413 implicit: implicit, 414 } 415 yaml_parser_set_event_comments(parser, event) 416 if len(event.head_comment) > 0 && len(event.foot_comment) == 0 { 417 event.foot_comment = event.head_comment 418 event.head_comment = nil 419 } 420 return true 421 } 422 423 func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) { 424 event.head_comment = parser.head_comment 425 event.line_comment = parser.line_comment 426 event.foot_comment = parser.foot_comment 427 parser.head_comment = nil 428 parser.line_comment = nil 429 parser.foot_comment = nil 430 parser.tail_comment = nil 431 parser.stem_comment = nil 432 } 433 434 // Parse the productions: 435 // block_node_or_indentless_sequence ::= 436 // 437 // ALIAS 438 // ***** 439 // | properties (block_content | indentless_block_sequence)? 440 // ********** * 441 // | block_content | indentless_block_sequence 442 // * 443 // 444 // block_node ::= ALIAS 445 // 446 // ***** 447 // | properties block_content? 448 // ********** * 449 // | block_content 450 // * 451 // 452 // flow_node ::= ALIAS 453 // 454 // ***** 455 // | properties flow_content? 456 // ********** * 457 // | flow_content 458 // * 459 // 460 // properties ::= TAG ANCHOR? | ANCHOR TAG? 461 // 462 // ************************* 463 // 464 // block_content ::= block_collection | flow_collection | SCALAR 465 // 466 // ****** 467 // 468 // flow_content ::= flow_collection | SCALAR 469 // 470 // ****** 471 func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { 472 //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() 473 474 token := peek_token(parser) 475 if token == nil { 476 return false 477 } 478 479 if token.typ == yaml_ALIAS_TOKEN { 480 parser.state = parser.states[len(parser.states)-1] 481 parser.states = parser.states[:len(parser.states)-1] 482 *event = yaml_event_t{ 483 typ: yaml_ALIAS_EVENT, 484 start_mark: token.start_mark, 485 end_mark: token.end_mark, 486 anchor: token.value, 487 } 488 yaml_parser_set_event_comments(parser, event) 489 skip_token(parser) 490 return true 491 } 492 493 start_mark := token.start_mark 494 end_mark := token.start_mark 495 496 var tag_token bool 497 var tag_handle, tag_suffix, anchor []byte 498 var tag_mark yaml_mark_t 499 if token.typ == yaml_ANCHOR_TOKEN { 500 anchor = token.value 501 start_mark = token.start_mark 502 end_mark = token.end_mark 503 skip_token(parser) 504 token = peek_token(parser) 505 if token == nil { 506 return false 507 } 508 if token.typ == yaml_TAG_TOKEN { 509 tag_token = true 510 tag_handle = token.value 511 tag_suffix = token.suffix 512 tag_mark = token.start_mark 513 end_mark = token.end_mark 514 skip_token(parser) 515 token = peek_token(parser) 516 if token == nil { 517 return false 518 } 519 } 520 } else if token.typ == yaml_TAG_TOKEN { 521 tag_token = true 522 tag_handle = token.value 523 tag_suffix = token.suffix 524 start_mark = token.start_mark 525 tag_mark = token.start_mark 526 end_mark = token.end_mark 527 skip_token(parser) 528 token = peek_token(parser) 529 if token == nil { 530 return false 531 } 532 if token.typ == yaml_ANCHOR_TOKEN { 533 anchor = token.value 534 end_mark = token.end_mark 535 skip_token(parser) 536 token = peek_token(parser) 537 if token == nil { 538 return false 539 } 540 } 541 } 542 543 var tag []byte 544 if tag_token { 545 if len(tag_handle) == 0 { 546 tag = tag_suffix 547 tag_suffix = nil 548 } else { 549 for i := range parser.tag_directives { 550 if bytes.Equal(parser.tag_directives[i].handle, tag_handle) { 551 tag = append([]byte(nil), parser.tag_directives[i].prefix...) 552 tag = append(tag, tag_suffix...) 553 break 554 } 555 } 556 if len(tag) == 0 { 557 yaml_parser_set_parser_error_context(parser, 558 "while parsing a node", start_mark, 559 "found undefined tag handle", tag_mark) 560 return false 561 } 562 } 563 } 564 565 implicit := len(tag) == 0 566 if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN { 567 end_mark = token.end_mark 568 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 569 *event = yaml_event_t{ 570 typ: yaml_SEQUENCE_START_EVENT, 571 start_mark: start_mark, 572 end_mark: end_mark, 573 anchor: anchor, 574 tag: tag, 575 implicit: implicit, 576 style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), 577 } 578 return true 579 } 580 if token.typ == yaml_SCALAR_TOKEN { 581 var plain_implicit, quoted_implicit bool 582 end_mark = token.end_mark 583 if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') { 584 plain_implicit = true 585 } else if len(tag) == 0 { 586 quoted_implicit = true 587 } 588 parser.state = parser.states[len(parser.states)-1] 589 parser.states = parser.states[:len(parser.states)-1] 590 591 *event = yaml_event_t{ 592 typ: yaml_SCALAR_EVENT, 593 start_mark: start_mark, 594 end_mark: end_mark, 595 anchor: anchor, 596 tag: tag, 597 value: token.value, 598 implicit: plain_implicit, 599 quoted_implicit: quoted_implicit, 600 style: yaml_style_t(token.style), 601 } 602 yaml_parser_set_event_comments(parser, event) 603 skip_token(parser) 604 return true 605 } 606 if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN { 607 // [Go] Some of the events below can be merged as they differ only on style. 608 end_mark = token.end_mark 609 parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE 610 *event = yaml_event_t{ 611 typ: yaml_SEQUENCE_START_EVENT, 612 start_mark: start_mark, 613 end_mark: end_mark, 614 anchor: anchor, 615 tag: tag, 616 implicit: implicit, 617 style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE), 618 } 619 yaml_parser_set_event_comments(parser, event) 620 return true 621 } 622 if token.typ == yaml_FLOW_MAPPING_START_TOKEN { 623 end_mark = token.end_mark 624 parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE 625 *event = yaml_event_t{ 626 typ: yaml_MAPPING_START_EVENT, 627 start_mark: start_mark, 628 end_mark: end_mark, 629 anchor: anchor, 630 tag: tag, 631 implicit: implicit, 632 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 633 } 634 yaml_parser_set_event_comments(parser, event) 635 return true 636 } 637 if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN { 638 end_mark = token.end_mark 639 parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE 640 *event = yaml_event_t{ 641 typ: yaml_SEQUENCE_START_EVENT, 642 start_mark: start_mark, 643 end_mark: end_mark, 644 anchor: anchor, 645 tag: tag, 646 implicit: implicit, 647 style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE), 648 } 649 if parser.stem_comment != nil { 650 event.head_comment = parser.stem_comment 651 parser.stem_comment = nil 652 } 653 return true 654 } 655 if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN { 656 end_mark = token.end_mark 657 parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE 658 *event = yaml_event_t{ 659 typ: yaml_MAPPING_START_EVENT, 660 start_mark: start_mark, 661 end_mark: end_mark, 662 anchor: anchor, 663 tag: tag, 664 implicit: implicit, 665 style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE), 666 } 667 if parser.stem_comment != nil { 668 event.head_comment = parser.stem_comment 669 parser.stem_comment = nil 670 } 671 return true 672 } 673 if len(anchor) > 0 || len(tag) > 0 { 674 parser.state = parser.states[len(parser.states)-1] 675 parser.states = parser.states[:len(parser.states)-1] 676 677 *event = yaml_event_t{ 678 typ: yaml_SCALAR_EVENT, 679 start_mark: start_mark, 680 end_mark: end_mark, 681 anchor: anchor, 682 tag: tag, 683 implicit: implicit, 684 quoted_implicit: false, 685 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 686 } 687 return true 688 } 689 690 context := "while parsing a flow node" 691 if block { 692 context = "while parsing a block node" 693 } 694 yaml_parser_set_parser_error_context(parser, context, start_mark, 695 "did not find expected node content", token.start_mark) 696 return false 697 } 698 699 // Parse the productions: 700 // block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END 701 // 702 // ******************** *********** * ********* 703 func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 704 if first { 705 token := peek_token(parser) 706 if token == nil { 707 return false 708 } 709 parser.marks = append(parser.marks, token.start_mark) 710 skip_token(parser) 711 } 712 713 token := peek_token(parser) 714 if token == nil { 715 return false 716 } 717 718 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 719 mark := token.end_mark 720 prior_head_len := len(parser.head_comment) 721 skip_token(parser) 722 yaml_parser_split_stem_comment(parser, prior_head_len) 723 token = peek_token(parser) 724 if token == nil { 725 return false 726 } 727 if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN { 728 parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE) 729 return yaml_parser_parse_node(parser, event, true, false) 730 } else { 731 parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE 732 return yaml_parser_process_empty_scalar(parser, event, mark) 733 } 734 } 735 if token.typ == yaml_BLOCK_END_TOKEN { 736 parser.state = parser.states[len(parser.states)-1] 737 parser.states = parser.states[:len(parser.states)-1] 738 parser.marks = parser.marks[:len(parser.marks)-1] 739 740 *event = yaml_event_t{ 741 typ: yaml_SEQUENCE_END_EVENT, 742 start_mark: token.start_mark, 743 end_mark: token.end_mark, 744 } 745 746 skip_token(parser) 747 return true 748 } 749 750 context_mark := parser.marks[len(parser.marks)-1] 751 parser.marks = parser.marks[:len(parser.marks)-1] 752 return yaml_parser_set_parser_error_context(parser, 753 "while parsing a block collection", context_mark, 754 "did not find expected '-' indicator", token.start_mark) 755 } 756 757 // Parse the productions: 758 // indentless_sequence ::= (BLOCK-ENTRY block_node?)+ 759 // 760 // *********** * 761 func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { 762 token := peek_token(parser) 763 if token == nil { 764 return false 765 } 766 767 if token.typ == yaml_BLOCK_ENTRY_TOKEN { 768 mark := token.end_mark 769 prior_head_len := len(parser.head_comment) 770 skip_token(parser) 771 yaml_parser_split_stem_comment(parser, prior_head_len) 772 token = peek_token(parser) 773 if token == nil { 774 return false 775 } 776 if token.typ != yaml_BLOCK_ENTRY_TOKEN && 777 token.typ != yaml_KEY_TOKEN && 778 token.typ != yaml_VALUE_TOKEN && 779 token.typ != yaml_BLOCK_END_TOKEN { 780 parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE) 781 return yaml_parser_parse_node(parser, event, true, false) 782 } 783 parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE 784 return yaml_parser_process_empty_scalar(parser, event, mark) 785 } 786 parser.state = parser.states[len(parser.states)-1] 787 parser.states = parser.states[:len(parser.states)-1] 788 789 *event = yaml_event_t{ 790 typ: yaml_SEQUENCE_END_EVENT, 791 start_mark: token.start_mark, 792 end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark? 793 } 794 return true 795 } 796 797 // Split stem comment from head comment. 798 // 799 // When a sequence or map is found under a sequence entry, the former head comment 800 // is assigned to the underlying sequence or map as a whole, not the individual 801 // sequence or map entry as would be expected otherwise. To handle this case the 802 // previous head comment is moved aside as the stem comment. 803 func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { 804 if stem_len == 0 { 805 return 806 } 807 808 token := peek_token(parser) 809 if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN { 810 return 811 } 812 813 parser.stem_comment = parser.head_comment[:stem_len] 814 if len(parser.head_comment) == stem_len { 815 parser.head_comment = nil 816 } else { 817 // Copy suffix to prevent very strange bugs if someone ever appends 818 // further bytes to the prefix in the stem_comment slice above. 819 parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...) 820 } 821 } 822 823 // Parse the productions: 824 // block_mapping ::= BLOCK-MAPPING_START 825 // 826 // ******************* 827 // ((KEY block_node_or_indentless_sequence?)? 828 // *** * 829 // (VALUE block_node_or_indentless_sequence?)?)* 830 // 831 // BLOCK-END 832 // ********* 833 func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 834 if first { 835 token := peek_token(parser) 836 if token == nil { 837 return false 838 } 839 parser.marks = append(parser.marks, token.start_mark) 840 skip_token(parser) 841 } 842 843 token := peek_token(parser) 844 if token == nil { 845 return false 846 } 847 848 // [Go] A tail comment was left from the prior mapping value processed. Emit an event 849 // as it needs to be processed with that value and not the following key. 850 if len(parser.tail_comment) > 0 { 851 *event = yaml_event_t{ 852 typ: yaml_TAIL_COMMENT_EVENT, 853 start_mark: token.start_mark, 854 end_mark: token.end_mark, 855 foot_comment: parser.tail_comment, 856 } 857 parser.tail_comment = nil 858 return true 859 } 860 861 if token.typ == yaml_KEY_TOKEN { 862 mark := token.end_mark 863 skip_token(parser) 864 token = peek_token(parser) 865 if token == nil { 866 return false 867 } 868 if token.typ != yaml_KEY_TOKEN && 869 token.typ != yaml_VALUE_TOKEN && 870 token.typ != yaml_BLOCK_END_TOKEN { 871 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE) 872 return yaml_parser_parse_node(parser, event, true, true) 873 } else { 874 parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE 875 return yaml_parser_process_empty_scalar(parser, event, mark) 876 } 877 } else if token.typ == yaml_BLOCK_END_TOKEN { 878 parser.state = parser.states[len(parser.states)-1] 879 parser.states = parser.states[:len(parser.states)-1] 880 parser.marks = parser.marks[:len(parser.marks)-1] 881 *event = yaml_event_t{ 882 typ: yaml_MAPPING_END_EVENT, 883 start_mark: token.start_mark, 884 end_mark: token.end_mark, 885 } 886 yaml_parser_set_event_comments(parser, event) 887 skip_token(parser) 888 return true 889 } 890 891 context_mark := parser.marks[len(parser.marks)-1] 892 parser.marks = parser.marks[:len(parser.marks)-1] 893 return yaml_parser_set_parser_error_context(parser, 894 "while parsing a block mapping", context_mark, 895 "did not find expected key", token.start_mark) 896 } 897 898 // Parse the productions: 899 // block_mapping ::= BLOCK-MAPPING_START 900 // 901 // ((KEY block_node_or_indentless_sequence?)? 902 // 903 // (VALUE block_node_or_indentless_sequence?)?)* 904 // ***** * 905 // BLOCK-END 906 func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 907 token := peek_token(parser) 908 if token == nil { 909 return false 910 } 911 if token.typ == yaml_VALUE_TOKEN { 912 mark := token.end_mark 913 skip_token(parser) 914 token = peek_token(parser) 915 if token == nil { 916 return false 917 } 918 if token.typ != yaml_KEY_TOKEN && 919 token.typ != yaml_VALUE_TOKEN && 920 token.typ != yaml_BLOCK_END_TOKEN { 921 parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE) 922 return yaml_parser_parse_node(parser, event, true, true) 923 } 924 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 925 return yaml_parser_process_empty_scalar(parser, event, mark) 926 } 927 parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE 928 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 929 } 930 931 // Parse the productions: 932 // flow_sequence ::= FLOW-SEQUENCE-START 933 // 934 // ******************* 935 // (flow_sequence_entry FLOW-ENTRY)* 936 // * ********** 937 // flow_sequence_entry? 938 // * 939 // FLOW-SEQUENCE-END 940 // ***************** 941 // 942 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 943 // 944 // * 945 func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 946 if first { 947 token := peek_token(parser) 948 if token == nil { 949 return false 950 } 951 parser.marks = append(parser.marks, token.start_mark) 952 skip_token(parser) 953 } 954 token := peek_token(parser) 955 if token == nil { 956 return false 957 } 958 if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 959 if !first { 960 if token.typ == yaml_FLOW_ENTRY_TOKEN { 961 skip_token(parser) 962 token = peek_token(parser) 963 if token == nil { 964 return false 965 } 966 } else { 967 context_mark := parser.marks[len(parser.marks)-1] 968 parser.marks = parser.marks[:len(parser.marks)-1] 969 return yaml_parser_set_parser_error_context(parser, 970 "while parsing a flow sequence", context_mark, 971 "did not find expected ',' or ']'", token.start_mark) 972 } 973 } 974 975 if token.typ == yaml_KEY_TOKEN { 976 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE 977 *event = yaml_event_t{ 978 typ: yaml_MAPPING_START_EVENT, 979 start_mark: token.start_mark, 980 end_mark: token.end_mark, 981 implicit: true, 982 style: yaml_style_t(yaml_FLOW_MAPPING_STYLE), 983 } 984 skip_token(parser) 985 return true 986 } else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 987 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE) 988 return yaml_parser_parse_node(parser, event, false, false) 989 } 990 } 991 992 parser.state = parser.states[len(parser.states)-1] 993 parser.states = parser.states[:len(parser.states)-1] 994 parser.marks = parser.marks[:len(parser.marks)-1] 995 996 *event = yaml_event_t{ 997 typ: yaml_SEQUENCE_END_EVENT, 998 start_mark: token.start_mark, 999 end_mark: token.end_mark, 1000 } 1001 yaml_parser_set_event_comments(parser, event) 1002 1003 skip_token(parser) 1004 return true 1005 } 1006 1007 // Parse the productions: 1008 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1009 // 1010 // *** * 1011 func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { 1012 token := peek_token(parser) 1013 if token == nil { 1014 return false 1015 } 1016 if token.typ != yaml_VALUE_TOKEN && 1017 token.typ != yaml_FLOW_ENTRY_TOKEN && 1018 token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 1019 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE) 1020 return yaml_parser_parse_node(parser, event, false, false) 1021 } 1022 mark := token.end_mark 1023 skip_token(parser) 1024 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE 1025 return yaml_parser_process_empty_scalar(parser, event, mark) 1026 } 1027 1028 // Parse the productions: 1029 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1030 // 1031 // ***** * 1032 func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { 1033 token := peek_token(parser) 1034 if token == nil { 1035 return false 1036 } 1037 if token.typ == yaml_VALUE_TOKEN { 1038 skip_token(parser) 1039 token := peek_token(parser) 1040 if token == nil { 1041 return false 1042 } 1043 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN { 1044 parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE) 1045 return yaml_parser_parse_node(parser, event, false, false) 1046 } 1047 } 1048 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE 1049 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1050 } 1051 1052 // Parse the productions: 1053 // flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1054 // 1055 // * 1056 func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { 1057 token := peek_token(parser) 1058 if token == nil { 1059 return false 1060 } 1061 parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE 1062 *event = yaml_event_t{ 1063 typ: yaml_MAPPING_END_EVENT, 1064 start_mark: token.start_mark, 1065 end_mark: token.start_mark, // [Go] Shouldn't this be end_mark? 1066 } 1067 return true 1068 } 1069 1070 // Parse the productions: 1071 // flow_mapping ::= FLOW-MAPPING-START 1072 // 1073 // ****************** 1074 // (flow_mapping_entry FLOW-ENTRY)* 1075 // * ********** 1076 // flow_mapping_entry? 1077 // ****************** 1078 // FLOW-MAPPING-END 1079 // **************** 1080 // 1081 // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1082 // - *** * 1083 func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { 1084 if first { 1085 token := peek_token(parser) 1086 parser.marks = append(parser.marks, token.start_mark) 1087 skip_token(parser) 1088 } 1089 1090 token := peek_token(parser) 1091 if token == nil { 1092 return false 1093 } 1094 1095 if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1096 if !first { 1097 if token.typ == yaml_FLOW_ENTRY_TOKEN { 1098 skip_token(parser) 1099 token = peek_token(parser) 1100 if token == nil { 1101 return false 1102 } 1103 } else { 1104 context_mark := parser.marks[len(parser.marks)-1] 1105 parser.marks = parser.marks[:len(parser.marks)-1] 1106 return yaml_parser_set_parser_error_context(parser, 1107 "while parsing a flow mapping", context_mark, 1108 "did not find expected ',' or '}'", token.start_mark) 1109 } 1110 } 1111 1112 if token.typ == yaml_KEY_TOKEN { 1113 skip_token(parser) 1114 token = peek_token(parser) 1115 if token == nil { 1116 return false 1117 } 1118 if token.typ != yaml_VALUE_TOKEN && 1119 token.typ != yaml_FLOW_ENTRY_TOKEN && 1120 token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1121 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE) 1122 return yaml_parser_parse_node(parser, event, false, false) 1123 } else { 1124 parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE 1125 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1126 } 1127 } else if token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1128 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE) 1129 return yaml_parser_parse_node(parser, event, false, false) 1130 } 1131 } 1132 1133 parser.state = parser.states[len(parser.states)-1] 1134 parser.states = parser.states[:len(parser.states)-1] 1135 parser.marks = parser.marks[:len(parser.marks)-1] 1136 *event = yaml_event_t{ 1137 typ: yaml_MAPPING_END_EVENT, 1138 start_mark: token.start_mark, 1139 end_mark: token.end_mark, 1140 } 1141 yaml_parser_set_event_comments(parser, event) 1142 skip_token(parser) 1143 return true 1144 } 1145 1146 // Parse the productions: 1147 // flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? 1148 // - ***** * 1149 func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { 1150 token := peek_token(parser) 1151 if token == nil { 1152 return false 1153 } 1154 if empty { 1155 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1156 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1157 } 1158 if token.typ == yaml_VALUE_TOKEN { 1159 skip_token(parser) 1160 token = peek_token(parser) 1161 if token == nil { 1162 return false 1163 } 1164 if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN { 1165 parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE) 1166 return yaml_parser_parse_node(parser, event, false, false) 1167 } 1168 } 1169 parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE 1170 return yaml_parser_process_empty_scalar(parser, event, token.start_mark) 1171 } 1172 1173 // Generate an empty scalar event. 1174 func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool { 1175 *event = yaml_event_t{ 1176 typ: yaml_SCALAR_EVENT, 1177 start_mark: mark, 1178 end_mark: mark, 1179 value: nil, // Empty 1180 implicit: true, 1181 style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE), 1182 } 1183 return true 1184 } 1185 1186 var default_tag_directives = []yaml_tag_directive_t{ 1187 {[]byte("!"), []byte("!")}, 1188 {[]byte("!!"), []byte("tag:yaml.org,2002:")}, 1189 } 1190 1191 // Parse directives. 1192 func yaml_parser_process_directives(parser *yaml_parser_t, 1193 version_directive_ref **yaml_version_directive_t, 1194 tag_directives_ref *[]yaml_tag_directive_t) bool { 1195 1196 var version_directive *yaml_version_directive_t 1197 var tag_directives []yaml_tag_directive_t 1198 1199 token := peek_token(parser) 1200 if token == nil { 1201 return false 1202 } 1203 1204 for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1205 if token.typ == yaml_VERSION_DIRECTIVE_TOKEN { 1206 if version_directive != nil { 1207 yaml_parser_set_parser_error(parser, 1208 "found duplicate %YAML directive", token.start_mark) 1209 return false 1210 } 1211 if token.major != 1 || token.minor != 1 { 1212 yaml_parser_set_parser_error(parser, 1213 "found incompatible YAML document", token.start_mark) 1214 return false 1215 } 1216 version_directive = &yaml_version_directive_t{ 1217 major: token.major, 1218 minor: token.minor, 1219 } 1220 } else if token.typ == yaml_TAG_DIRECTIVE_TOKEN { 1221 value := yaml_tag_directive_t{ 1222 handle: token.value, 1223 prefix: token.prefix, 1224 } 1225 if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) { 1226 return false 1227 } 1228 tag_directives = append(tag_directives, value) 1229 } 1230 1231 skip_token(parser) 1232 token = peek_token(parser) 1233 if token == nil { 1234 return false 1235 } 1236 } 1237 1238 for i := range default_tag_directives { 1239 if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) { 1240 return false 1241 } 1242 } 1243 1244 if version_directive_ref != nil { 1245 *version_directive_ref = version_directive 1246 } 1247 if tag_directives_ref != nil { 1248 *tag_directives_ref = tag_directives 1249 } 1250 return true 1251 } 1252 1253 // Append a tag directive to the directives stack. 1254 func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool { 1255 for i := range parser.tag_directives { 1256 if bytes.Equal(value.handle, parser.tag_directives[i].handle) { 1257 if allow_duplicates { 1258 return true 1259 } 1260 return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark) 1261 } 1262 } 1263 1264 // [Go] I suspect the copy is unnecessary. This was likely done 1265 // because there was no way to track ownership of the data. 1266 value_copy := yaml_tag_directive_t{ 1267 handle: make([]byte, len(value.handle)), 1268 prefix: make([]byte, len(value.prefix)), 1269 } 1270 copy(value_copy.handle, value.handle) 1271 copy(value_copy.prefix, value.prefix) 1272 parser.tag_directives = append(parser.tag_directives, value_copy) 1273 return true 1274 }