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