1 |
yakumo_izuru |
1.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 |
|
|
} |