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