1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
package org.yaml.snakeyaml.parser; |
18 | |
|
19 | |
import java.util.ArrayList; |
20 | |
import java.util.HashMap; |
21 | |
import java.util.List; |
22 | |
import java.util.Map; |
23 | |
|
24 | |
import org.yaml.snakeyaml.error.Mark; |
25 | |
import org.yaml.snakeyaml.error.YAMLException; |
26 | |
import org.yaml.snakeyaml.events.AliasEvent; |
27 | |
import org.yaml.snakeyaml.events.DocumentEndEvent; |
28 | |
import org.yaml.snakeyaml.events.DocumentStartEvent; |
29 | |
import org.yaml.snakeyaml.events.Event; |
30 | |
import org.yaml.snakeyaml.events.ImplicitTuple; |
31 | |
import org.yaml.snakeyaml.events.MappingEndEvent; |
32 | |
import org.yaml.snakeyaml.events.MappingStartEvent; |
33 | |
import org.yaml.snakeyaml.events.ScalarEvent; |
34 | |
import org.yaml.snakeyaml.events.SequenceEndEvent; |
35 | |
import org.yaml.snakeyaml.events.SequenceStartEvent; |
36 | |
import org.yaml.snakeyaml.events.StreamEndEvent; |
37 | |
import org.yaml.snakeyaml.events.StreamStartEvent; |
38 | |
import org.yaml.snakeyaml.nodes.Tag; |
39 | |
import org.yaml.snakeyaml.reader.StreamReader; |
40 | |
import org.yaml.snakeyaml.scanner.Scanner; |
41 | |
import org.yaml.snakeyaml.scanner.ScannerImpl; |
42 | |
import org.yaml.snakeyaml.tokens.AliasToken; |
43 | |
import org.yaml.snakeyaml.tokens.AnchorToken; |
44 | |
import org.yaml.snakeyaml.tokens.BlockEntryToken; |
45 | |
import org.yaml.snakeyaml.tokens.DirectiveToken; |
46 | |
import org.yaml.snakeyaml.tokens.ScalarToken; |
47 | |
import org.yaml.snakeyaml.tokens.StreamEndToken; |
48 | |
import org.yaml.snakeyaml.tokens.StreamStartToken; |
49 | |
import org.yaml.snakeyaml.tokens.TagToken; |
50 | |
import org.yaml.snakeyaml.tokens.TagTuple; |
51 | |
import org.yaml.snakeyaml.tokens.Token; |
52 | |
import org.yaml.snakeyaml.util.ArrayStack; |
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
|
60 | |
|
61 | |
|
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | |
|
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
|
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
|
82 | |
|
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
|
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
|
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
|
102 | |
|
103 | |
|
104 | |
|
105 | |
|
106 | |
|
107 | |
|
108 | |
|
109 | |
|
110 | |
|
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
|
117 | 2323524 | public final class ParserImpl implements Parser { |
118 | 1 | private static final Map<String, String> DEFAULT_TAGS = new HashMap<String, String>(); |
119 | |
static { |
120 | 1 | DEFAULT_TAGS.put("!", "!"); |
121 | 1 | DEFAULT_TAGS.put("!!", Tag.PREFIX); |
122 | 1 | } |
123 | |
|
124 | |
private final Scanner scanner; |
125 | |
private Event currentEvent; |
126 | |
private List<Integer> yamlVersion; |
127 | |
private Map<String, String> tagHandles; |
128 | |
private final ArrayStack<Production> states; |
129 | |
private final ArrayStack<Mark> marks; |
130 | |
private Production state; |
131 | |
|
132 | 3572 | public ParserImpl(StreamReader reader) { |
133 | 3572 | this.scanner = new ScannerImpl(reader); |
134 | 3572 | currentEvent = null; |
135 | 3572 | yamlVersion = null; |
136 | 3572 | tagHandles = new HashMap<String, String>(); |
137 | 3572 | states = new ArrayStack<Production>(100); |
138 | 3572 | marks = new ArrayStack<Mark>(10); |
139 | 3572 | state = new ParseStreamStart(); |
140 | 3572 | } |
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
public boolean checkEvent(Event.ID choices) { |
146 | 1093613 | peekEvent(); |
147 | 1093500 | if (currentEvent != null) { |
148 | 1093500 | if (currentEvent.is(choices)) { |
149 | 398846 | return true; |
150 | |
} |
151 | |
} |
152 | 694654 | return false; |
153 | |
} |
154 | |
|
155 | |
|
156 | |
|
157 | |
|
158 | |
public Event peekEvent() { |
159 | 1962916 | if (currentEvent == null) { |
160 | 455447 | if (state != null) { |
161 | 452798 | currentEvent = state.produce(); |
162 | |
} |
163 | |
} |
164 | 1962803 | return currentEvent; |
165 | |
} |
166 | |
|
167 | |
|
168 | |
|
169 | |
|
170 | |
public Event getEvent() { |
171 | 452483 | peekEvent(); |
172 | 452483 | Event value = currentEvent; |
173 | 452483 | currentEvent = null; |
174 | 452483 | return value; |
175 | |
} |
176 | |
|
177 | |
|
178 | |
|
179 | |
|
180 | |
|
181 | |
|
182 | |
|
183 | |
|
184 | 7144 | private class ParseStreamStart implements Production { |
185 | |
public Event produce() { |
186 | |
|
187 | 3572 | StreamStartToken token = (StreamStartToken) scanner.getToken(); |
188 | 3572 | Event event = new StreamStartEvent(token.getStartMark(), token.getEndMark()); |
189 | |
|
190 | 3572 | state = new ParseImplicitDocumentStart(); |
191 | 3572 | return event; |
192 | |
} |
193 | |
} |
194 | |
|
195 | 7144 | private class ParseImplicitDocumentStart implements Production { |
196 | |
public Event produce() { |
197 | |
|
198 | 3572 | if (!scanner.checkToken(Token.ID.Directive, Token.ID.DocumentStart, Token.ID.StreamEnd)) { |
199 | 1707 | tagHandles = DEFAULT_TAGS; |
200 | 1707 | Token token = scanner.peekToken(); |
201 | 1707 | Mark startMark = token.getStartMark(); |
202 | 1707 | Mark endMark = startMark; |
203 | 1707 | Event event = new DocumentStartEvent(startMark, endMark, false, null, null); |
204 | |
|
205 | 1707 | states.push(new ParseDocumentEnd()); |
206 | 1707 | state = new ParseBlockNode(); |
207 | 1707 | return event; |
208 | |
} else { |
209 | 1825 | Production p = new ParseDocumentStart(); |
210 | 1825 | return p.produce(); |
211 | |
} |
212 | |
} |
213 | |
} |
214 | |
|
215 | 11494 | private class ParseDocumentStart implements Production { |
216 | |
@SuppressWarnings("unchecked") |
217 | |
public Event produce() { |
218 | |
|
219 | 5711 | while (scanner.checkToken(Token.ID.DocumentEnd)) { |
220 | 4 | scanner.getToken(); |
221 | |
} |
222 | |
|
223 | |
Event event; |
224 | 5707 | if (!scanner.checkToken(Token.ID.StreamEnd)) { |
225 | 2301 | Token token = scanner.peekToken(); |
226 | 2301 | Mark startMark = token.getStartMark(); |
227 | 2301 | List<Object> version_tags = processDirectives(); |
228 | 2295 | List<Object> version = (List<Object>) version_tags.get(0); |
229 | 2295 | Map<String, String> tags = (Map<String, String>) version_tags.get(1); |
230 | 2295 | if (!scanner.checkToken(Token.ID.DocumentStart)) { |
231 | 6 | throw new ParserException(null, null, "expected '<document start>', but found " |
232 | |
+ scanner.peekToken().getTokenId(), scanner.peekToken().getStartMark()); |
233 | |
} |
234 | 2289 | token = scanner.getToken(); |
235 | 2289 | Mark endMark = token.getEndMark(); |
236 | |
Integer[] versionInteger; |
237 | 2289 | if (version != null) { |
238 | 1615 | versionInteger = new Integer[2]; |
239 | 1615 | versionInteger = version.toArray(versionInteger); |
240 | |
} else { |
241 | 674 | versionInteger = null; |
242 | |
} |
243 | 2289 | event = new DocumentStartEvent(startMark, endMark, true, versionInteger, tags); |
244 | 2289 | states.push(new ParseDocumentEnd()); |
245 | 2289 | state = new ParseDocumentContent(); |
246 | 2289 | } else { |
247 | |
|
248 | 3406 | StreamEndToken token = (StreamEndToken) scanner.getToken(); |
249 | 3406 | event = new StreamEndEvent(token.getStartMark(), token.getEndMark()); |
250 | 3406 | if (!states.isEmpty()) { |
251 | 0 | throw new YAMLException("Unexpected end of stream. States left: " + states); |
252 | |
} |
253 | 3406 | if (!marks.isEmpty()) { |
254 | 0 | throw new YAMLException("Unexpected end of stream. Marks left: " + marks); |
255 | |
} |
256 | 3406 | state = null; |
257 | |
} |
258 | 5695 | return event; |
259 | |
} |
260 | |
} |
261 | |
|
262 | 7992 | private class ParseDocumentEnd implements Production { |
263 | |
public Event produce() { |
264 | |
|
265 | 3922 | Token token = scanner.peekToken(); |
266 | 3922 | Mark startMark = token.getStartMark(); |
267 | 3922 | Mark endMark = startMark; |
268 | 3922 | boolean explicit = false; |
269 | 3922 | if (scanner.checkToken(Token.ID.DocumentEnd)) { |
270 | 122 | token = scanner.getToken(); |
271 | 122 | endMark = token.getEndMark(); |
272 | 122 | explicit = true; |
273 | |
} |
274 | 3922 | Event event = new DocumentEndEvent(startMark, endMark, explicit); |
275 | |
|
276 | 3922 | state = new ParseDocumentStart(); |
277 | 3922 | return event; |
278 | |
} |
279 | |
} |
280 | |
|
281 | 4578 | private class ParseDocumentContent implements Production { |
282 | |
public Event produce() { |
283 | |
Event event; |
284 | 2284 | if (scanner.checkToken(Token.ID.Directive, Token.ID.DocumentStart, |
285 | |
Token.ID.DocumentEnd, Token.ID.StreamEnd)) { |
286 | 21 | event = processEmptyScalar(scanner.peekToken().getStartMark()); |
287 | 21 | state = states.pop(); |
288 | 21 | return event; |
289 | |
} else { |
290 | 2245 | Production p = new ParseBlockNode(); |
291 | 2245 | return p.produce(); |
292 | |
} |
293 | |
} |
294 | |
} |
295 | |
|
296 | |
@SuppressWarnings("unchecked") |
297 | |
private List<Object> processDirectives() { |
298 | 2301 | yamlVersion = null; |
299 | 2301 | tagHandles = new HashMap<String, String>(); |
300 | 4065 | while (scanner.checkToken(Token.ID.Directive)) { |
301 | |
@SuppressWarnings("rawtypes") |
302 | 1770 | DirectiveToken token = (DirectiveToken) scanner.getToken(); |
303 | 1770 | if (token.getName().equals("YAML")) { |
304 | 1623 | if (yamlVersion != null) { |
305 | 2 | throw new ParserException(null, null, "found duplicate YAML directive", |
306 | |
token.getStartMark()); |
307 | |
} |
308 | 1621 | List<Integer> value = (List<Integer>) token.getValue(); |
309 | 1621 | Integer major = value.get(0); |
310 | 1621 | if (major != 1) { |
311 | 2 | throw new ParserException(null, null, |
312 | |
"found incompatible YAML document (version 1.* is required)", |
313 | |
token.getStartMark()); |
314 | |
} |
315 | 1619 | yamlVersion = (List<Integer>) token.getValue(); |
316 | 1619 | } else if (token.getName().equals("TAG")) { |
317 | 143 | List<String> value = (List<String>) token.getValue(); |
318 | 143 | String handle = value.get(0); |
319 | 143 | String prefix = value.get(1); |
320 | 143 | if (tagHandles.containsKey(handle)) { |
321 | 2 | throw new ParserException(null, null, "duplicate tag handle " + handle, |
322 | |
token.getStartMark()); |
323 | |
} |
324 | 141 | tagHandles.put(handle, prefix); |
325 | |
} |
326 | 1764 | } |
327 | 2295 | List<Object> value = new ArrayList<Object>(2); |
328 | 2295 | value.add(yamlVersion); |
329 | 2295 | if (!tagHandles.isEmpty()) { |
330 | 92 | value.add(new HashMap<String, String>(tagHandles)); |
331 | |
} else { |
332 | 2203 | value.add(new HashMap<String, String>()); |
333 | |
} |
334 | 2295 | for (String key : DEFAULT_TAGS.keySet()) { |
335 | 4590 | if (!tagHandles.containsKey(key)) { |
336 | 4513 | tagHandles.put(key, DEFAULT_TAGS.get(key)); |
337 | |
} |
338 | |
} |
339 | 2295 | return value; |
340 | |
} |
341 | |
|
342 | |
|
343 | |
|
344 | |
|
345 | |
|
346 | |
|
347 | |
|
348 | |
|
349 | |
|
350 | |
|
351 | |
|
352 | |
|
353 | |
|
354 | |
|
355 | |
|
356 | |
|
357 | |
|
358 | |
|
359 | |
|
360 | |
|
361 | |
|
362 | 236932 | private class ParseBlockNode implements Production { |
363 | |
public Event produce() { |
364 | 118464 | return parseNode(true, false); |
365 | |
} |
366 | |
} |
367 | |
|
368 | |
private Event parseFlowNode() { |
369 | 10995 | return parseNode(false, false); |
370 | |
} |
371 | |
|
372 | |
private Event parseBlockNodeOrIndentlessSequence() { |
373 | 270836 | return parseNode(true, true); |
374 | |
} |
375 | |
|
376 | |
private Event parseNode(boolean block, boolean indentlessSequence) { |
377 | |
Event event; |
378 | 400295 | Mark startMark = null; |
379 | 400295 | Mark endMark = null; |
380 | 400295 | Mark tagMark = null; |
381 | 400295 | if (scanner.checkToken(Token.ID.Alias)) { |
382 | 1414 | AliasToken token = (AliasToken) scanner.getToken(); |
383 | 1414 | event = new AliasEvent(token.getValue(), token.getStartMark(), token.getEndMark()); |
384 | 1414 | state = states.pop(); |
385 | 1414 | } else { |
386 | 398881 | String anchor = null; |
387 | 398881 | TagTuple tagTokenTag = null; |
388 | 398881 | if (scanner.checkToken(Token.ID.Anchor)) { |
389 | 1349 | AnchorToken token = (AnchorToken) scanner.getToken(); |
390 | 1349 | startMark = token.getStartMark(); |
391 | 1349 | endMark = token.getEndMark(); |
392 | 1349 | anchor = token.getValue(); |
393 | 1349 | if (scanner.checkToken(Token.ID.Tag)) { |
394 | 1242 | TagToken tagToken = (TagToken) scanner.getToken(); |
395 | 1242 | tagMark = tagToken.getStartMark(); |
396 | 1242 | endMark = tagToken.getEndMark(); |
397 | 1242 | tagTokenTag = tagToken.getValue(); |
398 | |
} |
399 | 1349 | } else if (scanner.checkToken(Token.ID.Tag)) { |
400 | 10866 | TagToken tagToken = (TagToken) scanner.getToken(); |
401 | 10866 | startMark = tagToken.getStartMark(); |
402 | 10866 | tagMark = startMark; |
403 | 10866 | endMark = tagToken.getEndMark(); |
404 | 10866 | tagTokenTag = tagToken.getValue(); |
405 | 10866 | if (scanner.checkToken(Token.ID.Anchor)) { |
406 | 10 | AnchorToken token = (AnchorToken) scanner.getToken(); |
407 | 10 | endMark = token.getEndMark(); |
408 | 10 | anchor = token.getValue(); |
409 | |
} |
410 | |
} |
411 | 398881 | String tag = null; |
412 | 398881 | if (tagTokenTag != null) { |
413 | 12108 | String handle = tagTokenTag.getHandle(); |
414 | 12108 | String suffix = tagTokenTag.getSuffix(); |
415 | 12108 | if (handle != null) { |
416 | 9931 | if (!tagHandles.containsKey(handle)) { |
417 | 2 | throw new ParserException("while parsing a node", startMark, |
418 | |
"found undefined tag handle " + handle, tagMark); |
419 | |
} |
420 | 9929 | tag = tagHandles.get(handle) + suffix; |
421 | |
} else { |
422 | 2177 | tag = suffix; |
423 | |
} |
424 | |
} |
425 | 398879 | if (startMark == null) { |
426 | 386666 | startMark = scanner.peekToken().getStartMark(); |
427 | 386666 | endMark = startMark; |
428 | |
} |
429 | 398879 | event = null; |
430 | 398879 | boolean implicit = (tag == null || tag.equals("!")); |
431 | 398879 | if (indentlessSequence && scanner.checkToken(Token.ID.BlockEntry)) { |
432 | 10368 | endMark = scanner.peekToken().getEndMark(); |
433 | 10368 | event = new SequenceStartEvent(anchor, tag, implicit, startMark, endMark, |
434 | |
Boolean.FALSE); |
435 | 10368 | state = new ParseIndentlessSequenceEntry(); |
436 | |
} else { |
437 | 388511 | if (scanner.checkToken(Token.ID.Scalar)) { |
438 | 361428 | ScalarToken token = (ScalarToken) scanner.getToken(); |
439 | 361428 | endMark = token.getEndMark(); |
440 | |
ImplicitTuple implicitValues; |
441 | 361428 | if ((token.getPlain() && tag == null) || "!".equals(tag)) { |
442 | 153001 | implicitValues = new ImplicitTuple(true, false); |
443 | 208427 | } else if (tag == null) { |
444 | 202487 | implicitValues = new ImplicitTuple(false, true); |
445 | |
} else { |
446 | 5940 | implicitValues = new ImplicitTuple(false, false); |
447 | |
} |
448 | 361428 | event = new ScalarEvent(anchor, tag, implicitValues, token.getValue(), |
449 | |
startMark, endMark, token.getStyle()); |
450 | 361428 | state = states.pop(); |
451 | 361428 | } else if (scanner.checkToken(Token.ID.FlowSequenceStart)) { |
452 | 1074 | endMark = scanner.peekToken().getEndMark(); |
453 | 1074 | event = new SequenceStartEvent(anchor, tag, implicit, startMark, endMark, |
454 | |
Boolean.TRUE); |
455 | 1074 | state = new ParseFlowSequenceFirstEntry(); |
456 | 26009 | } else if (scanner.checkToken(Token.ID.FlowMappingStart)) { |
457 | 2768 | endMark = scanner.peekToken().getEndMark(); |
458 | 2768 | event = new MappingStartEvent(anchor, tag, implicit, startMark, endMark, |
459 | |
Boolean.TRUE); |
460 | 2768 | state = new ParseFlowMappingFirstKey(); |
461 | 23241 | } else if (block && scanner.checkToken(Token.ID.BlockSequenceStart)) { |
462 | 562 | endMark = scanner.peekToken().getStartMark(); |
463 | 562 | event = new SequenceStartEvent(anchor, tag, implicit, startMark, endMark, |
464 | |
Boolean.FALSE); |
465 | 562 | state = new ParseBlockSequenceFirstEntry(); |
466 | 22679 | } else if (block && scanner.checkToken(Token.ID.BlockMappingStart)) { |
467 | 22507 | endMark = scanner.peekToken().getStartMark(); |
468 | 22507 | event = new MappingStartEvent(anchor, tag, implicit, startMark, endMark, |
469 | |
Boolean.FALSE); |
470 | 22507 | state = new ParseBlockMappingFirstKey(); |
471 | 172 | } else if (anchor != null || tag != null) { |
472 | |
|
473 | |
|
474 | 168 | event = new ScalarEvent(anchor, tag, new ImplicitTuple(implicit, false), "", |
475 | |
startMark, endMark, (char) 0); |
476 | 168 | state = states.pop(); |
477 | |
} else { |
478 | |
String node; |
479 | 4 | if (block) { |
480 | 0 | node = "block"; |
481 | |
} else { |
482 | 4 | node = "flow"; |
483 | |
} |
484 | 4 | Token token = scanner.peekToken(); |
485 | 4 | throw new ParserException("while parsing a " + node + " node", startMark, |
486 | |
"expected the node content, but found " + token.getTokenId(), |
487 | |
token.getStartMark()); |
488 | |
} |
489 | |
} |
490 | |
} |
491 | 400289 | return event; |
492 | |
} |
493 | |
|
494 | |
|
495 | |
|
496 | |
|
497 | 1124 | private class ParseBlockSequenceFirstEntry implements Production { |
498 | |
public Event produce() { |
499 | 562 | Token token = scanner.getToken(); |
500 | 562 | marks.push(token.getStartMark()); |
501 | 562 | return new ParseBlockSequenceEntry().produce(); |
502 | |
} |
503 | |
} |
504 | |
|
505 | 14878 | private class ParseBlockSequenceEntry implements Production { |
506 | |
public Event produce() { |
507 | 14308 | if (scanner.checkToken(Token.ID.BlockEntry)) { |
508 | 13762 | BlockEntryToken token = (BlockEntryToken) scanner.getToken(); |
509 | 13762 | if (!scanner.checkToken(Token.ID.BlockEntry, Token.ID.BlockEnd)) { |
510 | 13743 | states.push(new ParseBlockSequenceEntry()); |
511 | 13743 | return new ParseBlockNode().produce(); |
512 | |
} else { |
513 | 11 | state = new ParseBlockSequenceEntry(); |
514 | 11 | return processEmptyScalar(token.getEndMark()); |
515 | |
} |
516 | |
} |
517 | 546 | if (!scanner.checkToken(Token.ID.BlockEnd)) { |
518 | 4 | Token token = scanner.peekToken(); |
519 | 4 | throw new ParserException("while parsing a block collection", marks.pop(), |
520 | |
"expected <block end>, but found " + token.getTokenId(), |
521 | |
token.getStartMark()); |
522 | |
} |
523 | 542 | Token token = scanner.getToken(); |
524 | 542 | Event event = new SequenceEndEvent(token.getStartMark(), token.getEndMark()); |
525 | 542 | state = states.pop(); |
526 | 542 | marks.pop(); |
527 | 542 | return event; |
528 | |
} |
529 | |
} |
530 | |
|
531 | |
|
532 | |
|
533 | 121507 | private class ParseIndentlessSequenceEntry implements Production { |
534 | |
public Event produce() { |
535 | 111139 | if (scanner.checkToken(Token.ID.BlockEntry)) { |
536 | 100771 | Token token = scanner.getToken(); |
537 | 100771 | if (!scanner.checkToken(Token.ID.BlockEntry, Token.ID.Key, Token.ID.Value, |
538 | |
Token.ID.BlockEnd)) { |
539 | 100771 | states.push(new ParseIndentlessSequenceEntry()); |
540 | 100771 | return new ParseBlockNode().produce(); |
541 | |
} else { |
542 | 0 | state = new ParseIndentlessSequenceEntry(); |
543 | 0 | return processEmptyScalar(token.getEndMark()); |
544 | |
} |
545 | |
} |
546 | 10368 | Token token = scanner.peekToken(); |
547 | 10368 | Event event = new SequenceEndEvent(token.getStartMark(), token.getEndMark()); |
548 | 10368 | state = states.pop(); |
549 | 10368 | return event; |
550 | |
} |
551 | |
} |
552 | |
|
553 | 45014 | private class ParseBlockMappingFirstKey implements Production { |
554 | |
public Event produce() { |
555 | 22507 | Token token = scanner.getToken(); |
556 | 22507 | marks.push(token.getStartMark()); |
557 | 22507 | return new ParseBlockMappingKey().produce(); |
558 | |
} |
559 | |
} |
560 | |
|
561 | 315952 | private class ParseBlockMappingKey implements Production { |
562 | |
public Event produce() { |
563 | 157973 | if (scanner.checkToken(Token.ID.Key)) { |
564 | 135473 | Token token = scanner.getToken(); |
565 | 135473 | if (!scanner.checkToken(Token.ID.Key, Token.ID.Value, Token.ID.BlockEnd)) { |
566 | 135466 | states.push(new ParseBlockMappingValue()); |
567 | 135466 | return parseBlockNodeOrIndentlessSequence(); |
568 | |
} else { |
569 | 7 | state = new ParseBlockMappingValue(); |
570 | 7 | return processEmptyScalar(token.getEndMark()); |
571 | |
} |
572 | |
} |
573 | 22494 | if (!scanner.checkToken(Token.ID.BlockEnd)) { |
574 | 6 | Token token = scanner.peekToken(); |
575 | 6 | throw new ParserException("while parsing a block mapping", marks.pop(), |
576 | |
"expected <block end>, but found " + token.getTokenId(), |
577 | |
token.getStartMark()); |
578 | |
} |
579 | 22488 | Token token = scanner.getToken(); |
580 | 22488 | Event event = new MappingEndEvent(token.getStartMark(), token.getEndMark()); |
581 | 22488 | state = states.pop(); |
582 | 22488 | marks.pop(); |
583 | 22488 | return event; |
584 | |
} |
585 | |
} |
586 | |
|
587 | 270946 | private class ParseBlockMappingValue implements Production { |
588 | |
public Event produce() { |
589 | 135473 | if (scanner.checkToken(Token.ID.Value)) { |
590 | 135457 | Token token = scanner.getToken(); |
591 | 135457 | if (!scanner.checkToken(Token.ID.Key, Token.ID.Value, Token.ID.BlockEnd)) { |
592 | 135370 | states.push(new ParseBlockMappingKey()); |
593 | 135370 | return parseBlockNodeOrIndentlessSequence(); |
594 | |
} else { |
595 | 83 | state = new ParseBlockMappingKey(); |
596 | 83 | return processEmptyScalar(token.getEndMark()); |
597 | |
} |
598 | |
} |
599 | 16 | state = new ParseBlockMappingKey(); |
600 | 16 | Token token = scanner.peekToken(); |
601 | 16 | return processEmptyScalar(token.getStartMark()); |
602 | |
} |
603 | |
} |
604 | |
|
605 | |
|
606 | |
|
607 | |
|
608 | |
|
609 | |
|
610 | |
|
611 | |
|
612 | |
|
613 | |
|
614 | |
|
615 | |
|
616 | |
|
617 | |
|
618 | 2148 | private class ParseFlowSequenceFirstEntry implements Production { |
619 | |
public Event produce() { |
620 | 1074 | Token token = scanner.getToken(); |
621 | 1074 | marks.push(token.getStartMark()); |
622 | 1074 | return new ParseFlowSequenceEntry(true).produce(); |
623 | |
} |
624 | |
} |
625 | |
|
626 | |
private class ParseFlowSequenceEntry implements Production { |
627 | 3714 | private boolean first = false; |
628 | |
|
629 | 3714 | public ParseFlowSequenceEntry(boolean first) { |
630 | 3714 | this.first = first; |
631 | 3714 | } |
632 | |
|
633 | |
public Event produce() { |
634 | 3707 | if (!scanner.checkToken(Token.ID.FlowSequenceEnd)) { |
635 | 2786 | if (!first) { |
636 | 1883 | if (scanner.checkToken(Token.ID.FlowEntry)) { |
637 | 1877 | scanner.getToken(); |
638 | |
} else { |
639 | 6 | Token token = scanner.peekToken(); |
640 | 6 | throw new ParserException("while parsing a flow sequence", marks.pop(), |
641 | |
"expected ',' or ']', but got " + token.getTokenId(), |
642 | |
token.getStartMark()); |
643 | |
} |
644 | |
} |
645 | 2780 | if (scanner.checkToken(Token.ID.Key)) { |
646 | 41 | Token token = scanner.peekToken(); |
647 | 41 | Event event = new MappingStartEvent(null, null, true, token.getStartMark(), |
648 | |
token.getEndMark(), Boolean.TRUE); |
649 | 41 | state = new ParseFlowSequenceEntryMappingKey(); |
650 | 41 | return event; |
651 | 2739 | } else if (!scanner.checkToken(Token.ID.FlowSequenceEnd)) { |
652 | 2599 | states.push(new ParseFlowSequenceEntry(false)); |
653 | 2599 | return parseFlowNode(); |
654 | |
} |
655 | |
} |
656 | 1061 | Token token = scanner.getToken(); |
657 | 1061 | Event event = new SequenceEndEvent(token.getStartMark(), token.getEndMark()); |
658 | 1061 | state = states.pop(); |
659 | 1061 | marks.pop(); |
660 | 1061 | return event; |
661 | |
} |
662 | |
} |
663 | |
|
664 | 82 | private class ParseFlowSequenceEntryMappingKey implements Production { |
665 | |
public Event produce() { |
666 | 41 | Token token = scanner.getToken(); |
667 | 41 | if (!scanner.checkToken(Token.ID.Value, Token.ID.FlowEntry, Token.ID.FlowSequenceEnd)) { |
668 | 41 | states.push(new ParseFlowSequenceEntryMappingValue()); |
669 | 41 | return parseFlowNode(); |
670 | |
} else { |
671 | 0 | state = new ParseFlowSequenceEntryMappingValue(); |
672 | 0 | return processEmptyScalar(token.getEndMark()); |
673 | |
} |
674 | |
} |
675 | |
} |
676 | |
|
677 | 82 | private class ParseFlowSequenceEntryMappingValue implements Production { |
678 | |
public Event produce() { |
679 | 41 | if (scanner.checkToken(Token.ID.Value)) { |
680 | 37 | Token token = scanner.getToken(); |
681 | 37 | if (!scanner.checkToken(Token.ID.FlowEntry, Token.ID.FlowSequenceEnd)) { |
682 | 29 | states.push(new ParseFlowSequenceEntryMappingEnd()); |
683 | 29 | return parseFlowNode(); |
684 | |
} else { |
685 | 8 | state = new ParseFlowSequenceEntryMappingEnd(); |
686 | 8 | return processEmptyScalar(token.getEndMark()); |
687 | |
} |
688 | |
} else { |
689 | 4 | state = new ParseFlowSequenceEntryMappingEnd(); |
690 | 4 | Token token = scanner.peekToken(); |
691 | 4 | return processEmptyScalar(token.getStartMark()); |
692 | |
} |
693 | |
} |
694 | |
} |
695 | |
|
696 | 82 | private class ParseFlowSequenceEntryMappingEnd implements Production { |
697 | |
public Event produce() { |
698 | 41 | state = new ParseFlowSequenceEntry(false); |
699 | 41 | Token token = scanner.peekToken(); |
700 | 41 | return new MappingEndEvent(token.getStartMark(), token.getEndMark()); |
701 | |
} |
702 | |
} |
703 | |
|
704 | |
|
705 | |
|
706 | |
|
707 | |
|
708 | |
|
709 | |
|
710 | |
|
711 | |
|
712 | |
|
713 | 5536 | private class ParseFlowMappingFirstKey implements Production { |
714 | |
public Event produce() { |
715 | 2768 | Token token = scanner.getToken(); |
716 | 2768 | marks.push(token.getStartMark()); |
717 | 2768 | return new ParseFlowMappingKey(true).produce(); |
718 | |
} |
719 | |
} |
720 | |
|
721 | |
private class ParseFlowMappingKey implements Production { |
722 | 6953 | private boolean first = false; |
723 | |
|
724 | 6953 | public ParseFlowMappingKey(boolean first) { |
725 | 6953 | this.first = first; |
726 | 6953 | } |
727 | |
|
728 | |
public Event produce() { |
729 | 6953 | if (!scanner.checkToken(Token.ID.FlowMappingEnd)) { |
730 | 4352 | if (!first) { |
731 | 1632 | if (scanner.checkToken(Token.ID.FlowEntry)) { |
732 | 1629 | scanner.getToken(); |
733 | |
} else { |
734 | 3 | Token token = scanner.peekToken(); |
735 | 3 | throw new ParserException("while parsing a flow mapping", marks.pop(), |
736 | |
"expected ',' or '}', but got " + token.getTokenId(), |
737 | |
token.getStartMark()); |
738 | |
} |
739 | |
} |
740 | 4349 | if (scanner.checkToken(Token.ID.Key)) { |
741 | 4168 | Token token = scanner.getToken(); |
742 | 4168 | if (!scanner.checkToken(Token.ID.Value, Token.ID.FlowEntry, |
743 | |
Token.ID.FlowMappingEnd)) { |
744 | 4160 | states.push(new ParseFlowMappingValue()); |
745 | 4160 | return parseFlowNode(); |
746 | |
} else { |
747 | 8 | state = new ParseFlowMappingValue(); |
748 | 8 | return processEmptyScalar(token.getEndMark()); |
749 | |
} |
750 | 181 | } else if (!scanner.checkToken(Token.ID.FlowMappingEnd)) { |
751 | 18 | states.push(new ParseFlowMappingEmptyValue()); |
752 | 18 | return parseFlowNode(); |
753 | |
} |
754 | |
} |
755 | 2764 | Token token = scanner.getToken(); |
756 | 2764 | Event event = new MappingEndEvent(token.getStartMark(), token.getEndMark()); |
757 | 2764 | state = states.pop(); |
758 | 2764 | marks.pop(); |
759 | 2764 | return event; |
760 | |
} |
761 | |
} |
762 | |
|
763 | 8336 | private class ParseFlowMappingValue implements Production { |
764 | |
public Event produce() { |
765 | 4168 | if (scanner.checkToken(Token.ID.Value)) { |
766 | 4164 | Token token = scanner.getToken(); |
767 | 4164 | if (!scanner.checkToken(Token.ID.FlowEntry, Token.ID.FlowMappingEnd)) { |
768 | 4148 | states.push(new ParseFlowMappingKey(false)); |
769 | 4148 | return parseFlowNode(); |
770 | |
} else { |
771 | 16 | state = new ParseFlowMappingKey(false); |
772 | 16 | return processEmptyScalar(token.getEndMark()); |
773 | |
} |
774 | |
} else { |
775 | 4 | state = new ParseFlowMappingKey(false); |
776 | 4 | Token token = scanner.peekToken(); |
777 | 4 | return processEmptyScalar(token.getStartMark()); |
778 | |
} |
779 | |
} |
780 | |
} |
781 | |
|
782 | 36 | private class ParseFlowMappingEmptyValue implements Production { |
783 | |
public Event produce() { |
784 | 17 | state = new ParseFlowMappingKey(false); |
785 | 17 | return processEmptyScalar(scanner.peekToken().getStartMark()); |
786 | |
} |
787 | |
} |
788 | |
|
789 | |
|
790 | |
|
791 | |
|
792 | |
|
793 | |
|
794 | |
|
795 | |
|
796 | |
|
797 | |
private Event processEmptyScalar(Mark mark) { |
798 | 195 | return new ScalarEvent(null, null, new ImplicitTuple(true, false), "", mark, mark, (char) 0); |
799 | |
} |
800 | |
} |