parserc.go raw

   1  package yaml
   2  
   3  import (
   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.
  46  func 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).
  54  func 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.
  62  func 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.
  76  func 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  
  83  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 {
  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.
  93  func 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  //              ************
 174  func 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  //                          *************************
 198  func 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  //
 282  func 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  //
 305  func 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  //                                            ******
 359  func 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  //
 579  func 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  //                           *********** *
 631  func 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  //
 675  func 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  //
 733  func 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  //
 770  func 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  //
 833  func 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  //
 854  func 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  //
 878  func 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  //
 904  func 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  //
 970  func 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.
 995  func 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  
1007  var default_tag_directives = []yaml_tag_directive_t{
1008  	{[]byte("!"), []byte("!")},
1009  	{[]byte("!!"), []byte("tag:yaml.org,2002:")},
1010  }
1011  
1012  // Parse directives.
1013  func 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.
1075  func 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  }
1096