Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/go.yaml.in/yaml/v3/parserc.go
2872 views
1
//
2
// Copyright (c) 2011-2019 Canonical Ltd
3
// Copyright (c) 2006-2010 Kirill Simonov
4
//
5
// Permission is hereby granted, free of charge, to any person obtaining a copy of
6
// this software and associated documentation files (the "Software"), to deal in
7
// the Software without restriction, including without limitation the rights to
8
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
// of the Software, and to permit persons to whom the Software is furnished to do
10
// so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included in all
13
// copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
// SOFTWARE.
22
23
package yaml
24
25
import (
26
"bytes"
27
)
28
29
// The parser implements the following grammar:
30
//
31
// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
32
// implicit_document ::= block_node DOCUMENT-END*
33
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
34
// block_node_or_indentless_sequence ::=
35
// ALIAS
36
// | properties (block_content | indentless_block_sequence)?
37
// | block_content
38
// | indentless_block_sequence
39
// block_node ::= ALIAS
40
// | properties block_content?
41
// | block_content
42
// flow_node ::= ALIAS
43
// | properties flow_content?
44
// | flow_content
45
// properties ::= TAG ANCHOR? | ANCHOR TAG?
46
// block_content ::= block_collection | flow_collection | SCALAR
47
// flow_content ::= flow_collection | SCALAR
48
// block_collection ::= block_sequence | block_mapping
49
// flow_collection ::= flow_sequence | flow_mapping
50
// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
51
// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
52
// block_mapping ::= BLOCK-MAPPING_START
53
// ((KEY block_node_or_indentless_sequence?)?
54
// (VALUE block_node_or_indentless_sequence?)?)*
55
// BLOCK-END
56
// flow_sequence ::= FLOW-SEQUENCE-START
57
// (flow_sequence_entry FLOW-ENTRY)*
58
// flow_sequence_entry?
59
// FLOW-SEQUENCE-END
60
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
61
// flow_mapping ::= FLOW-MAPPING-START
62
// (flow_mapping_entry FLOW-ENTRY)*
63
// flow_mapping_entry?
64
// FLOW-MAPPING-END
65
// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
66
67
// Peek the next token in the token queue.
68
func peek_token(parser *yaml_parser_t) *yaml_token_t {
69
if parser.token_available || yaml_parser_fetch_more_tokens(parser) {
70
token := &parser.tokens[parser.tokens_head]
71
yaml_parser_unfold_comments(parser, token)
72
return token
73
}
74
return nil
75
}
76
77
// yaml_parser_unfold_comments walks through the comments queue and joins all
78
// comments behind the position of the provided token into the respective
79
// top-level comment slices in the parser.
80
func yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) {
81
for parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index {
82
comment := &parser.comments[parser.comments_head]
83
if len(comment.head) > 0 {
84
if token.typ == yaml_BLOCK_END_TOKEN {
85
// No heads on ends, so keep comment.head for a follow up token.
86
break
87
}
88
if len(parser.head_comment) > 0 {
89
parser.head_comment = append(parser.head_comment, '\n')
90
}
91
parser.head_comment = append(parser.head_comment, comment.head...)
92
}
93
if len(comment.foot) > 0 {
94
if len(parser.foot_comment) > 0 {
95
parser.foot_comment = append(parser.foot_comment, '\n')
96
}
97
parser.foot_comment = append(parser.foot_comment, comment.foot...)
98
}
99
if len(comment.line) > 0 {
100
if len(parser.line_comment) > 0 {
101
parser.line_comment = append(parser.line_comment, '\n')
102
}
103
parser.line_comment = append(parser.line_comment, comment.line...)
104
}
105
*comment = yaml_comment_t{}
106
parser.comments_head++
107
}
108
}
109
110
// Remove the next token from the queue (must be called after peek_token).
111
func skip_token(parser *yaml_parser_t) {
112
parser.token_available = false
113
parser.tokens_parsed++
114
parser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN
115
parser.tokens_head++
116
}
117
118
// Get the next event.
119
func yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {
120
// Erase the event object.
121
*event = yaml_event_t{}
122
123
// No events after the end of the stream or error.
124
if parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {
125
return true
126
}
127
128
// Generate the next event.
129
return yaml_parser_state_machine(parser, event)
130
}
131
132
// Set parser error.
133
func yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {
134
parser.error = yaml_PARSER_ERROR
135
parser.problem = problem
136
parser.problem_mark = problem_mark
137
return false
138
}
139
140
func yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {
141
parser.error = yaml_PARSER_ERROR
142
parser.context = context
143
parser.context_mark = context_mark
144
parser.problem = problem
145
parser.problem_mark = problem_mark
146
return false
147
}
148
149
// State dispatcher.
150
func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {
151
//trace("yaml_parser_state_machine", "state:", parser.state.String())
152
153
switch parser.state {
154
case yaml_PARSE_STREAM_START_STATE:
155
return yaml_parser_parse_stream_start(parser, event)
156
157
case yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:
158
return yaml_parser_parse_document_start(parser, event, true)
159
160
case yaml_PARSE_DOCUMENT_START_STATE:
161
return yaml_parser_parse_document_start(parser, event, false)
162
163
case yaml_PARSE_DOCUMENT_CONTENT_STATE:
164
return yaml_parser_parse_document_content(parser, event)
165
166
case yaml_PARSE_DOCUMENT_END_STATE:
167
return yaml_parser_parse_document_end(parser, event)
168
169
case yaml_PARSE_BLOCK_NODE_STATE:
170
return yaml_parser_parse_node(parser, event, true, false)
171
172
case yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
173
return yaml_parser_parse_node(parser, event, true, true)
174
175
case yaml_PARSE_FLOW_NODE_STATE:
176
return yaml_parser_parse_node(parser, event, false, false)
177
178
case yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
179
return yaml_parser_parse_block_sequence_entry(parser, event, true)
180
181
case yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
182
return yaml_parser_parse_block_sequence_entry(parser, event, false)
183
184
case yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
185
return yaml_parser_parse_indentless_sequence_entry(parser, event)
186
187
case yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
188
return yaml_parser_parse_block_mapping_key(parser, event, true)
189
190
case yaml_PARSE_BLOCK_MAPPING_KEY_STATE:
191
return yaml_parser_parse_block_mapping_key(parser, event, false)
192
193
case yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:
194
return yaml_parser_parse_block_mapping_value(parser, event)
195
196
case yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
197
return yaml_parser_parse_flow_sequence_entry(parser, event, true)
198
199
case yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
200
return yaml_parser_parse_flow_sequence_entry(parser, event, false)
201
202
case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
203
return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
204
205
case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
206
return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
207
208
case yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
209
return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
210
211
case yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
212
return yaml_parser_parse_flow_mapping_key(parser, event, true)
213
214
case yaml_PARSE_FLOW_MAPPING_KEY_STATE:
215
return yaml_parser_parse_flow_mapping_key(parser, event, false)
216
217
case yaml_PARSE_FLOW_MAPPING_VALUE_STATE:
218
return yaml_parser_parse_flow_mapping_value(parser, event, false)
219
220
case yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
221
return yaml_parser_parse_flow_mapping_value(parser, event, true)
222
223
default:
224
panic("invalid parser state")
225
}
226
}
227
228
// Parse the production:
229
// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
230
//
231
// ************
232
func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
233
token := peek_token(parser)
234
if token == nil {
235
return false
236
}
237
if token.typ != yaml_STREAM_START_TOKEN {
238
return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
239
}
240
parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
241
*event = yaml_event_t{
242
typ: yaml_STREAM_START_EVENT,
243
start_mark: token.start_mark,
244
end_mark: token.end_mark,
245
encoding: token.encoding,
246
}
247
skip_token(parser)
248
return true
249
}
250
251
// Parse the productions:
252
// implicit_document ::= block_node DOCUMENT-END*
253
//
254
// *
255
//
256
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
257
//
258
// *************************
259
func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
260
261
token := peek_token(parser)
262
if token == nil {
263
return false
264
}
265
266
// Parse extra document end indicators.
267
if !implicit {
268
for token.typ == yaml_DOCUMENT_END_TOKEN {
269
skip_token(parser)
270
token = peek_token(parser)
271
if token == nil {
272
return false
273
}
274
}
275
}
276
277
if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
278
token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
279
token.typ != yaml_DOCUMENT_START_TOKEN &&
280
token.typ != yaml_STREAM_END_TOKEN {
281
// Parse an implicit document.
282
if !yaml_parser_process_directives(parser, nil, nil) {
283
return false
284
}
285
parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
286
parser.state = yaml_PARSE_BLOCK_NODE_STATE
287
288
var head_comment []byte
289
if len(parser.head_comment) > 0 {
290
// [Go] Scan the header comment backwards, and if an empty line is found, break
291
// the header so the part before the last empty line goes into the
292
// document header, while the bottom of it goes into a follow up event.
293
for i := len(parser.head_comment) - 1; i > 0; i-- {
294
if parser.head_comment[i] == '\n' {
295
if i == len(parser.head_comment)-1 {
296
head_comment = parser.head_comment[:i]
297
parser.head_comment = parser.head_comment[i+1:]
298
break
299
} else if parser.head_comment[i-1] == '\n' {
300
head_comment = parser.head_comment[:i-1]
301
parser.head_comment = parser.head_comment[i+1:]
302
break
303
}
304
}
305
}
306
}
307
308
*event = yaml_event_t{
309
typ: yaml_DOCUMENT_START_EVENT,
310
start_mark: token.start_mark,
311
end_mark: token.end_mark,
312
313
head_comment: head_comment,
314
}
315
316
} else if token.typ != yaml_STREAM_END_TOKEN {
317
// Parse an explicit document.
318
var version_directive *yaml_version_directive_t
319
var tag_directives []yaml_tag_directive_t
320
start_mark := token.start_mark
321
if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
322
return false
323
}
324
token = peek_token(parser)
325
if token == nil {
326
return false
327
}
328
if token.typ != yaml_DOCUMENT_START_TOKEN {
329
yaml_parser_set_parser_error(parser,
330
"did not find expected <document start>", token.start_mark)
331
return false
332
}
333
parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
334
parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
335
end_mark := token.end_mark
336
337
*event = yaml_event_t{
338
typ: yaml_DOCUMENT_START_EVENT,
339
start_mark: start_mark,
340
end_mark: end_mark,
341
version_directive: version_directive,
342
tag_directives: tag_directives,
343
implicit: false,
344
}
345
skip_token(parser)
346
347
} else {
348
// Parse the stream end.
349
parser.state = yaml_PARSE_END_STATE
350
*event = yaml_event_t{
351
typ: yaml_STREAM_END_EVENT,
352
start_mark: token.start_mark,
353
end_mark: token.end_mark,
354
}
355
skip_token(parser)
356
}
357
358
return true
359
}
360
361
// Parse the productions:
362
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
363
//
364
// ***********
365
func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
366
token := peek_token(parser)
367
if token == nil {
368
return false
369
}
370
371
if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
372
token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
373
token.typ == yaml_DOCUMENT_START_TOKEN ||
374
token.typ == yaml_DOCUMENT_END_TOKEN ||
375
token.typ == yaml_STREAM_END_TOKEN {
376
parser.state = parser.states[len(parser.states)-1]
377
parser.states = parser.states[:len(parser.states)-1]
378
return yaml_parser_process_empty_scalar(parser, event,
379
token.start_mark)
380
}
381
return yaml_parser_parse_node(parser, event, true, false)
382
}
383
384
// Parse the productions:
385
// implicit_document ::= block_node DOCUMENT-END*
386
//
387
// *************
388
//
389
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
390
func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
391
token := peek_token(parser)
392
if token == nil {
393
return false
394
}
395
396
start_mark := token.start_mark
397
end_mark := token.start_mark
398
399
implicit := true
400
if token.typ == yaml_DOCUMENT_END_TOKEN {
401
end_mark = token.end_mark
402
skip_token(parser)
403
implicit = false
404
}
405
406
parser.tag_directives = parser.tag_directives[:0]
407
408
parser.state = yaml_PARSE_DOCUMENT_START_STATE
409
*event = yaml_event_t{
410
typ: yaml_DOCUMENT_END_EVENT,
411
start_mark: start_mark,
412
end_mark: end_mark,
413
implicit: implicit,
414
}
415
yaml_parser_set_event_comments(parser, event)
416
if len(event.head_comment) > 0 && len(event.foot_comment) == 0 {
417
event.foot_comment = event.head_comment
418
event.head_comment = nil
419
}
420
return true
421
}
422
423
func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) {
424
event.head_comment = parser.head_comment
425
event.line_comment = parser.line_comment
426
event.foot_comment = parser.foot_comment
427
parser.head_comment = nil
428
parser.line_comment = nil
429
parser.foot_comment = nil
430
parser.tail_comment = nil
431
parser.stem_comment = nil
432
}
433
434
// Parse the productions:
435
// block_node_or_indentless_sequence ::=
436
//
437
// ALIAS
438
// *****
439
// | properties (block_content | indentless_block_sequence)?
440
// ********** *
441
// | block_content | indentless_block_sequence
442
// *
443
//
444
// block_node ::= ALIAS
445
//
446
// *****
447
// | properties block_content?
448
// ********** *
449
// | block_content
450
// *
451
//
452
// flow_node ::= ALIAS
453
//
454
// *****
455
// | properties flow_content?
456
// ********** *
457
// | flow_content
458
// *
459
//
460
// properties ::= TAG ANCHOR? | ANCHOR TAG?
461
//
462
// *************************
463
//
464
// block_content ::= block_collection | flow_collection | SCALAR
465
//
466
// ******
467
//
468
// flow_content ::= flow_collection | SCALAR
469
//
470
// ******
471
func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
472
//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
473
474
token := peek_token(parser)
475
if token == nil {
476
return false
477
}
478
479
if token.typ == yaml_ALIAS_TOKEN {
480
parser.state = parser.states[len(parser.states)-1]
481
parser.states = parser.states[:len(parser.states)-1]
482
*event = yaml_event_t{
483
typ: yaml_ALIAS_EVENT,
484
start_mark: token.start_mark,
485
end_mark: token.end_mark,
486
anchor: token.value,
487
}
488
yaml_parser_set_event_comments(parser, event)
489
skip_token(parser)
490
return true
491
}
492
493
start_mark := token.start_mark
494
end_mark := token.start_mark
495
496
var tag_token bool
497
var tag_handle, tag_suffix, anchor []byte
498
var tag_mark yaml_mark_t
499
if token.typ == yaml_ANCHOR_TOKEN {
500
anchor = token.value
501
start_mark = token.start_mark
502
end_mark = token.end_mark
503
skip_token(parser)
504
token = peek_token(parser)
505
if token == nil {
506
return false
507
}
508
if token.typ == yaml_TAG_TOKEN {
509
tag_token = true
510
tag_handle = token.value
511
tag_suffix = token.suffix
512
tag_mark = token.start_mark
513
end_mark = token.end_mark
514
skip_token(parser)
515
token = peek_token(parser)
516
if token == nil {
517
return false
518
}
519
}
520
} else if token.typ == yaml_TAG_TOKEN {
521
tag_token = true
522
tag_handle = token.value
523
tag_suffix = token.suffix
524
start_mark = token.start_mark
525
tag_mark = token.start_mark
526
end_mark = token.end_mark
527
skip_token(parser)
528
token = peek_token(parser)
529
if token == nil {
530
return false
531
}
532
if token.typ == yaml_ANCHOR_TOKEN {
533
anchor = token.value
534
end_mark = token.end_mark
535
skip_token(parser)
536
token = peek_token(parser)
537
if token == nil {
538
return false
539
}
540
}
541
}
542
543
var tag []byte
544
if tag_token {
545
if len(tag_handle) == 0 {
546
tag = tag_suffix
547
tag_suffix = nil
548
} else {
549
for i := range parser.tag_directives {
550
if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
551
tag = append([]byte(nil), parser.tag_directives[i].prefix...)
552
tag = append(tag, tag_suffix...)
553
break
554
}
555
}
556
if len(tag) == 0 {
557
yaml_parser_set_parser_error_context(parser,
558
"while parsing a node", start_mark,
559
"found undefined tag handle", tag_mark)
560
return false
561
}
562
}
563
}
564
565
implicit := len(tag) == 0
566
if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
567
end_mark = token.end_mark
568
parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
569
*event = yaml_event_t{
570
typ: yaml_SEQUENCE_START_EVENT,
571
start_mark: start_mark,
572
end_mark: end_mark,
573
anchor: anchor,
574
tag: tag,
575
implicit: implicit,
576
style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
577
}
578
return true
579
}
580
if token.typ == yaml_SCALAR_TOKEN {
581
var plain_implicit, quoted_implicit bool
582
end_mark = token.end_mark
583
if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
584
plain_implicit = true
585
} else if len(tag) == 0 {
586
quoted_implicit = true
587
}
588
parser.state = parser.states[len(parser.states)-1]
589
parser.states = parser.states[:len(parser.states)-1]
590
591
*event = yaml_event_t{
592
typ: yaml_SCALAR_EVENT,
593
start_mark: start_mark,
594
end_mark: end_mark,
595
anchor: anchor,
596
tag: tag,
597
value: token.value,
598
implicit: plain_implicit,
599
quoted_implicit: quoted_implicit,
600
style: yaml_style_t(token.style),
601
}
602
yaml_parser_set_event_comments(parser, event)
603
skip_token(parser)
604
return true
605
}
606
if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
607
// [Go] Some of the events below can be merged as they differ only on style.
608
end_mark = token.end_mark
609
parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
610
*event = yaml_event_t{
611
typ: yaml_SEQUENCE_START_EVENT,
612
start_mark: start_mark,
613
end_mark: end_mark,
614
anchor: anchor,
615
tag: tag,
616
implicit: implicit,
617
style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
618
}
619
yaml_parser_set_event_comments(parser, event)
620
return true
621
}
622
if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
623
end_mark = token.end_mark
624
parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
625
*event = yaml_event_t{
626
typ: yaml_MAPPING_START_EVENT,
627
start_mark: start_mark,
628
end_mark: end_mark,
629
anchor: anchor,
630
tag: tag,
631
implicit: implicit,
632
style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
633
}
634
yaml_parser_set_event_comments(parser, event)
635
return true
636
}
637
if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
638
end_mark = token.end_mark
639
parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
640
*event = yaml_event_t{
641
typ: yaml_SEQUENCE_START_EVENT,
642
start_mark: start_mark,
643
end_mark: end_mark,
644
anchor: anchor,
645
tag: tag,
646
implicit: implicit,
647
style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
648
}
649
if parser.stem_comment != nil {
650
event.head_comment = parser.stem_comment
651
parser.stem_comment = nil
652
}
653
return true
654
}
655
if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
656
end_mark = token.end_mark
657
parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
658
*event = yaml_event_t{
659
typ: yaml_MAPPING_START_EVENT,
660
start_mark: start_mark,
661
end_mark: end_mark,
662
anchor: anchor,
663
tag: tag,
664
implicit: implicit,
665
style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
666
}
667
if parser.stem_comment != nil {
668
event.head_comment = parser.stem_comment
669
parser.stem_comment = nil
670
}
671
return true
672
}
673
if len(anchor) > 0 || len(tag) > 0 {
674
parser.state = parser.states[len(parser.states)-1]
675
parser.states = parser.states[:len(parser.states)-1]
676
677
*event = yaml_event_t{
678
typ: yaml_SCALAR_EVENT,
679
start_mark: start_mark,
680
end_mark: end_mark,
681
anchor: anchor,
682
tag: tag,
683
implicit: implicit,
684
quoted_implicit: false,
685
style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
686
}
687
return true
688
}
689
690
context := "while parsing a flow node"
691
if block {
692
context = "while parsing a block node"
693
}
694
yaml_parser_set_parser_error_context(parser, context, start_mark,
695
"did not find expected node content", token.start_mark)
696
return false
697
}
698
699
// Parse the productions:
700
// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
701
//
702
// ******************** *********** * *********
703
func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
704
if first {
705
token := peek_token(parser)
706
if token == nil {
707
return false
708
}
709
parser.marks = append(parser.marks, token.start_mark)
710
skip_token(parser)
711
}
712
713
token := peek_token(parser)
714
if token == nil {
715
return false
716
}
717
718
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
719
mark := token.end_mark
720
prior_head_len := len(parser.head_comment)
721
skip_token(parser)
722
yaml_parser_split_stem_comment(parser, prior_head_len)
723
token = peek_token(parser)
724
if token == nil {
725
return false
726
}
727
if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
728
parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
729
return yaml_parser_parse_node(parser, event, true, false)
730
} else {
731
parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
732
return yaml_parser_process_empty_scalar(parser, event, mark)
733
}
734
}
735
if token.typ == yaml_BLOCK_END_TOKEN {
736
parser.state = parser.states[len(parser.states)-1]
737
parser.states = parser.states[:len(parser.states)-1]
738
parser.marks = parser.marks[:len(parser.marks)-1]
739
740
*event = yaml_event_t{
741
typ: yaml_SEQUENCE_END_EVENT,
742
start_mark: token.start_mark,
743
end_mark: token.end_mark,
744
}
745
746
skip_token(parser)
747
return true
748
}
749
750
context_mark := parser.marks[len(parser.marks)-1]
751
parser.marks = parser.marks[:len(parser.marks)-1]
752
return yaml_parser_set_parser_error_context(parser,
753
"while parsing a block collection", context_mark,
754
"did not find expected '-' indicator", token.start_mark)
755
}
756
757
// Parse the productions:
758
// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
759
//
760
// *********** *
761
func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
762
token := peek_token(parser)
763
if token == nil {
764
return false
765
}
766
767
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
768
mark := token.end_mark
769
prior_head_len := len(parser.head_comment)
770
skip_token(parser)
771
yaml_parser_split_stem_comment(parser, prior_head_len)
772
token = peek_token(parser)
773
if token == nil {
774
return false
775
}
776
if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
777
token.typ != yaml_KEY_TOKEN &&
778
token.typ != yaml_VALUE_TOKEN &&
779
token.typ != yaml_BLOCK_END_TOKEN {
780
parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
781
return yaml_parser_parse_node(parser, event, true, false)
782
}
783
parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
784
return yaml_parser_process_empty_scalar(parser, event, mark)
785
}
786
parser.state = parser.states[len(parser.states)-1]
787
parser.states = parser.states[:len(parser.states)-1]
788
789
*event = yaml_event_t{
790
typ: yaml_SEQUENCE_END_EVENT,
791
start_mark: token.start_mark,
792
end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark?
793
}
794
return true
795
}
796
797
// Split stem comment from head comment.
798
//
799
// When a sequence or map is found under a sequence entry, the former head comment
800
// is assigned to the underlying sequence or map as a whole, not the individual
801
// sequence or map entry as would be expected otherwise. To handle this case the
802
// previous head comment is moved aside as the stem comment.
803
func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
804
if stem_len == 0 {
805
return
806
}
807
808
token := peek_token(parser)
809
if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
810
return
811
}
812
813
parser.stem_comment = parser.head_comment[:stem_len]
814
if len(parser.head_comment) == stem_len {
815
parser.head_comment = nil
816
} else {
817
// Copy suffix to prevent very strange bugs if someone ever appends
818
// further bytes to the prefix in the stem_comment slice above.
819
parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...)
820
}
821
}
822
823
// Parse the productions:
824
// block_mapping ::= BLOCK-MAPPING_START
825
//
826
// *******************
827
// ((KEY block_node_or_indentless_sequence?)?
828
// *** *
829
// (VALUE block_node_or_indentless_sequence?)?)*
830
//
831
// BLOCK-END
832
// *********
833
func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
834
if first {
835
token := peek_token(parser)
836
if token == nil {
837
return false
838
}
839
parser.marks = append(parser.marks, token.start_mark)
840
skip_token(parser)
841
}
842
843
token := peek_token(parser)
844
if token == nil {
845
return false
846
}
847
848
// [Go] A tail comment was left from the prior mapping value processed. Emit an event
849
// as it needs to be processed with that value and not the following key.
850
if len(parser.tail_comment) > 0 {
851
*event = yaml_event_t{
852
typ: yaml_TAIL_COMMENT_EVENT,
853
start_mark: token.start_mark,
854
end_mark: token.end_mark,
855
foot_comment: parser.tail_comment,
856
}
857
parser.tail_comment = nil
858
return true
859
}
860
861
if token.typ == yaml_KEY_TOKEN {
862
mark := token.end_mark
863
skip_token(parser)
864
token = peek_token(parser)
865
if token == nil {
866
return false
867
}
868
if token.typ != yaml_KEY_TOKEN &&
869
token.typ != yaml_VALUE_TOKEN &&
870
token.typ != yaml_BLOCK_END_TOKEN {
871
parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
872
return yaml_parser_parse_node(parser, event, true, true)
873
} else {
874
parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
875
return yaml_parser_process_empty_scalar(parser, event, mark)
876
}
877
} else if token.typ == yaml_BLOCK_END_TOKEN {
878
parser.state = parser.states[len(parser.states)-1]
879
parser.states = parser.states[:len(parser.states)-1]
880
parser.marks = parser.marks[:len(parser.marks)-1]
881
*event = yaml_event_t{
882
typ: yaml_MAPPING_END_EVENT,
883
start_mark: token.start_mark,
884
end_mark: token.end_mark,
885
}
886
yaml_parser_set_event_comments(parser, event)
887
skip_token(parser)
888
return true
889
}
890
891
context_mark := parser.marks[len(parser.marks)-1]
892
parser.marks = parser.marks[:len(parser.marks)-1]
893
return yaml_parser_set_parser_error_context(parser,
894
"while parsing a block mapping", context_mark,
895
"did not find expected key", token.start_mark)
896
}
897
898
// Parse the productions:
899
// block_mapping ::= BLOCK-MAPPING_START
900
//
901
// ((KEY block_node_or_indentless_sequence?)?
902
//
903
// (VALUE block_node_or_indentless_sequence?)?)*
904
// ***** *
905
// BLOCK-END
906
func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
907
token := peek_token(parser)
908
if token == nil {
909
return false
910
}
911
if token.typ == yaml_VALUE_TOKEN {
912
mark := token.end_mark
913
skip_token(parser)
914
token = peek_token(parser)
915
if token == nil {
916
return false
917
}
918
if token.typ != yaml_KEY_TOKEN &&
919
token.typ != yaml_VALUE_TOKEN &&
920
token.typ != yaml_BLOCK_END_TOKEN {
921
parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
922
return yaml_parser_parse_node(parser, event, true, true)
923
}
924
parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
925
return yaml_parser_process_empty_scalar(parser, event, mark)
926
}
927
parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
928
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
929
}
930
931
// Parse the productions:
932
// flow_sequence ::= FLOW-SEQUENCE-START
933
//
934
// *******************
935
// (flow_sequence_entry FLOW-ENTRY)*
936
// * **********
937
// flow_sequence_entry?
938
// *
939
// FLOW-SEQUENCE-END
940
// *****************
941
//
942
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
943
//
944
// *
945
func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
946
if first {
947
token := peek_token(parser)
948
if token == nil {
949
return false
950
}
951
parser.marks = append(parser.marks, token.start_mark)
952
skip_token(parser)
953
}
954
token := peek_token(parser)
955
if token == nil {
956
return false
957
}
958
if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
959
if !first {
960
if token.typ == yaml_FLOW_ENTRY_TOKEN {
961
skip_token(parser)
962
token = peek_token(parser)
963
if token == nil {
964
return false
965
}
966
} else {
967
context_mark := parser.marks[len(parser.marks)-1]
968
parser.marks = parser.marks[:len(parser.marks)-1]
969
return yaml_parser_set_parser_error_context(parser,
970
"while parsing a flow sequence", context_mark,
971
"did not find expected ',' or ']'", token.start_mark)
972
}
973
}
974
975
if token.typ == yaml_KEY_TOKEN {
976
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
977
*event = yaml_event_t{
978
typ: yaml_MAPPING_START_EVENT,
979
start_mark: token.start_mark,
980
end_mark: token.end_mark,
981
implicit: true,
982
style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
983
}
984
skip_token(parser)
985
return true
986
} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
987
parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
988
return yaml_parser_parse_node(parser, event, false, false)
989
}
990
}
991
992
parser.state = parser.states[len(parser.states)-1]
993
parser.states = parser.states[:len(parser.states)-1]
994
parser.marks = parser.marks[:len(parser.marks)-1]
995
996
*event = yaml_event_t{
997
typ: yaml_SEQUENCE_END_EVENT,
998
start_mark: token.start_mark,
999
end_mark: token.end_mark,
1000
}
1001
yaml_parser_set_event_comments(parser, event)
1002
1003
skip_token(parser)
1004
return true
1005
}
1006
1007
// Parse the productions:
1008
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1009
//
1010
// *** *
1011
func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
1012
token := peek_token(parser)
1013
if token == nil {
1014
return false
1015
}
1016
if token.typ != yaml_VALUE_TOKEN &&
1017
token.typ != yaml_FLOW_ENTRY_TOKEN &&
1018
token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
1019
parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
1020
return yaml_parser_parse_node(parser, event, false, false)
1021
}
1022
mark := token.end_mark
1023
skip_token(parser)
1024
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
1025
return yaml_parser_process_empty_scalar(parser, event, mark)
1026
}
1027
1028
// Parse the productions:
1029
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1030
//
1031
// ***** *
1032
func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
1033
token := peek_token(parser)
1034
if token == nil {
1035
return false
1036
}
1037
if token.typ == yaml_VALUE_TOKEN {
1038
skip_token(parser)
1039
token := peek_token(parser)
1040
if token == nil {
1041
return false
1042
}
1043
if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
1044
parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
1045
return yaml_parser_parse_node(parser, event, false, false)
1046
}
1047
}
1048
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
1049
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1050
}
1051
1052
// Parse the productions:
1053
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1054
//
1055
// *
1056
func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
1057
token := peek_token(parser)
1058
if token == nil {
1059
return false
1060
}
1061
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
1062
*event = yaml_event_t{
1063
typ: yaml_MAPPING_END_EVENT,
1064
start_mark: token.start_mark,
1065
end_mark: token.start_mark, // [Go] Shouldn't this be end_mark?
1066
}
1067
return true
1068
}
1069
1070
// Parse the productions:
1071
// flow_mapping ::= FLOW-MAPPING-START
1072
//
1073
// ******************
1074
// (flow_mapping_entry FLOW-ENTRY)*
1075
// * **********
1076
// flow_mapping_entry?
1077
// ******************
1078
// FLOW-MAPPING-END
1079
// ****************
1080
//
1081
// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1082
// - *** *
1083
func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
1084
if first {
1085
token := peek_token(parser)
1086
parser.marks = append(parser.marks, token.start_mark)
1087
skip_token(parser)
1088
}
1089
1090
token := peek_token(parser)
1091
if token == nil {
1092
return false
1093
}
1094
1095
if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1096
if !first {
1097
if token.typ == yaml_FLOW_ENTRY_TOKEN {
1098
skip_token(parser)
1099
token = peek_token(parser)
1100
if token == nil {
1101
return false
1102
}
1103
} else {
1104
context_mark := parser.marks[len(parser.marks)-1]
1105
parser.marks = parser.marks[:len(parser.marks)-1]
1106
return yaml_parser_set_parser_error_context(parser,
1107
"while parsing a flow mapping", context_mark,
1108
"did not find expected ',' or '}'", token.start_mark)
1109
}
1110
}
1111
1112
if token.typ == yaml_KEY_TOKEN {
1113
skip_token(parser)
1114
token = peek_token(parser)
1115
if token == nil {
1116
return false
1117
}
1118
if token.typ != yaml_VALUE_TOKEN &&
1119
token.typ != yaml_FLOW_ENTRY_TOKEN &&
1120
token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1121
parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
1122
return yaml_parser_parse_node(parser, event, false, false)
1123
} else {
1124
parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
1125
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1126
}
1127
} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1128
parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
1129
return yaml_parser_parse_node(parser, event, false, false)
1130
}
1131
}
1132
1133
parser.state = parser.states[len(parser.states)-1]
1134
parser.states = parser.states[:len(parser.states)-1]
1135
parser.marks = parser.marks[:len(parser.marks)-1]
1136
*event = yaml_event_t{
1137
typ: yaml_MAPPING_END_EVENT,
1138
start_mark: token.start_mark,
1139
end_mark: token.end_mark,
1140
}
1141
yaml_parser_set_event_comments(parser, event)
1142
skip_token(parser)
1143
return true
1144
}
1145
1146
// Parse the productions:
1147
// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1148
// - ***** *
1149
func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
1150
token := peek_token(parser)
1151
if token == nil {
1152
return false
1153
}
1154
if empty {
1155
parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
1156
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1157
}
1158
if token.typ == yaml_VALUE_TOKEN {
1159
skip_token(parser)
1160
token = peek_token(parser)
1161
if token == nil {
1162
return false
1163
}
1164
if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1165
parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
1166
return yaml_parser_parse_node(parser, event, false, false)
1167
}
1168
}
1169
parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
1170
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1171
}
1172
1173
// Generate an empty scalar event.
1174
func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
1175
*event = yaml_event_t{
1176
typ: yaml_SCALAR_EVENT,
1177
start_mark: mark,
1178
end_mark: mark,
1179
value: nil, // Empty
1180
implicit: true,
1181
style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
1182
}
1183
return true
1184
}
1185
1186
var default_tag_directives = []yaml_tag_directive_t{
1187
{[]byte("!"), []byte("!")},
1188
{[]byte("!!"), []byte("tag:yaml.org,2002:")},
1189
}
1190
1191
// Parse directives.
1192
func yaml_parser_process_directives(parser *yaml_parser_t,
1193
version_directive_ref **yaml_version_directive_t,
1194
tag_directives_ref *[]yaml_tag_directive_t) bool {
1195
1196
var version_directive *yaml_version_directive_t
1197
var tag_directives []yaml_tag_directive_t
1198
1199
token := peek_token(parser)
1200
if token == nil {
1201
return false
1202
}
1203
1204
for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1205
if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
1206
if version_directive != nil {
1207
yaml_parser_set_parser_error(parser,
1208
"found duplicate %YAML directive", token.start_mark)
1209
return false
1210
}
1211
if token.major != 1 || token.minor != 1 {
1212
yaml_parser_set_parser_error(parser,
1213
"found incompatible YAML document", token.start_mark)
1214
return false
1215
}
1216
version_directive = &yaml_version_directive_t{
1217
major: token.major,
1218
minor: token.minor,
1219
}
1220
} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1221
value := yaml_tag_directive_t{
1222
handle: token.value,
1223
prefix: token.prefix,
1224
}
1225
if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
1226
return false
1227
}
1228
tag_directives = append(tag_directives, value)
1229
}
1230
1231
skip_token(parser)
1232
token = peek_token(parser)
1233
if token == nil {
1234
return false
1235
}
1236
}
1237
1238
for i := range default_tag_directives {
1239
if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
1240
return false
1241
}
1242
}
1243
1244
if version_directive_ref != nil {
1245
*version_directive_ref = version_directive
1246
}
1247
if tag_directives_ref != nil {
1248
*tag_directives_ref = tag_directives
1249
}
1250
return true
1251
}
1252
1253
// Append a tag directive to the directives stack.
1254
func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
1255
for i := range parser.tag_directives {
1256
if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
1257
if allow_duplicates {
1258
return true
1259
}
1260
return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
1261
}
1262
}
1263
1264
// [Go] I suspect the copy is unnecessary. This was likely done
1265
// because there was no way to track ownership of the data.
1266
value_copy := yaml_tag_directive_t{
1267
handle: make([]byte, len(value.handle)),
1268
prefix: make([]byte, len(value.prefix)),
1269
}
1270
copy(value_copy.handle, value.handle)
1271
copy(value_copy.prefix, value.prefix)
1272
parser.tag_directives = append(parser.tag_directives, value_copy)
1273
return true
1274
}
1275
1276