OSDN Git Service

new repo
[bytom/vapor.git] / vendor / gopkg.in / yaml.v2 / parserc.go
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 }