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