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