parserc.go

   1package yaml
   2
   3import (
   4	"bytes"
   5)
   6
   7// The parser implements the following grammar:
   8//
   9// stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END
  10// implicit_document    ::= block_node DOCUMENT-END*
  11// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
  12// block_node_or_indentless_sequence    ::=
  13//                          ALIAS
  14//                          | properties (block_content | indentless_block_sequence)?
  15//                          | block_content
  16//                          | indentless_block_sequence
  17// block_node           ::= ALIAS
  18//                          | properties block_content?
  19//                          | block_content
  20// flow_node            ::= ALIAS
  21//                          | properties flow_content?
  22//                          | flow_content
  23// properties           ::= TAG ANCHOR? | ANCHOR TAG?
  24// block_content        ::= block_collection | flow_collection | SCALAR
  25// flow_content         ::= flow_collection | SCALAR
  26// block_collection     ::= block_sequence | block_mapping
  27// flow_collection      ::= flow_sequence | flow_mapping
  28// block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
  29// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
  30// block_mapping        ::= BLOCK-MAPPING_START
  31//                          ((KEY block_node_or_indentless_sequence?)?
  32//                          (VALUE block_node_or_indentless_sequence?)?)*
  33//                          BLOCK-END
  34// flow_sequence        ::= FLOW-SEQUENCE-START
  35//                          (flow_sequence_entry FLOW-ENTRY)*
  36//                          flow_sequence_entry?
  37//                          FLOW-SEQUENCE-END
  38// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  39// flow_mapping         ::= FLOW-MAPPING-START
  40//                          (flow_mapping_entry FLOW-ENTRY)*
  41//                          flow_mapping_entry?
  42//                          FLOW-MAPPING-END
  43// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
  44
  45// Peek the next token in the token queue.
  46func peek_token(parser *yaml_parser_t) *yaml_token_t {
  47	if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
  48		return &parser.tokens[parser.tokens_head]
  49	}
  50	return nil
  51}
  52
  53// Remove the next token from the queue (must be called after peek_token).
  54func skip_token(parser *yaml_parser_t) {
  55	parser.token_available = false
  56	parser.tokens_parsed++
  57	parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
  58	parser.tokens_head++
  59}
  60
  61// Get the next event.
  62func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
  63	// Erase the event object.
  64	*event = yaml_event_t{}
  65
  66	// No events after the end of the stream or error.
  67	if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
  68		return true
  69	}
  70
  71	// Generate the next event.
  72	return yaml_parser_state_machine(parser, event)
  73}
  74
  75// Set parser error.
  76func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
  77	parser.error = yaml_PARSER_ERROR
  78	parser.problem = problem
  79	parser.problem_mark = problem_mark
  80	return false
  81}
  82
  83func 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 {
  84	parser.error = yaml_PARSER_ERROR
  85	parser.context = context
  86	parser.context_mark = context_mark
  87	parser.problem = problem
  88	parser.problem_mark = problem_mark
  89	return false
  90}
  91
  92// State dispatcher.
  93func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
  94	//trace("yaml_parser_state_machine", "state:", parser.state.String())
  95
  96	switch parser.state {
  97	case yaml_PARSE_STREAM_START_STATE:
  98		return yaml_parser_parse_stream_start(parser, event)
  99
 100	case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
 101		return yaml_parser_parse_document_start(parser, event, true)
 102
 103	case yaml_PARSE_DOCUMENT_START_STATE:
 104		return yaml_parser_parse_document_start(parser, event, false)
 105
 106	case yaml_PARSE_DOCUMENT_CONTENT_STATE:
 107		return yaml_parser_parse_document_content(parser, event)
 108
 109	case yaml_PARSE_DOCUMENT_END_STATE:
 110		return yaml_parser_parse_document_end(parser, event)
 111
 112	case yaml_PARSE_BLOCK_NODE_STATE:
 113		return yaml_parser_parse_node(parser, event, true, false)
 114
 115	case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
 116		return yaml_parser_parse_node(parser, event, true, true)
 117
 118	case yaml_PARSE_FLOW_NODE_STATE:
 119		return yaml_parser_parse_node(parser, event, false, false)
 120
 121	case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
 122		return yaml_parser_parse_block_sequence_entry(parser, event, true)
 123
 124	case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
 125		return yaml_parser_parse_block_sequence_entry(parser, event, false)
 126
 127	case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
 128		return yaml_parser_parse_indentless_sequence_entry(parser, event)
 129
 130	case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
 131		return yaml_parser_parse_block_mapping_key(parser, event, true)
 132
 133	case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
 134		return yaml_parser_parse_block_mapping_key(parser, event, false)
 135
 136	case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
 137		return yaml_parser_parse_block_mapping_value(parser, event)
 138
 139	case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
 140		return yaml_parser_parse_flow_sequence_entry(parser, event, true)
 141
 142	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
 143		return yaml_parser_parse_flow_sequence_entry(parser, event, false)
 144
 145	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
 146		return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
 147
 148	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
 149		return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
 150
 151	case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
 152		return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
 153
 154	case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
 155		return yaml_parser_parse_flow_mapping_key(parser, event, true)
 156
 157	case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
 158		return yaml_parser_parse_flow_mapping_key(parser, event, false)
 159
 160	case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
 161		return yaml_parser_parse_flow_mapping_value(parser, event, false)
 162
 163	case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
 164		return yaml_parser_parse_flow_mapping_value(parser, event, true)
 165
 166	default:
 167		panic("invalid parser state")
 168	}
 169}
 170
 171// Parse the production:
 172// stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END
 173//              ************
 174func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
 175	token := peek_token(parser)
 176	if token == nil {
 177		return false
 178	}
 179	if token.typ != yaml_STREAM_START_TOKEN {
 180		return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
 181	}
 182	parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
 183	*event = yaml_event_t{
 184		typ:        yaml_STREAM_START_EVENT,
 185		start_mark: token.start_mark,
 186		end_mark:   token.end_mark,
 187		encoding:   token.encoding,
 188	}
 189	skip_token(parser)
 190	return true
 191}
 192
 193// Parse the productions:
 194// implicit_document    ::= block_node DOCUMENT-END*
 195//                          *
 196// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
 197//                          *************************
 198func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
 199
 200	token := peek_token(parser)
 201	if token == nil {
 202		return false
 203	}
 204
 205	// Parse extra document end indicators.
 206	if !implicit {
 207		for token.typ == yaml_DOCUMENT_END_TOKEN {
 208			skip_token(parser)
 209			token = peek_token(parser)
 210			if token == nil {
 211				return false
 212			}
 213		}
 214	}
 215
 216	if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
 217		token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
 218		token.typ != yaml_DOCUMENT_START_TOKEN &&
 219		token.typ != yaml_STREAM_END_TOKEN {
 220		// Parse an implicit document.
 221		if !yaml_parser_process_directives(parser, nil, nil) {
 222			return false
 223		}
 224		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
 225		parser.state = yaml_PARSE_BLOCK_NODE_STATE
 226
 227		*event = yaml_event_t{
 228			typ:        yaml_DOCUMENT_START_EVENT,
 229			start_mark: token.start_mark,
 230			end_mark:   token.end_mark,
 231		}
 232
 233	} else if token.typ != yaml_STREAM_END_TOKEN {
 234		// Parse an explicit document.
 235		var version_directive *yaml_version_directive_t
 236		var tag_directives []yaml_tag_directive_t
 237		start_mark := token.start_mark
 238		if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
 239			return false
 240		}
 241		token = peek_token(parser)
 242		if token == nil {
 243			return false
 244		}
 245		if token.typ != yaml_DOCUMENT_START_TOKEN {
 246			yaml_parser_set_parser_error(parser,
 247				"did not find expected <document start>", token.start_mark)
 248			return false
 249		}
 250		parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
 251		parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
 252		end_mark := token.end_mark
 253
 254		*event = yaml_event_t{
 255			typ:               yaml_DOCUMENT_START_EVENT,
 256			start_mark:        start_mark,
 257			end_mark:          end_mark,
 258			version_directive: version_directive,
 259			tag_directives:    tag_directives,
 260			implicit:          false,
 261		}
 262		skip_token(parser)
 263
 264	} else {
 265		// Parse the stream end.
 266		parser.state = yaml_PARSE_END_STATE
 267		*event = yaml_event_t{
 268			typ:        yaml_STREAM_END_EVENT,
 269			start_mark: token.start_mark,
 270			end_mark:   token.end_mark,
 271		}
 272		skip_token(parser)
 273	}
 274
 275	return true
 276}
 277
 278// Parse the productions:
 279// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
 280//                                                    ***********
 281//
 282func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
 283	token := peek_token(parser)
 284	if token == nil {
 285		return false
 286	}
 287	if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
 288		token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
 289		token.typ == yaml_DOCUMENT_START_TOKEN ||
 290		token.typ == yaml_DOCUMENT_END_TOKEN ||
 291		token.typ == yaml_STREAM_END_TOKEN {
 292		parser.state = parser.states[len(parser.states)-1]
 293		parser.states = parser.states[:len(parser.states)-1]
 294		return yaml_parser_process_empty_scalar(parser, event,
 295			token.start_mark)
 296	}
 297	return yaml_parser_parse_node(parser, event, true, false)
 298}
 299
 300// Parse the productions:
 301// implicit_document    ::= block_node DOCUMENT-END*
 302//                                     *************
 303// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
 304//
 305func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
 306	token := peek_token(parser)
 307	if token == nil {
 308		return false
 309	}
 310
 311	start_mark := token.start_mark
 312	end_mark := token.start_mark
 313
 314	implicit := true
 315	if token.typ == yaml_DOCUMENT_END_TOKEN {
 316		end_mark = token.end_mark
 317		skip_token(parser)
 318		implicit = false
 319	}
 320
 321	parser.tag_directives = parser.tag_directives[:0]
 322
 323	parser.state = yaml_PARSE_DOCUMENT_START_STATE
 324	*event = yaml_event_t{
 325		typ:        yaml_DOCUMENT_END_EVENT,
 326		start_mark: start_mark,
 327		end_mark:   end_mark,
 328		implicit:   implicit,
 329	}
 330	return true
 331}
 332
 333// Parse the productions:
 334// block_node_or_indentless_sequence    ::=
 335//                          ALIAS
 336//                          *****
 337//                          | properties (block_content | indentless_block_sequence)?
 338//                            **********  *
 339//                          | block_content | indentless_block_sequence
 340//                            *
 341// block_node           ::= ALIAS
 342//                          *****
 343//                          | properties block_content?
 344//                            ********** *
 345//                          | block_content
 346//                            *
 347// flow_node            ::= ALIAS
 348//                          *****
 349//                          | properties flow_content?
 350//                            ********** *
 351//                          | flow_content
 352//                            *
 353// properties           ::= TAG ANCHOR? | ANCHOR TAG?
 354//                          *************************
 355// block_content        ::= block_collection | flow_collection | SCALAR
 356//                                                               ******
 357// flow_content         ::= flow_collection | SCALAR
 358//                                            ******
 359func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
 360	//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
 361
 362	token := peek_token(parser)
 363	if token == nil {
 364		return false
 365	}
 366
 367	if token.typ == yaml_ALIAS_TOKEN {
 368		parser.state = parser.states[len(parser.states)-1]
 369		parser.states = parser.states[:len(parser.states)-1]
 370		*event = yaml_event_t{
 371			typ:        yaml_ALIAS_EVENT,
 372			start_mark: token.start_mark,
 373			end_mark:   token.end_mark,
 374			anchor:     token.value,
 375		}
 376		skip_token(parser)
 377		return true
 378	}
 379
 380	start_mark := token.start_mark
 381	end_mark := token.start_mark
 382
 383	var tag_token bool
 384	var tag_handle, tag_suffix, anchor []byte
 385	var tag_mark yaml_mark_t
 386	if token.typ == yaml_ANCHOR_TOKEN {
 387		anchor = token.value
 388		start_mark = token.start_mark
 389		end_mark = token.end_mark
 390		skip_token(parser)
 391		token = peek_token(parser)
 392		if token == nil {
 393			return false
 394		}
 395		if token.typ == yaml_TAG_TOKEN {
 396			tag_token = true
 397			tag_handle = token.value
 398			tag_suffix = token.suffix
 399			tag_mark = token.start_mark
 400			end_mark = token.end_mark
 401			skip_token(parser)
 402			token = peek_token(parser)
 403			if token == nil {
 404				return false
 405			}
 406		}
 407	} else if token.typ == yaml_TAG_TOKEN {
 408		tag_token = true
 409		tag_handle = token.value
 410		tag_suffix = token.suffix
 411		start_mark = token.start_mark
 412		tag_mark = token.start_mark
 413		end_mark = token.end_mark
 414		skip_token(parser)
 415		token = peek_token(parser)
 416		if token == nil {
 417			return false
 418		}
 419		if token.typ == yaml_ANCHOR_TOKEN {
 420			anchor = token.value
 421			end_mark = token.end_mark
 422			skip_token(parser)
 423			token = peek_token(parser)
 424			if token == nil {
 425				return false
 426			}
 427		}
 428	}
 429
 430	var tag []byte
 431	if tag_token {
 432		if len(tag_handle) == 0 {
 433			tag = tag_suffix
 434			tag_suffix = nil
 435		} else {
 436			for i := range parser.tag_directives {
 437				if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
 438					tag = append([]byte(nil), parser.tag_directives[i].prefix...)
 439					tag = append(tag, tag_suffix...)
 440					break
 441				}
 442			}
 443			if len(tag) == 0 {
 444				yaml_parser_set_parser_error_context(parser,
 445					"while parsing a node", start_mark,
 446					"found undefined tag handle", tag_mark)
 447				return false
 448			}
 449		}
 450	}
 451
 452	implicit := len(tag) == 0
 453	if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
 454		end_mark = token.end_mark
 455		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
 456		*event = yaml_event_t{
 457			typ:        yaml_SEQUENCE_START_EVENT,
 458			start_mark: start_mark,
 459			end_mark:   end_mark,
 460			anchor:     anchor,
 461			tag:        tag,
 462			implicit:   implicit,
 463			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
 464		}
 465		return true
 466	}
 467	if token.typ == yaml_SCALAR_TOKEN {
 468		var plain_implicit, quoted_implicit bool
 469		end_mark = token.end_mark
 470		if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
 471			plain_implicit = true
 472		} else if len(tag) == 0 {
 473			quoted_implicit = true
 474		}
 475		parser.state = parser.states[len(parser.states)-1]
 476		parser.states = parser.states[:len(parser.states)-1]
 477
 478		*event = yaml_event_t{
 479			typ:             yaml_SCALAR_EVENT,
 480			start_mark:      start_mark,
 481			end_mark:        end_mark,
 482			anchor:          anchor,
 483			tag:             tag,
 484			value:           token.value,
 485			implicit:        plain_implicit,
 486			quoted_implicit: quoted_implicit,
 487			style:           yaml_style_t(token.style),
 488		}
 489		skip_token(parser)
 490		return true
 491	}
 492	if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
 493		// [Go] Some of the events below can be merged as they differ only on style.
 494		end_mark = token.end_mark
 495		parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
 496		*event = yaml_event_t{
 497			typ:        yaml_SEQUENCE_START_EVENT,
 498			start_mark: start_mark,
 499			end_mark:   end_mark,
 500			anchor:     anchor,
 501			tag:        tag,
 502			implicit:   implicit,
 503			style:      yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
 504		}
 505		return true
 506	}
 507	if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
 508		end_mark = token.end_mark
 509		parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
 510		*event = yaml_event_t{
 511			typ:        yaml_MAPPING_START_EVENT,
 512			start_mark: start_mark,
 513			end_mark:   end_mark,
 514			anchor:     anchor,
 515			tag:        tag,
 516			implicit:   implicit,
 517			style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
 518		}
 519		return true
 520	}
 521	if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
 522		end_mark = token.end_mark
 523		parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
 524		*event = yaml_event_t{
 525			typ:        yaml_SEQUENCE_START_EVENT,
 526			start_mark: start_mark,
 527			end_mark:   end_mark,
 528			anchor:     anchor,
 529			tag:        tag,
 530			implicit:   implicit,
 531			style:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
 532		}
 533		return true
 534	}
 535	if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
 536		end_mark = token.end_mark
 537		parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
 538		*event = yaml_event_t{
 539			typ:        yaml_MAPPING_START_EVENT,
 540			start_mark: start_mark,
 541			end_mark:   end_mark,
 542			anchor:     anchor,
 543			tag:        tag,
 544			implicit:   implicit,
 545			style:      yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
 546		}
 547		return true
 548	}
 549	if len(anchor) > 0 || len(tag) > 0 {
 550		parser.state = parser.states[len(parser.states)-1]
 551		parser.states = parser.states[:len(parser.states)-1]
 552
 553		*event = yaml_event_t{
 554			typ:             yaml_SCALAR_EVENT,
 555			start_mark:      start_mark,
 556			end_mark:        end_mark,
 557			anchor:          anchor,
 558			tag:             tag,
 559			implicit:        implicit,
 560			quoted_implicit: false,
 561			style:           yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
 562		}
 563		return true
 564	}
 565
 566	context := "while parsing a flow node"
 567	if block {
 568		context = "while parsing a block node"
 569	}
 570	yaml_parser_set_parser_error_context(parser, context, start_mark,
 571		"did not find expected node content", token.start_mark)
 572	return false
 573}
 574
 575// Parse the productions:
 576// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
 577//                    ********************  *********** *             *********
 578//
 579func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
 580	if first {
 581		token := peek_token(parser)
 582		parser.marks = append(parser.marks, token.start_mark)
 583		skip_token(parser)
 584	}
 585
 586	token := peek_token(parser)
 587	if token == nil {
 588		return false
 589	}
 590
 591	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
 592		mark := token.end_mark
 593		skip_token(parser)
 594		token = peek_token(parser)
 595		if token == nil {
 596			return false
 597		}
 598		if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
 599			parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
 600			return yaml_parser_parse_node(parser, event, true, false)
 601		} else {
 602			parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
 603			return yaml_parser_process_empty_scalar(parser, event, mark)
 604		}
 605	}
 606	if token.typ == yaml_BLOCK_END_TOKEN {
 607		parser.state = parser.states[len(parser.states)-1]
 608		parser.states = parser.states[:len(parser.states)-1]
 609		parser.marks = parser.marks[:len(parser.marks)-1]
 610
 611		*event = yaml_event_t{
 612			typ:        yaml_SEQUENCE_END_EVENT,
 613			start_mark: token.start_mark,
 614			end_mark:   token.end_mark,
 615		}
 616
 617		skip_token(parser)
 618		return true
 619	}
 620
 621	context_mark := parser.marks[len(parser.marks)-1]
 622	parser.marks = parser.marks[:len(parser.marks)-1]
 623	return yaml_parser_set_parser_error_context(parser,
 624		"while parsing a block collection", context_mark,
 625		"did not find expected '-' indicator", token.start_mark)
 626}
 627
 628// Parse the productions:
 629// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+
 630//                           *********** *
 631func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
 632	token := peek_token(parser)
 633	if token == nil {
 634		return false
 635	}
 636
 637	if token.typ == yaml_BLOCK_ENTRY_TOKEN {
 638		mark := token.end_mark
 639		skip_token(parser)
 640		token = peek_token(parser)
 641		if token == nil {
 642			return false
 643		}
 644		if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
 645			token.typ != yaml_KEY_TOKEN &&
 646			token.typ != yaml_VALUE_TOKEN &&
 647			token.typ != yaml_BLOCK_END_TOKEN {
 648			parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
 649			return yaml_parser_parse_node(parser, event, true, false)
 650		}
 651		parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
 652		return yaml_parser_process_empty_scalar(parser, event, mark)
 653	}
 654	parser.state = parser.states[len(parser.states)-1]
 655	parser.states = parser.states[:len(parser.states)-1]
 656
 657	*event = yaml_event_t{
 658		typ:        yaml_SEQUENCE_END_EVENT,
 659		start_mark: token.start_mark,
 660		end_mark:   token.start_mark, // [Go] Shouldn't this be token.end_mark?
 661	}
 662	return true
 663}
 664
 665// Parse the productions:
 666// block_mapping        ::= BLOCK-MAPPING_START
 667//                          *******************
 668//                          ((KEY block_node_or_indentless_sequence?)?
 669//                            *** *
 670//                          (VALUE block_node_or_indentless_sequence?)?)*
 671//
 672//                          BLOCK-END
 673//                          *********
 674//
 675func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
 676	if first {
 677		token := peek_token(parser)
 678		parser.marks = append(parser.marks, token.start_mark)
 679		skip_token(parser)
 680	}
 681
 682	token := peek_token(parser)
 683	if token == nil {
 684		return false
 685	}
 686
 687	if token.typ == yaml_KEY_TOKEN {
 688		mark := token.end_mark
 689		skip_token(parser)
 690		token = peek_token(parser)
 691		if token == nil {
 692			return false
 693		}
 694		if token.typ != yaml_KEY_TOKEN &&
 695			token.typ != yaml_VALUE_TOKEN &&
 696			token.typ != yaml_BLOCK_END_TOKEN {
 697			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
 698			return yaml_parser_parse_node(parser, event, true, true)
 699		} else {
 700			parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
 701			return yaml_parser_process_empty_scalar(parser, event, mark)
 702		}
 703	} else if token.typ == yaml_BLOCK_END_TOKEN {
 704		parser.state = parser.states[len(parser.states)-1]
 705		parser.states = parser.states[:len(parser.states)-1]
 706		parser.marks = parser.marks[:len(parser.marks)-1]
 707		*event = yaml_event_t{
 708			typ:        yaml_MAPPING_END_EVENT,
 709			start_mark: token.start_mark,
 710			end_mark:   token.end_mark,
 711		}
 712		skip_token(parser)
 713		return true
 714	}
 715
 716	context_mark := parser.marks[len(parser.marks)-1]
 717	parser.marks = parser.marks[:len(parser.marks)-1]
 718	return yaml_parser_set_parser_error_context(parser,
 719		"while parsing a block mapping", context_mark,
 720		"did not find expected key", token.start_mark)
 721}
 722
 723// Parse the productions:
 724// block_mapping        ::= BLOCK-MAPPING_START
 725//
 726//                          ((KEY block_node_or_indentless_sequence?)?
 727//
 728//                          (VALUE block_node_or_indentless_sequence?)?)*
 729//                           ***** *
 730//                          BLOCK-END
 731//
 732//
 733func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
 734	token := peek_token(parser)
 735	if token == nil {
 736		return false
 737	}
 738	if token.typ == yaml_VALUE_TOKEN {
 739		mark := token.end_mark
 740		skip_token(parser)
 741		token = peek_token(parser)
 742		if token == nil {
 743			return false
 744		}
 745		if token.typ != yaml_KEY_TOKEN &&
 746			token.typ != yaml_VALUE_TOKEN &&
 747			token.typ != yaml_BLOCK_END_TOKEN {
 748			parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
 749			return yaml_parser_parse_node(parser, event, true, true)
 750		}
 751		parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
 752		return yaml_parser_process_empty_scalar(parser, event, mark)
 753	}
 754	parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
 755	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
 756}
 757
 758// Parse the productions:
 759// flow_sequence        ::= FLOW-SEQUENCE-START
 760//                          *******************
 761//                          (flow_sequence_entry FLOW-ENTRY)*
 762//                           *                   **********
 763//                          flow_sequence_entry?
 764//                          *
 765//                          FLOW-SEQUENCE-END
 766//                          *****************
 767// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
 768//                          *
 769//
 770func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
 771	if first {
 772		token := peek_token(parser)
 773		parser.marks = append(parser.marks, token.start_mark)
 774		skip_token(parser)
 775	}
 776	token := peek_token(parser)
 777	if token == nil {
 778		return false
 779	}
 780	if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
 781		if !first {
 782			if token.typ == yaml_FLOW_ENTRY_TOKEN {
 783				skip_token(parser)
 784				token = peek_token(parser)
 785				if token == nil {
 786					return false
 787				}
 788			} else {
 789				context_mark := parser.marks[len(parser.marks)-1]
 790				parser.marks = parser.marks[:len(parser.marks)-1]
 791				return yaml_parser_set_parser_error_context(parser,
 792					"while parsing a flow sequence", context_mark,
 793					"did not find expected ',' or ']'", token.start_mark)
 794			}
 795		}
 796
 797		if token.typ == yaml_KEY_TOKEN {
 798			parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
 799			*event = yaml_event_t{
 800				typ:        yaml_MAPPING_START_EVENT,
 801				start_mark: token.start_mark,
 802				end_mark:   token.end_mark,
 803				implicit:   true,
 804				style:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),
 805			}
 806			skip_token(parser)
 807			return true
 808		} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
 809			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
 810			return yaml_parser_parse_node(parser, event, false, false)
 811		}
 812	}
 813
 814	parser.state = parser.states[len(parser.states)-1]
 815	parser.states = parser.states[:len(parser.states)-1]
 816	parser.marks = parser.marks[:len(parser.marks)-1]
 817
 818	*event = yaml_event_t{
 819		typ:        yaml_SEQUENCE_END_EVENT,
 820		start_mark: token.start_mark,
 821		end_mark:   token.end_mark,
 822	}
 823
 824	skip_token(parser)
 825	return true
 826}
 827
 828//
 829// Parse the productions:
 830// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
 831//                                      *** *
 832//
 833func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
 834	token := peek_token(parser)
 835	if token == nil {
 836		return false
 837	}
 838	if token.typ != yaml_VALUE_TOKEN &&
 839		token.typ != yaml_FLOW_ENTRY_TOKEN &&
 840		token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
 841		parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
 842		return yaml_parser_parse_node(parser, event, false, false)
 843	}
 844	mark := token.end_mark
 845	skip_token(parser)
 846	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
 847	return yaml_parser_process_empty_scalar(parser, event, mark)
 848}
 849
 850// Parse the productions:
 851// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
 852//                                                      ***** *
 853//
 854func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
 855	token := peek_token(parser)
 856	if token == nil {
 857		return false
 858	}
 859	if token.typ == yaml_VALUE_TOKEN {
 860		skip_token(parser)
 861		token := peek_token(parser)
 862		if token == nil {
 863			return false
 864		}
 865		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
 866			parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
 867			return yaml_parser_parse_node(parser, event, false, false)
 868		}
 869	}
 870	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
 871	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
 872}
 873
 874// Parse the productions:
 875// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?
 876//                                                                      *
 877//
 878func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
 879	token := peek_token(parser)
 880	if token == nil {
 881		return false
 882	}
 883	parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
 884	*event = yaml_event_t{
 885		typ:        yaml_MAPPING_END_EVENT,
 886		start_mark: token.start_mark,
 887		end_mark:   token.start_mark, // [Go] Shouldn't this be end_mark?
 888	}
 889	return true
 890}
 891
 892// Parse the productions:
 893// flow_mapping         ::= FLOW-MAPPING-START
 894//                          ******************
 895//                          (flow_mapping_entry FLOW-ENTRY)*
 896//                           *                  **********
 897//                          flow_mapping_entry?
 898//                          ******************
 899//                          FLOW-MAPPING-END
 900//                          ****************
 901// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
 902//                          *           *** *
 903//
 904func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
 905	if first {
 906		token := peek_token(parser)
 907		parser.marks = append(parser.marks, token.start_mark)
 908		skip_token(parser)
 909	}
 910
 911	token := peek_token(parser)
 912	if token == nil {
 913		return false
 914	}
 915
 916	if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
 917		if !first {
 918			if token.typ == yaml_FLOW_ENTRY_TOKEN {
 919				skip_token(parser)
 920				token = peek_token(parser)
 921				if token == nil {
 922					return false
 923				}
 924			} else {
 925				context_mark := parser.marks[len(parser.marks)-1]
 926				parser.marks = parser.marks[:len(parser.marks)-1]
 927				return yaml_parser_set_parser_error_context(parser,
 928					"while parsing a flow mapping", context_mark,
 929					"did not find expected ',' or '}'", token.start_mark)
 930			}
 931		}
 932
 933		if token.typ == yaml_KEY_TOKEN {
 934			skip_token(parser)
 935			token = peek_token(parser)
 936			if token == nil {
 937				return false
 938			}
 939			if token.typ != yaml_VALUE_TOKEN &&
 940				token.typ != yaml_FLOW_ENTRY_TOKEN &&
 941				token.typ != yaml_FLOW_MAPPING_END_TOKEN {
 942				parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
 943				return yaml_parser_parse_node(parser, event, false, false)
 944			} else {
 945				parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
 946				return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
 947			}
 948		} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
 949			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
 950			return yaml_parser_parse_node(parser, event, false, false)
 951		}
 952	}
 953
 954	parser.state = parser.states[len(parser.states)-1]
 955	parser.states = parser.states[:len(parser.states)-1]
 956	parser.marks = parser.marks[:len(parser.marks)-1]
 957	*event = yaml_event_t{
 958		typ:        yaml_MAPPING_END_EVENT,
 959		start_mark: token.start_mark,
 960		end_mark:   token.end_mark,
 961	}
 962	skip_token(parser)
 963	return true
 964}
 965
 966// Parse the productions:
 967// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
 968//                                   *                  ***** *
 969//
 970func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
 971	token := peek_token(parser)
 972	if token == nil {
 973		return false
 974	}
 975	if empty {
 976		parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
 977		return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
 978	}
 979	if token.typ == yaml_VALUE_TOKEN {
 980		skip_token(parser)
 981		token = peek_token(parser)
 982		if token == nil {
 983			return false
 984		}
 985		if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
 986			parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
 987			return yaml_parser_parse_node(parser, event, false, false)
 988		}
 989	}
 990	parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
 991	return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
 992}
 993
 994// Generate an empty scalar event.
 995func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
 996	*event = yaml_event_t{
 997		typ:        yaml_SCALAR_EVENT,
 998		start_mark: mark,
 999		end_mark:   mark,
1000		value:      nil, // Empty
1001		implicit:   true,
1002		style:      yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
1003	}
1004	return true
1005}
1006
1007var default_tag_directives = []yaml_tag_directive_t{
1008	{[]byte("!"), []byte("!")},
1009	{[]byte("!!"), []byte("tag:yaml.org,2002:")},
1010}
1011
1012// Parse directives.
1013func yaml_parser_process_directives(parser *yaml_parser_t,
1014	version_directive_ref **yaml_version_directive_t,
1015	tag_directives_ref *[]yaml_tag_directive_t) bool {
1016
1017	var version_directive *yaml_version_directive_t
1018	var tag_directives []yaml_tag_directive_t
1019
1020	token := peek_token(parser)
1021	if token == nil {
1022		return false
1023	}
1024
1025	for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1026		if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
1027			if version_directive != nil {
1028				yaml_parser_set_parser_error(parser,
1029					"found duplicate %YAML directive", token.start_mark)
1030				return false
1031			}
1032			if token.major != 1 || token.minor != 1 {
1033				yaml_parser_set_parser_error(parser,
1034					"found incompatible YAML document", token.start_mark)
1035				return false
1036			}
1037			version_directive = &yaml_version_directive_t{
1038				major: token.major,
1039				minor: token.minor,
1040			}
1041		} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1042			value := yaml_tag_directive_t{
1043				handle: token.value,
1044				prefix: token.prefix,
1045			}
1046			if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
1047				return false
1048			}
1049			tag_directives = append(tag_directives, value)
1050		}
1051
1052		skip_token(parser)
1053		token = peek_token(parser)
1054		if token == nil {
1055			return false
1056		}
1057	}
1058
1059	for i := range default_tag_directives {
1060		if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
1061			return false
1062		}
1063	}
1064
1065	if version_directive_ref != nil {
1066		*version_directive_ref = version_directive
1067	}
1068	if tag_directives_ref != nil {
1069		*tag_directives_ref = tag_directives
1070	}
1071	return true
1072}
1073
1074// Append a tag directive to the directives stack.
1075func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
1076	for i := range parser.tag_directives {
1077		if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
1078			if allow_duplicates {
1079				return true
1080			}
1081			return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
1082		}
1083	}
1084
1085	// [Go] I suspect the copy is unnecessary. This was likely done
1086	// because there was no way to track ownership of the data.
1087	value_copy := yaml_tag_directive_t{
1088		handle: make([]byte, len(value.handle)),
1089		prefix: make([]byte, len(value.prefix)),
1090	}
1091	copy(value_copy.handle, value.handle)
1092	copy(value_copy.prefix, value.prefix)
1093	parser.tag_directives = append(parser.tag_directives, value_copy)
1094	return true
1095}