Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/gopkg.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
func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {
232
token := peek_token(parser)
233
if token == nil {
234
return false
235
}
236
if token.typ != yaml_STREAM_START_TOKEN {
237
return yaml_parser_set_parser_error(parser, "did not find expected <stream-start>", token.start_mark)
238
}
239
parser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE
240
*event = yaml_event_t{
241
typ: yaml_STREAM_START_EVENT,
242
start_mark: token.start_mark,
243
end_mark: token.end_mark,
244
encoding: token.encoding,
245
}
246
skip_token(parser)
247
return true
248
}
249
250
// Parse the productions:
251
// implicit_document ::= block_node DOCUMENT-END*
252
// *
253
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
254
// *************************
255
func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {
256
257
token := peek_token(parser)
258
if token == nil {
259
return false
260
}
261
262
// Parse extra document end indicators.
263
if !implicit {
264
for token.typ == yaml_DOCUMENT_END_TOKEN {
265
skip_token(parser)
266
token = peek_token(parser)
267
if token == nil {
268
return false
269
}
270
}
271
}
272
273
if implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&
274
token.typ != yaml_TAG_DIRECTIVE_TOKEN &&
275
token.typ != yaml_DOCUMENT_START_TOKEN &&
276
token.typ != yaml_STREAM_END_TOKEN {
277
// Parse an implicit document.
278
if !yaml_parser_process_directives(parser, nil, nil) {
279
return false
280
}
281
parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
282
parser.state = yaml_PARSE_BLOCK_NODE_STATE
283
284
var head_comment []byte
285
if len(parser.head_comment) > 0 {
286
// [Go] Scan the header comment backwards, and if an empty line is found, break
287
// the header so the part before the last empty line goes into the
288
// document header, while the bottom of it goes into a follow up event.
289
for i := len(parser.head_comment) - 1; i > 0; i-- {
290
if parser.head_comment[i] == '\n' {
291
if i == len(parser.head_comment)-1 {
292
head_comment = parser.head_comment[:i]
293
parser.head_comment = parser.head_comment[i+1:]
294
break
295
} else if parser.head_comment[i-1] == '\n' {
296
head_comment = parser.head_comment[:i-1]
297
parser.head_comment = parser.head_comment[i+1:]
298
break
299
}
300
}
301
}
302
}
303
304
*event = yaml_event_t{
305
typ: yaml_DOCUMENT_START_EVENT,
306
start_mark: token.start_mark,
307
end_mark: token.end_mark,
308
309
head_comment: head_comment,
310
}
311
312
} else if token.typ != yaml_STREAM_END_TOKEN {
313
// Parse an explicit document.
314
var version_directive *yaml_version_directive_t
315
var tag_directives []yaml_tag_directive_t
316
start_mark := token.start_mark
317
if !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {
318
return false
319
}
320
token = peek_token(parser)
321
if token == nil {
322
return false
323
}
324
if token.typ != yaml_DOCUMENT_START_TOKEN {
325
yaml_parser_set_parser_error(parser,
326
"did not find expected <document start>", token.start_mark)
327
return false
328
}
329
parser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)
330
parser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE
331
end_mark := token.end_mark
332
333
*event = yaml_event_t{
334
typ: yaml_DOCUMENT_START_EVENT,
335
start_mark: start_mark,
336
end_mark: end_mark,
337
version_directive: version_directive,
338
tag_directives: tag_directives,
339
implicit: false,
340
}
341
skip_token(parser)
342
343
} else {
344
// Parse the stream end.
345
parser.state = yaml_PARSE_END_STATE
346
*event = yaml_event_t{
347
typ: yaml_STREAM_END_EVENT,
348
start_mark: token.start_mark,
349
end_mark: token.end_mark,
350
}
351
skip_token(parser)
352
}
353
354
return true
355
}
356
357
// Parse the productions:
358
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
359
// ***********
360
//
361
func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {
362
token := peek_token(parser)
363
if token == nil {
364
return false
365
}
366
367
if token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||
368
token.typ == yaml_TAG_DIRECTIVE_TOKEN ||
369
token.typ == yaml_DOCUMENT_START_TOKEN ||
370
token.typ == yaml_DOCUMENT_END_TOKEN ||
371
token.typ == yaml_STREAM_END_TOKEN {
372
parser.state = parser.states[len(parser.states)-1]
373
parser.states = parser.states[:len(parser.states)-1]
374
return yaml_parser_process_empty_scalar(parser, event,
375
token.start_mark)
376
}
377
return yaml_parser_parse_node(parser, event, true, false)
378
}
379
380
// Parse the productions:
381
// implicit_document ::= block_node DOCUMENT-END*
382
// *************
383
// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
384
//
385
func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {
386
token := peek_token(parser)
387
if token == nil {
388
return false
389
}
390
391
start_mark := token.start_mark
392
end_mark := token.start_mark
393
394
implicit := true
395
if token.typ == yaml_DOCUMENT_END_TOKEN {
396
end_mark = token.end_mark
397
skip_token(parser)
398
implicit = false
399
}
400
401
parser.tag_directives = parser.tag_directives[:0]
402
403
parser.state = yaml_PARSE_DOCUMENT_START_STATE
404
*event = yaml_event_t{
405
typ: yaml_DOCUMENT_END_EVENT,
406
start_mark: start_mark,
407
end_mark: end_mark,
408
implicit: implicit,
409
}
410
yaml_parser_set_event_comments(parser, event)
411
if len(event.head_comment) > 0 && len(event.foot_comment) == 0 {
412
event.foot_comment = event.head_comment
413
event.head_comment = nil
414
}
415
return true
416
}
417
418
func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) {
419
event.head_comment = parser.head_comment
420
event.line_comment = parser.line_comment
421
event.foot_comment = parser.foot_comment
422
parser.head_comment = nil
423
parser.line_comment = nil
424
parser.foot_comment = nil
425
parser.tail_comment = nil
426
parser.stem_comment = nil
427
}
428
429
// Parse the productions:
430
// block_node_or_indentless_sequence ::=
431
// ALIAS
432
// *****
433
// | properties (block_content | indentless_block_sequence)?
434
// ********** *
435
// | block_content | indentless_block_sequence
436
// *
437
// block_node ::= ALIAS
438
// *****
439
// | properties block_content?
440
// ********** *
441
// | block_content
442
// *
443
// flow_node ::= ALIAS
444
// *****
445
// | properties flow_content?
446
// ********** *
447
// | flow_content
448
// *
449
// properties ::= TAG ANCHOR? | ANCHOR TAG?
450
// *************************
451
// block_content ::= block_collection | flow_collection | SCALAR
452
// ******
453
// flow_content ::= flow_collection | SCALAR
454
// ******
455
func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {
456
//defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)()
457
458
token := peek_token(parser)
459
if token == nil {
460
return false
461
}
462
463
if token.typ == yaml_ALIAS_TOKEN {
464
parser.state = parser.states[len(parser.states)-1]
465
parser.states = parser.states[:len(parser.states)-1]
466
*event = yaml_event_t{
467
typ: yaml_ALIAS_EVENT,
468
start_mark: token.start_mark,
469
end_mark: token.end_mark,
470
anchor: token.value,
471
}
472
yaml_parser_set_event_comments(parser, event)
473
skip_token(parser)
474
return true
475
}
476
477
start_mark := token.start_mark
478
end_mark := token.start_mark
479
480
var tag_token bool
481
var tag_handle, tag_suffix, anchor []byte
482
var tag_mark yaml_mark_t
483
if token.typ == yaml_ANCHOR_TOKEN {
484
anchor = token.value
485
start_mark = token.start_mark
486
end_mark = token.end_mark
487
skip_token(parser)
488
token = peek_token(parser)
489
if token == nil {
490
return false
491
}
492
if token.typ == yaml_TAG_TOKEN {
493
tag_token = true
494
tag_handle = token.value
495
tag_suffix = token.suffix
496
tag_mark = token.start_mark
497
end_mark = token.end_mark
498
skip_token(parser)
499
token = peek_token(parser)
500
if token == nil {
501
return false
502
}
503
}
504
} else if token.typ == yaml_TAG_TOKEN {
505
tag_token = true
506
tag_handle = token.value
507
tag_suffix = token.suffix
508
start_mark = token.start_mark
509
tag_mark = token.start_mark
510
end_mark = token.end_mark
511
skip_token(parser)
512
token = peek_token(parser)
513
if token == nil {
514
return false
515
}
516
if token.typ == yaml_ANCHOR_TOKEN {
517
anchor = token.value
518
end_mark = token.end_mark
519
skip_token(parser)
520
token = peek_token(parser)
521
if token == nil {
522
return false
523
}
524
}
525
}
526
527
var tag []byte
528
if tag_token {
529
if len(tag_handle) == 0 {
530
tag = tag_suffix
531
tag_suffix = nil
532
} else {
533
for i := range parser.tag_directives {
534
if bytes.Equal(parser.tag_directives[i].handle, tag_handle) {
535
tag = append([]byte(nil), parser.tag_directives[i].prefix...)
536
tag = append(tag, tag_suffix...)
537
break
538
}
539
}
540
if len(tag) == 0 {
541
yaml_parser_set_parser_error_context(parser,
542
"while parsing a node", start_mark,
543
"found undefined tag handle", tag_mark)
544
return false
545
}
546
}
547
}
548
549
implicit := len(tag) == 0
550
if indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {
551
end_mark = token.end_mark
552
parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
553
*event = yaml_event_t{
554
typ: yaml_SEQUENCE_START_EVENT,
555
start_mark: start_mark,
556
end_mark: end_mark,
557
anchor: anchor,
558
tag: tag,
559
implicit: implicit,
560
style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
561
}
562
return true
563
}
564
if token.typ == yaml_SCALAR_TOKEN {
565
var plain_implicit, quoted_implicit bool
566
end_mark = token.end_mark
567
if (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {
568
plain_implicit = true
569
} else if len(tag) == 0 {
570
quoted_implicit = true
571
}
572
parser.state = parser.states[len(parser.states)-1]
573
parser.states = parser.states[:len(parser.states)-1]
574
575
*event = yaml_event_t{
576
typ: yaml_SCALAR_EVENT,
577
start_mark: start_mark,
578
end_mark: end_mark,
579
anchor: anchor,
580
tag: tag,
581
value: token.value,
582
implicit: plain_implicit,
583
quoted_implicit: quoted_implicit,
584
style: yaml_style_t(token.style),
585
}
586
yaml_parser_set_event_comments(parser, event)
587
skip_token(parser)
588
return true
589
}
590
if token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {
591
// [Go] Some of the events below can be merged as they differ only on style.
592
end_mark = token.end_mark
593
parser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE
594
*event = yaml_event_t{
595
typ: yaml_SEQUENCE_START_EVENT,
596
start_mark: start_mark,
597
end_mark: end_mark,
598
anchor: anchor,
599
tag: tag,
600
implicit: implicit,
601
style: yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),
602
}
603
yaml_parser_set_event_comments(parser, event)
604
return true
605
}
606
if token.typ == yaml_FLOW_MAPPING_START_TOKEN {
607
end_mark = token.end_mark
608
parser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE
609
*event = yaml_event_t{
610
typ: yaml_MAPPING_START_EVENT,
611
start_mark: start_mark,
612
end_mark: end_mark,
613
anchor: anchor,
614
tag: tag,
615
implicit: implicit,
616
style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
617
}
618
yaml_parser_set_event_comments(parser, event)
619
return true
620
}
621
if block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {
622
end_mark = token.end_mark
623
parser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE
624
*event = yaml_event_t{
625
typ: yaml_SEQUENCE_START_EVENT,
626
start_mark: start_mark,
627
end_mark: end_mark,
628
anchor: anchor,
629
tag: tag,
630
implicit: implicit,
631
style: yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),
632
}
633
if parser.stem_comment != nil {
634
event.head_comment = parser.stem_comment
635
parser.stem_comment = nil
636
}
637
return true
638
}
639
if block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {
640
end_mark = token.end_mark
641
parser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE
642
*event = yaml_event_t{
643
typ: yaml_MAPPING_START_EVENT,
644
start_mark: start_mark,
645
end_mark: end_mark,
646
anchor: anchor,
647
tag: tag,
648
implicit: implicit,
649
style: yaml_style_t(yaml_BLOCK_MAPPING_STYLE),
650
}
651
if parser.stem_comment != nil {
652
event.head_comment = parser.stem_comment
653
parser.stem_comment = nil
654
}
655
return true
656
}
657
if len(anchor) > 0 || len(tag) > 0 {
658
parser.state = parser.states[len(parser.states)-1]
659
parser.states = parser.states[:len(parser.states)-1]
660
661
*event = yaml_event_t{
662
typ: yaml_SCALAR_EVENT,
663
start_mark: start_mark,
664
end_mark: end_mark,
665
anchor: anchor,
666
tag: tag,
667
implicit: implicit,
668
quoted_implicit: false,
669
style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
670
}
671
return true
672
}
673
674
context := "while parsing a flow node"
675
if block {
676
context = "while parsing a block node"
677
}
678
yaml_parser_set_parser_error_context(parser, context, start_mark,
679
"did not find expected node content", token.start_mark)
680
return false
681
}
682
683
// Parse the productions:
684
// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
685
// ******************** *********** * *********
686
//
687
func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
688
if first {
689
token := peek_token(parser)
690
if token == nil {
691
return false
692
}
693
parser.marks = append(parser.marks, token.start_mark)
694
skip_token(parser)
695
}
696
697
token := peek_token(parser)
698
if token == nil {
699
return false
700
}
701
702
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
703
mark := token.end_mark
704
prior_head_len := len(parser.head_comment)
705
skip_token(parser)
706
yaml_parser_split_stem_comment(parser, prior_head_len)
707
token = peek_token(parser)
708
if token == nil {
709
return false
710
}
711
if token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {
712
parser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)
713
return yaml_parser_parse_node(parser, event, true, false)
714
} else {
715
parser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE
716
return yaml_parser_process_empty_scalar(parser, event, mark)
717
}
718
}
719
if token.typ == yaml_BLOCK_END_TOKEN {
720
parser.state = parser.states[len(parser.states)-1]
721
parser.states = parser.states[:len(parser.states)-1]
722
parser.marks = parser.marks[:len(parser.marks)-1]
723
724
*event = yaml_event_t{
725
typ: yaml_SEQUENCE_END_EVENT,
726
start_mark: token.start_mark,
727
end_mark: token.end_mark,
728
}
729
730
skip_token(parser)
731
return true
732
}
733
734
context_mark := parser.marks[len(parser.marks)-1]
735
parser.marks = parser.marks[:len(parser.marks)-1]
736
return yaml_parser_set_parser_error_context(parser,
737
"while parsing a block collection", context_mark,
738
"did not find expected '-' indicator", token.start_mark)
739
}
740
741
// Parse the productions:
742
// indentless_sequence ::= (BLOCK-ENTRY block_node?)+
743
// *********** *
744
func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {
745
token := peek_token(parser)
746
if token == nil {
747
return false
748
}
749
750
if token.typ == yaml_BLOCK_ENTRY_TOKEN {
751
mark := token.end_mark
752
prior_head_len := len(parser.head_comment)
753
skip_token(parser)
754
yaml_parser_split_stem_comment(parser, prior_head_len)
755
token = peek_token(parser)
756
if token == nil {
757
return false
758
}
759
if token.typ != yaml_BLOCK_ENTRY_TOKEN &&
760
token.typ != yaml_KEY_TOKEN &&
761
token.typ != yaml_VALUE_TOKEN &&
762
token.typ != yaml_BLOCK_END_TOKEN {
763
parser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)
764
return yaml_parser_parse_node(parser, event, true, false)
765
}
766
parser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE
767
return yaml_parser_process_empty_scalar(parser, event, mark)
768
}
769
parser.state = parser.states[len(parser.states)-1]
770
parser.states = parser.states[:len(parser.states)-1]
771
772
*event = yaml_event_t{
773
typ: yaml_SEQUENCE_END_EVENT,
774
start_mark: token.start_mark,
775
end_mark: token.start_mark, // [Go] Shouldn't this be token.end_mark?
776
}
777
return true
778
}
779
780
// Split stem comment from head comment.
781
//
782
// When a sequence or map is found under a sequence entry, the former head comment
783
// is assigned to the underlying sequence or map as a whole, not the individual
784
// sequence or map entry as would be expected otherwise. To handle this case the
785
// previous head comment is moved aside as the stem comment.
786
func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {
787
if stem_len == 0 {
788
return
789
}
790
791
token := peek_token(parser)
792
if token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {
793
return
794
}
795
796
parser.stem_comment = parser.head_comment[:stem_len]
797
if len(parser.head_comment) == stem_len {
798
parser.head_comment = nil
799
} else {
800
// Copy suffix to prevent very strange bugs if someone ever appends
801
// further bytes to the prefix in the stem_comment slice above.
802
parser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...)
803
}
804
}
805
806
// Parse the productions:
807
// block_mapping ::= BLOCK-MAPPING_START
808
// *******************
809
// ((KEY block_node_or_indentless_sequence?)?
810
// *** *
811
// (VALUE block_node_or_indentless_sequence?)?)*
812
//
813
// BLOCK-END
814
// *********
815
//
816
func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
817
if first {
818
token := peek_token(parser)
819
if token == nil {
820
return false
821
}
822
parser.marks = append(parser.marks, token.start_mark)
823
skip_token(parser)
824
}
825
826
token := peek_token(parser)
827
if token == nil {
828
return false
829
}
830
831
// [Go] A tail comment was left from the prior mapping value processed. Emit an event
832
// as it needs to be processed with that value and not the following key.
833
if len(parser.tail_comment) > 0 {
834
*event = yaml_event_t{
835
typ: yaml_TAIL_COMMENT_EVENT,
836
start_mark: token.start_mark,
837
end_mark: token.end_mark,
838
foot_comment: parser.tail_comment,
839
}
840
parser.tail_comment = nil
841
return true
842
}
843
844
if token.typ == yaml_KEY_TOKEN {
845
mark := token.end_mark
846
skip_token(parser)
847
token = peek_token(parser)
848
if token == nil {
849
return false
850
}
851
if token.typ != yaml_KEY_TOKEN &&
852
token.typ != yaml_VALUE_TOKEN &&
853
token.typ != yaml_BLOCK_END_TOKEN {
854
parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)
855
return yaml_parser_parse_node(parser, event, true, true)
856
} else {
857
parser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE
858
return yaml_parser_process_empty_scalar(parser, event, mark)
859
}
860
} else if token.typ == yaml_BLOCK_END_TOKEN {
861
parser.state = parser.states[len(parser.states)-1]
862
parser.states = parser.states[:len(parser.states)-1]
863
parser.marks = parser.marks[:len(parser.marks)-1]
864
*event = yaml_event_t{
865
typ: yaml_MAPPING_END_EVENT,
866
start_mark: token.start_mark,
867
end_mark: token.end_mark,
868
}
869
yaml_parser_set_event_comments(parser, event)
870
skip_token(parser)
871
return true
872
}
873
874
context_mark := parser.marks[len(parser.marks)-1]
875
parser.marks = parser.marks[:len(parser.marks)-1]
876
return yaml_parser_set_parser_error_context(parser,
877
"while parsing a block mapping", context_mark,
878
"did not find expected key", token.start_mark)
879
}
880
881
// Parse the productions:
882
// block_mapping ::= BLOCK-MAPPING_START
883
//
884
// ((KEY block_node_or_indentless_sequence?)?
885
//
886
// (VALUE block_node_or_indentless_sequence?)?)*
887
// ***** *
888
// BLOCK-END
889
//
890
//
891
func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
892
token := peek_token(parser)
893
if token == nil {
894
return false
895
}
896
if token.typ == yaml_VALUE_TOKEN {
897
mark := token.end_mark
898
skip_token(parser)
899
token = peek_token(parser)
900
if token == nil {
901
return false
902
}
903
if token.typ != yaml_KEY_TOKEN &&
904
token.typ != yaml_VALUE_TOKEN &&
905
token.typ != yaml_BLOCK_END_TOKEN {
906
parser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)
907
return yaml_parser_parse_node(parser, event, true, true)
908
}
909
parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
910
return yaml_parser_process_empty_scalar(parser, event, mark)
911
}
912
parser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE
913
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
914
}
915
916
// Parse the productions:
917
// flow_sequence ::= FLOW-SEQUENCE-START
918
// *******************
919
// (flow_sequence_entry FLOW-ENTRY)*
920
// * **********
921
// flow_sequence_entry?
922
// *
923
// FLOW-SEQUENCE-END
924
// *****************
925
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
926
// *
927
//
928
func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
929
if first {
930
token := peek_token(parser)
931
if token == nil {
932
return false
933
}
934
parser.marks = append(parser.marks, token.start_mark)
935
skip_token(parser)
936
}
937
token := peek_token(parser)
938
if token == nil {
939
return false
940
}
941
if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
942
if !first {
943
if token.typ == yaml_FLOW_ENTRY_TOKEN {
944
skip_token(parser)
945
token = peek_token(parser)
946
if token == nil {
947
return false
948
}
949
} else {
950
context_mark := parser.marks[len(parser.marks)-1]
951
parser.marks = parser.marks[:len(parser.marks)-1]
952
return yaml_parser_set_parser_error_context(parser,
953
"while parsing a flow sequence", context_mark,
954
"did not find expected ',' or ']'", token.start_mark)
955
}
956
}
957
958
if token.typ == yaml_KEY_TOKEN {
959
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE
960
*event = yaml_event_t{
961
typ: yaml_MAPPING_START_EVENT,
962
start_mark: token.start_mark,
963
end_mark: token.end_mark,
964
implicit: true,
965
style: yaml_style_t(yaml_FLOW_MAPPING_STYLE),
966
}
967
skip_token(parser)
968
return true
969
} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
970
parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)
971
return yaml_parser_parse_node(parser, event, false, false)
972
}
973
}
974
975
parser.state = parser.states[len(parser.states)-1]
976
parser.states = parser.states[:len(parser.states)-1]
977
parser.marks = parser.marks[:len(parser.marks)-1]
978
979
*event = yaml_event_t{
980
typ: yaml_SEQUENCE_END_EVENT,
981
start_mark: token.start_mark,
982
end_mark: token.end_mark,
983
}
984
yaml_parser_set_event_comments(parser, event)
985
986
skip_token(parser)
987
return true
988
}
989
990
//
991
// Parse the productions:
992
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
993
// *** *
994
//
995
func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {
996
token := peek_token(parser)
997
if token == nil {
998
return false
999
}
1000
if token.typ != yaml_VALUE_TOKEN &&
1001
token.typ != yaml_FLOW_ENTRY_TOKEN &&
1002
token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
1003
parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)
1004
return yaml_parser_parse_node(parser, event, false, false)
1005
}
1006
mark := token.end_mark
1007
skip_token(parser)
1008
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
1009
return yaml_parser_process_empty_scalar(parser, event, mark)
1010
}
1011
1012
// Parse the productions:
1013
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1014
// ***** *
1015
//
1016
func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {
1017
token := peek_token(parser)
1018
if token == nil {
1019
return false
1020
}
1021
if token.typ == yaml_VALUE_TOKEN {
1022
skip_token(parser)
1023
token := peek_token(parser)
1024
if token == nil {
1025
return false
1026
}
1027
if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {
1028
parser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)
1029
return yaml_parser_parse_node(parser, event, false, false)
1030
}
1031
}
1032
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
1033
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1034
}
1035
1036
// Parse the productions:
1037
// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1038
// *
1039
//
1040
func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {
1041
token := peek_token(parser)
1042
if token == nil {
1043
return false
1044
}
1045
parser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE
1046
*event = yaml_event_t{
1047
typ: yaml_MAPPING_END_EVENT,
1048
start_mark: token.start_mark,
1049
end_mark: token.start_mark, // [Go] Shouldn't this be end_mark?
1050
}
1051
return true
1052
}
1053
1054
// Parse the productions:
1055
// flow_mapping ::= FLOW-MAPPING-START
1056
// ******************
1057
// (flow_mapping_entry FLOW-ENTRY)*
1058
// * **********
1059
// flow_mapping_entry?
1060
// ******************
1061
// FLOW-MAPPING-END
1062
// ****************
1063
// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1064
// * *** *
1065
//
1066
func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {
1067
if first {
1068
token := peek_token(parser)
1069
parser.marks = append(parser.marks, token.start_mark)
1070
skip_token(parser)
1071
}
1072
1073
token := peek_token(parser)
1074
if token == nil {
1075
return false
1076
}
1077
1078
if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1079
if !first {
1080
if token.typ == yaml_FLOW_ENTRY_TOKEN {
1081
skip_token(parser)
1082
token = peek_token(parser)
1083
if token == nil {
1084
return false
1085
}
1086
} else {
1087
context_mark := parser.marks[len(parser.marks)-1]
1088
parser.marks = parser.marks[:len(parser.marks)-1]
1089
return yaml_parser_set_parser_error_context(parser,
1090
"while parsing a flow mapping", context_mark,
1091
"did not find expected ',' or '}'", token.start_mark)
1092
}
1093
}
1094
1095
if token.typ == yaml_KEY_TOKEN {
1096
skip_token(parser)
1097
token = peek_token(parser)
1098
if token == nil {
1099
return false
1100
}
1101
if token.typ != yaml_VALUE_TOKEN &&
1102
token.typ != yaml_FLOW_ENTRY_TOKEN &&
1103
token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1104
parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)
1105
return yaml_parser_parse_node(parser, event, false, false)
1106
} else {
1107
parser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE
1108
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1109
}
1110
} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1111
parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)
1112
return yaml_parser_parse_node(parser, event, false, false)
1113
}
1114
}
1115
1116
parser.state = parser.states[len(parser.states)-1]
1117
parser.states = parser.states[:len(parser.states)-1]
1118
parser.marks = parser.marks[:len(parser.marks)-1]
1119
*event = yaml_event_t{
1120
typ: yaml_MAPPING_END_EVENT,
1121
start_mark: token.start_mark,
1122
end_mark: token.end_mark,
1123
}
1124
yaml_parser_set_event_comments(parser, event)
1125
skip_token(parser)
1126
return true
1127
}
1128
1129
// Parse the productions:
1130
// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1131
// * ***** *
1132
//
1133
func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {
1134
token := peek_token(parser)
1135
if token == nil {
1136
return false
1137
}
1138
if empty {
1139
parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
1140
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1141
}
1142
if token.typ == yaml_VALUE_TOKEN {
1143
skip_token(parser)
1144
token = peek_token(parser)
1145
if token == nil {
1146
return false
1147
}
1148
if token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {
1149
parser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)
1150
return yaml_parser_parse_node(parser, event, false, false)
1151
}
1152
}
1153
parser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE
1154
return yaml_parser_process_empty_scalar(parser, event, token.start_mark)
1155
}
1156
1157
// Generate an empty scalar event.
1158
func yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {
1159
*event = yaml_event_t{
1160
typ: yaml_SCALAR_EVENT,
1161
start_mark: mark,
1162
end_mark: mark,
1163
value: nil, // Empty
1164
implicit: true,
1165
style: yaml_style_t(yaml_PLAIN_SCALAR_STYLE),
1166
}
1167
return true
1168
}
1169
1170
var default_tag_directives = []yaml_tag_directive_t{
1171
{[]byte("!"), []byte("!")},
1172
{[]byte("!!"), []byte("tag:yaml.org,2002:")},
1173
}
1174
1175
// Parse directives.
1176
func yaml_parser_process_directives(parser *yaml_parser_t,
1177
version_directive_ref **yaml_version_directive_t,
1178
tag_directives_ref *[]yaml_tag_directive_t) bool {
1179
1180
var version_directive *yaml_version_directive_t
1181
var tag_directives []yaml_tag_directive_t
1182
1183
token := peek_token(parser)
1184
if token == nil {
1185
return false
1186
}
1187
1188
for token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1189
if token.typ == yaml_VERSION_DIRECTIVE_TOKEN {
1190
if version_directive != nil {
1191
yaml_parser_set_parser_error(parser,
1192
"found duplicate %YAML directive", token.start_mark)
1193
return false
1194
}
1195
if token.major != 1 || token.minor != 1 {
1196
yaml_parser_set_parser_error(parser,
1197
"found incompatible YAML document", token.start_mark)
1198
return false
1199
}
1200
version_directive = &yaml_version_directive_t{
1201
major: token.major,
1202
minor: token.minor,
1203
}
1204
} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {
1205
value := yaml_tag_directive_t{
1206
handle: token.value,
1207
prefix: token.prefix,
1208
}
1209
if !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {
1210
return false
1211
}
1212
tag_directives = append(tag_directives, value)
1213
}
1214
1215
skip_token(parser)
1216
token = peek_token(parser)
1217
if token == nil {
1218
return false
1219
}
1220
}
1221
1222
for i := range default_tag_directives {
1223
if !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {
1224
return false
1225
}
1226
}
1227
1228
if version_directive_ref != nil {
1229
*version_directive_ref = version_directive
1230
}
1231
if tag_directives_ref != nil {
1232
*tag_directives_ref = tag_directives
1233
}
1234
return true
1235
}
1236
1237
// Append a tag directive to the directives stack.
1238
func yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {
1239
for i := range parser.tag_directives {
1240
if bytes.Equal(value.handle, parser.tag_directives[i].handle) {
1241
if allow_duplicates {
1242
return true
1243
}
1244
return yaml_parser_set_parser_error(parser, "found duplicate %TAG directive", mark)
1245
}
1246
}
1247
1248
// [Go] I suspect the copy is unnecessary. This was likely done
1249
// because there was no way to track ownership of the data.
1250
value_copy := yaml_tag_directive_t{
1251
handle: make([]byte, len(value.handle)),
1252
prefix: make([]byte, len(value.prefix)),
1253
}
1254
copy(value_copy.handle, value.handle)
1255
copy(value_copy.prefix, value.prefix)
1256
parser.tag_directives = append(parser.tag_directives, value_copy)
1257
return true
1258
}
1259
1260