Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: pkg/yaml/lib/src/parser.dart

Issue 14103026: Restructure the yaml package. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/yaml/lib/src/model.dart ('k') | pkg/yaml/lib/src/utils.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of yaml; 5 library parser;
6
7 import 'dart:collection';
8
9 import 'model.dart';
10 import 'yaml_exception.dart';
11 import 'yaml_map.dart';
6 12
7 /// Translates a string of characters into a YAML serialization tree. 13 /// Translates a string of characters into a YAML serialization tree.
8 /// 14 ///
9 /// This parser is designed to closely follow the spec. All productions in the 15 /// This parser is designed to closely follow the spec. All productions in the
10 /// spec are numbered, and the corresponding methods in the parser have the same 16 /// spec are numbered, and the corresponding methods in the parser have the same
11 /// numbers. This is certainly not the most efficient way of parsing YAML, but 17 /// numbers. This is certainly not the most efficient way of parsing YAML, but
12 /// it is the easiest to write and read in the context of the spec. 18 /// it is the easiest to write and read in the context of the spec.
13 /// 19 ///
14 /// Methods corresponding to productions are also named as in the spec, 20 /// Methods corresponding to productions are also named as in the spec,
15 /// translating the name of the method (although not the annotation characters) 21 /// translating the name of the method (although not the annotation characters)
16 /// into camel-case for dart style.. For example, the spec has a production 22 /// into camel-case for dart style.. For example, the spec has a production
17 /// named `nb-ns-plain-in-line`, and the method implementing it is named 23 /// named `nb-ns-plain-in-line`, and the method implementing it is named
18 /// `nb_ns_plainInLine`. The exception to that rule is methods that just 24 /// `nb_ns_plainInLine`. The exception to that rule is methods that just
19 /// recognize character classes; these are named `is*`. 25 /// recognize character classes; these are named `is*`.
20 class _Parser { 26 class Parser {
21 static const TAB = 0x9; 27 static const TAB = 0x9;
22 static const LF = 0xA; 28 static const LF = 0xA;
23 static const CR = 0xD; 29 static const CR = 0xD;
24 static const SP = 0x20; 30 static const SP = 0x20;
25 static const TILDE = 0x7E; 31 static const TILDE = 0x7E;
26 static const NEL = 0x85; 32 static const NEL = 0x85;
27 static const PLUS = 0x2B; 33 static const PLUS = 0x2B;
28 static const HYPHEN = 0x2D; 34 static const HYPHEN = 0x2D;
29 static const QUESTION_MARK = 0x3F; 35 static const QUESTION_MARK = 0x3F;
30 static const COLON = 0x3A; 36 static const COLON = 0x3A;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 static const FLOW_OUT = 2; 110 static const FLOW_OUT = 2;
105 static const FLOW_IN = 3; 111 static const FLOW_IN = 3;
106 static const BLOCK_KEY = 4; 112 static const BLOCK_KEY = 4;
107 static const FLOW_KEY = 5; 113 static const FLOW_KEY = 5;
108 114
109 static const CHOMPING_STRIP = 0; 115 static const CHOMPING_STRIP = 0;
110 static const CHOMPING_KEEP = 1; 116 static const CHOMPING_KEEP = 1;
111 static const CHOMPING_CLIP = 2; 117 static const CHOMPING_CLIP = 2;
112 118
113 /// The source string being parsed. 119 /// The source string being parsed.
114 final String s; 120 final String _s;
115 121
116 /// The current position in the source string. 122 /// The current position in the source string.
117 int pos = 0; 123 int _pos = 0;
118 124
119 /// The length of the string being parsed. 125 /// The length of the string being parsed.
120 final int len; 126 final int _len;
121 127
122 /// The current (0-based) line in the source string. 128 /// The current (0-based) line in the source string.
123 int line = 0; 129 int _line = 0;
124 130
125 /// The current (0-based) column in the source string. 131 /// The current (0-based) column in the source string.
126 int column = 0; 132 int _column = 0;
127 133
128 /// Whether we're parsing a bare document (that is, one that doesn't begin 134 /// Whether we're parsing a bare document (that is, one that doesn't begin
129 /// with `---`). Bare documents don't allow `%` immediately following 135 /// with `---`). Bare documents don't allow `%` immediately following
130 /// newlines. 136 /// newlines.
131 bool inBareDocument = false; 137 bool _inBareDocument = false;
132 138
133 /// The line number of the farthest position that has been parsed successfully 139 /// The line number of the farthest position that has been parsed successfully
134 /// before backtracking. Used for error reporting. 140 /// before backtracking. Used for error reporting.
135 int farthestLine = 0; 141 int _farthestLine = 0;
136 142
137 /// The column number of the farthest position that has been parsed 143 /// The column number of the farthest position that has been parsed
138 /// successfully before backtracking. Used for error reporting. 144 /// successfully before backtracking. Used for error reporting.
139 int farthestColumn = 0; 145 int _farthestColumn = 0;
140 146
141 /// The farthest position in the source string that has been parsed 147 /// The farthest position in the source string that has been parsed
142 /// successfully before backtracking. Used for error reporting. 148 /// successfully before backtracking. Used for error reporting.
143 int farthestPos = 0; 149 int _farthestPos = 0;
144 150
145 /// The name of the context of the farthest position that has been parsed 151 /// The name of the context of the farthest position that has been parsed
146 /// successfully before backtracking. Used for error reporting. 152 /// successfully before backtracking. Used for error reporting.
147 String farthestContext = "document"; 153 String _farthestContext = "document";
148 154
149 /// A stack of the names of parse contexts. Used for error reporting. 155 /// A stack of the names of parse contexts. Used for error reporting.
150 List<String> contextStack; 156 List<String> _contextStack;
151 157
152 /// Annotations attached to ranges of the source string that add extra 158 /// Annotations attached to ranges of the source string that add extra
153 /// information to any errors that occur in the annotated range. 159 /// information to any errors that occur in the annotated range.
154 _RangeMap<String> errorAnnotations; 160 _RangeMap<String> _errorAnnotations;
155 161
156 /// The buffer containing the string currently being captured. 162 /// The buffer containing the string currently being captured.
157 StringBuffer capturedString; 163 StringBuffer _capturedString;
158 164
159 /// The beginning of the current section of the captured string. 165 /// The beginning of the current section of the captured string.
160 int captureStart; 166 int _captureStart;
161 167
162 /// Whether the current string capture is being overridden. 168 /// Whether the current string capture is being overridden.
163 bool capturingAs = false; 169 bool _capturingAs = false;
164 170
165 _Parser(String s) 171 Parser(String s)
166 : this.s = s, 172 : this._s = s,
167 len = s.length, 173 _len = s.length,
168 contextStack = <String>["document"], 174 _contextStack = <String>["document"],
169 errorAnnotations = new _RangeMap(); 175 _errorAnnotations = new _RangeMap();
170 176
171 /// Return the character at the current position, then move that position 177 /// Return the character at the current position, then move that position
172 /// forward one character. Also updates the current line and column numbers. 178 /// forward one character. Also updates the current line and column numbers.
173 int next() { 179 int next() {
174 if (pos == len) return -1; 180 if (_pos == _len) return -1;
175 var char = s.codeUnitAt(pos++); 181 var char = _s.codeUnitAt(_pos++);
176 if (isBreak(char)) { 182 if (isBreak(char)) {
177 line++; 183 _line++;
178 column = 0; 184 _column = 0;
179 } else { 185 } else {
180 column++; 186 _column++;
181 } 187 }
182 188
183 if (farthestLine < line) { 189 if (_farthestLine < _line) {
184 farthestLine = line; 190 _farthestLine = _line;
185 farthestColumn = column; 191 _farthestColumn = _column;
186 farthestContext = contextStack.last; 192 _farthestContext = _contextStack.last;
187 } else if (farthestLine == line && farthestColumn < column) { 193 } else if (_farthestLine == _line && _farthestColumn < _column) {
188 farthestColumn = column; 194 _farthestColumn = _column;
189 farthestContext = contextStack.last; 195 _farthestContext = _contextStack.last;
190 } 196 }
191 farthestPos = pos; 197 _farthestPos = _pos;
192 198
193 return char; 199 return char;
194 } 200 }
195 201
196 /// Returns the code unit at the current position, or the character [i] 202 /// Returns the code unit at the current position, or the character [i]
197 /// characters after the current position. 203 /// characters after the current position.
198 /// 204 ///
199 /// Returns -1 if this would return a character after the end or before the 205 /// Returns -1 if this would return a character after the end or before the
200 /// beginning of the input string. 206 /// beginning of the input string.
201 int peek([int i = 0]) { 207 int peek([int i = 0]) {
202 var peekPos = pos + i; 208 var peekPos = _pos + i;
203 return (peekPos >= len || peekPos < 0) ? -1 : s.codeUnitAt(peekPos); 209 return (peekPos >= _len || peekPos < 0) ? -1 : _s.codeUnitAt(peekPos);
204 } 210 }
205 211
206 /// The truthiness operator. Returns `false` if [obj] is `null` or `false`, 212 /// The truthiness operator. Returns `false` if [obj] is `null` or `false`,
207 /// `true` otherwise. 213 /// `true` otherwise.
208 bool truth(obj) => obj != null && obj != false; 214 bool truth(obj) => obj != null && obj != false;
209 215
210 /// Consumes the current character if it matches [matcher]. Returns the result 216 /// Consumes the current character if it matches [matcher]. Returns the result
211 /// of [matcher]. 217 /// of [matcher].
212 bool consume(bool matcher(int)) { 218 bool consume(bool matcher(int)) {
213 if (matcher(peek())) { 219 if (matcher(peek())) {
(...skipping 22 matching lines...) Expand all
236 return null; // Unreachable. 242 return null; // Unreachable.
237 } 243 }
238 244
239 /// Calls [consumer] until it returns a falsey value. Returns a list of all 245 /// Calls [consumer] until it returns a falsey value. Returns a list of all
240 /// truthy return values of [consumer], or the empty list if it didn't consume 246 /// truthy return values of [consumer], or the empty list if it didn't consume
241 /// anything. 247 /// anything.
242 /// 248 ///
243 /// Conceptually, repeats a production any number of times. 249 /// Conceptually, repeats a production any number of times.
244 List zeroOrMore(consumer()) { 250 List zeroOrMore(consumer()) {
245 var out = []; 251 var out = [];
246 var oldPos = pos; 252 var oldPos = _pos;
247 while (true) { 253 while (true) {
248 var el = consumer(); 254 var el = consumer();
249 if (!truth(el) || oldPos == pos) return out; 255 if (!truth(el) || oldPos == _pos) return out;
250 oldPos = pos; 256 oldPos = _pos;
251 out.add(el); 257 out.add(el);
252 } 258 }
253 return null; // Unreachable. 259 return null; // Unreachable.
254 } 260 }
255 261
256 /// Just calls [consumer] and returns its result. Used to make it explicit 262 /// Just calls [consumer] and returns its result. Used to make it explicit
257 /// that a production is intended to be optional. 263 /// that a production is intended to be optional.
258 zeroOrOne(consumer()) => consumer(); 264 zeroOrOne(consumer()) => consumer();
259 265
260 /// Calls each function in [consumers] until one returns a truthy value, then 266 /// Calls each function in [consumers] until one returns a truthy value, then
261 /// returns that. 267 /// returns that.
262 or(List<Function> consumers) { 268 or(List<Function> consumers) {
263 for (var c in consumers) { 269 for (var c in consumers) {
264 var res = c(); 270 var res = c();
265 if (truth(res)) return res; 271 if (truth(res)) return res;
266 } 272 }
267 return null; 273 return null;
268 } 274 }
269 275
270 /// Calls [consumer] and returns its result, but rolls back the parser state 276 /// Calls [consumer] and returns its result, but rolls back the parser state
271 /// if [consumer] returns a falsey value. 277 /// if [consumer] returns a falsey value.
272 transaction(consumer()) { 278 transaction(consumer()) {
273 var oldPos = pos; 279 var oldPos = _pos;
274 var oldLine = line; 280 var oldLine = _line;
275 var oldColumn = column; 281 var oldColumn = _column;
276 var oldCaptureStart = captureStart; 282 var oldCaptureStart = _captureStart;
277 String capturedSoFar = capturedString == null ? null : 283 String capturedSoFar = _capturedString == null ? null :
278 capturedString.toString(); 284 _capturedString.toString();
279 var res = consumer(); 285 var res = consumer();
280 if (truth(res)) return res; 286 if (truth(res)) return res;
281 287
282 pos = oldPos; 288 _pos = oldPos;
283 line = oldLine; 289 _line = oldLine;
284 column = oldColumn; 290 _column = oldColumn;
285 captureStart = oldCaptureStart; 291 _captureStart = oldCaptureStart;
286 capturedString = capturedSoFar == null ? null : 292 _capturedString = capturedSoFar == null ? null :
287 new StringBuffer(capturedSoFar); 293 new StringBuffer(capturedSoFar);
288 return res; 294 return res;
289 } 295 }
290 296
291 /// Consumes [n] characters matching [matcher], or none if there isn't a 297 /// Consumes [n] characters matching [matcher], or none if there isn't a
292 /// complete match. The first argument to [matcher] is the character code, the 298 /// complete match. The first argument to [matcher] is the character code, the
293 /// second is the index (from 0 to [n] - 1). 299 /// second is the index (from 0 to [n] - 1).
294 /// 300 ///
295 /// Returns whether or not the characters were consumed. 301 /// Returns whether or not the characters were consumed.
296 bool nAtOnce(int n, bool matcher(int c, int i)) => transaction(() { 302 bool nAtOnce(int n, bool matcher(int c, int i)) => transaction(() {
(...skipping 12 matching lines...) Expand all
309 /// Consumes and returns a string of characters matching [matcher], or null if 315 /// Consumes and returns a string of characters matching [matcher], or null if
310 /// there are no such characters. 316 /// there are no such characters.
311 String stringOf(bool matcher(int)) => 317 String stringOf(bool matcher(int)) =>
312 captureString(() => oneOrMore(() => consume(matcher))); 318 captureString(() => oneOrMore(() => consume(matcher)));
313 319
314 /// Calls [consumer] and returns the string that was consumed while doing so, 320 /// Calls [consumer] and returns the string that was consumed while doing so,
315 /// or null if [consumer] returned a falsey value. Automatically wraps 321 /// or null if [consumer] returned a falsey value. Automatically wraps
316 /// [consumer] in `transaction`. 322 /// [consumer] in `transaction`.
317 String captureString(consumer()) { 323 String captureString(consumer()) {
318 // captureString calls may not be nested 324 // captureString calls may not be nested
319 assert(capturedString == null); 325 assert(_capturedString == null);
320 326
321 captureStart = pos; 327 _captureStart = _pos;
322 capturedString = new StringBuffer(); 328 _capturedString = new StringBuffer();
323 var res = transaction(consumer); 329 var res = transaction(consumer);
324 if (!truth(res)) { 330 if (!truth(res)) {
325 captureStart = null; 331 _captureStart = null;
326 capturedString = null; 332 _capturedString = null;
327 return null; 333 return null;
328 } 334 }
329 335
330 flushCapture(); 336 flushCapture();
331 var result = capturedString.toString(); 337 var result = _capturedString.toString();
332 captureStart = null; 338 _captureStart = null;
333 capturedString = null; 339 _capturedString = null;
334 return result; 340 return result;
335 } 341 }
336 342
337 captureAs(String replacement, consumer()) => 343 captureAs(String replacement, consumer()) =>
338 captureAndTransform(consumer, (_) => replacement); 344 captureAndTransform(consumer, (_) => replacement);
339 345
340 captureAndTransform(consumer(), String transformation(String captured)) { 346 captureAndTransform(consumer(), String transformation(String captured)) {
341 if (capturedString == null) return consumer(); 347 if (_capturedString == null) return consumer();
342 if (capturingAs) return consumer(); 348 if (_capturingAs) return consumer();
343 349
344 flushCapture(); 350 flushCapture();
345 capturingAs = true; 351 _capturingAs = true;
346 var res = consumer(); 352 var res = consumer();
347 capturingAs = false; 353 _capturingAs = false;
348 if (!truth(res)) return res; 354 if (!truth(res)) return res;
349 355
350 capturedString.write(transformation(s.substring(captureStart, pos))); 356 _capturedString.write(transformation(_s.substring(_captureStart, _pos)));
351 captureStart = pos; 357 _captureStart = _pos;
352 return res; 358 return res;
353 } 359 }
354 360
355 void flushCapture() { 361 void flushCapture() {
356 capturedString.write(s.substring(captureStart, pos)); 362 _capturedString.write(_s.substring(_captureStart, _pos));
357 captureStart = pos; 363 _captureStart = _pos;
358 } 364 }
359 365
360 /// Adds a tag and an anchor to [node], if they're defined. 366 /// Adds a tag and an anchor to [node], if they're defined.
361 _Node addProps(_Node node, _Pair<_Tag, String> props) { 367 Node addProps(Node node, _Pair<Tag, String> props) {
362 if (props == null || node == null) return node; 368 if (props == null || node == null) return node;
363 if (truth(props.first)) node.tag = props.first; 369 if (truth(props.first)) node.tag = props.first;
364 if (truth(props.last)) node.anchor = props.last; 370 if (truth(props.last)) node.anchor = props.last;
365 return node; 371 return node;
366 } 372 }
367 373
368 /// Creates a MappingNode from [pairs]. 374 /// Creates a MappingNode from [pairs].
369 _MappingNode map(List<_Pair<_Node, _Node>> pairs) { 375 MappingNode map(List<_Pair<Node, Node>> pairs) {
370 var content = new Map<_Node, _Node>(); 376 var content = new Map<Node, Node>();
371 pairs.forEach((pair) => content[pair.first] = pair.last); 377 pairs.forEach((pair) => content[pair.first] = pair.last);
372 return new _MappingNode("?", content); 378 return new MappingNode("?", content);
373 } 379 }
374 380
375 /// Runs [fn] in a context named [name]. Used for error reporting. 381 /// Runs [fn] in a context named [name]. Used for error reporting.
376 context(String name, fn()) { 382 context(String name, fn()) {
377 try { 383 try {
378 contextStack.add(name); 384 _contextStack.add(name);
379 return fn(); 385 return fn();
380 } finally { 386 } finally {
381 var popped = contextStack.removeLast(); 387 var popped = _contextStack.removeLast();
382 assert(popped == name); 388 assert(popped == name);
383 } 389 }
384 } 390 }
385 391
386 /// Adds [message] as extra information to any errors that occur between the 392 /// Adds [message] as extra information to any errors that occur between the
387 /// current position and the position of the cursor after running [fn]. The 393 /// current position and the position of the cursor after running [fn]. The
388 /// cursor is reset after [fn] is run. 394 /// cursor is reset after [fn] is run.
389 annotateError(String message, fn()) { 395 annotateError(String message, fn()) {
390 var start = pos; 396 var start = _pos;
391 var end; 397 var end;
392 transaction(() { 398 transaction(() {
393 fn(); 399 fn();
394 end = pos; 400 end = _pos;
395 return false; 401 return false;
396 }); 402 });
397 errorAnnotations[new _Range(start, end)] = message; 403 _errorAnnotations[new _Range(start, end)] = message;
398 } 404 }
399 405
400 /// Throws an error with additional context information. 406 /// Throws an error with additional context information.
401 error(String message) { 407 error(String message) {
402 // Line and column should be one-based. 408 // Line and column should be one-based.
403 throw new SyntaxError(line + 1, column + 1, 409 throw new SyntaxError(_line + 1, _column + 1,
404 "$message (in $farthestContext)"); 410 "$message (in $_farthestContext)");
405 } 411 }
406 412
407 /// If [result] is falsey, throws an error saying that [expected] was 413 /// If [result] is falsey, throws an error saying that [expected] was
408 /// expected. 414 /// expected.
409 expect(result, String expected) { 415 expect(result, String expected) {
410 if (truth(result)) return result; 416 if (truth(result)) return result;
411 error("expected $expected"); 417 error("expected $expected");
412 } 418 }
413 419
414 /// Throws an error saying that the parse failed. Uses [farthestLine], 420 /// Throws an error saying that the parse failed. Uses [_farthestLine],
415 /// [farthestColumn], and [farthestContext] to provide additional information. 421 /// [_farthestColumn], and [_farthestContext] to provide additional informatio n.
416 parseFailed() { 422 parseFailed() {
417 var message = "invalid YAML in $farthestContext"; 423 var message = "invalid YAML in $_farthestContext";
418 var extraError = errorAnnotations[farthestPos]; 424 var extraError = _errorAnnotations[_farthestPos];
419 if (extraError != null) message = "$message ($extraError)"; 425 if (extraError != null) message = "$message ($extraError)";
420 throw new SyntaxError(farthestLine + 1, farthestColumn + 1, message); 426 throw new SyntaxError(_farthestLine + 1, _farthestColumn + 1, message);
421 } 427 }
422 428
423 /// Returns the number of spaces after the current position. 429 /// Returns the number of spaces after the current position.
424 int countIndentation() { 430 int countIndentation() {
425 var i = 0; 431 var i = 0;
426 while (peek(i) == SP) i++; 432 while (peek(i) == SP) i++;
427 return i; 433 return i;
428 } 434 }
429 435
430 /// Returns the indentation for a block scalar. 436 /// Returns the indentation for a block scalar.
431 int blockScalarAdditionalIndentation(_BlockHeader header, int indent) { 437 int blockScalarAdditionalIndentation(_BlockHeader header, int indent) {
432 if (!header.autoDetectIndent) return header.additionalIndent; 438 if (!header.autoDetectIndent) return header.additionalIndent;
433 439
434 var maxSpaces = 0; 440 var maxSpaces = 0;
435 var maxSpacesLine = 0; 441 var maxSpacesLine = 0;
436 var spaces = 0; 442 var spaces = 0;
437 transaction(() { 443 transaction(() {
438 do { 444 do {
439 spaces = captureString(() => zeroOrMore(() => consumeChar(SP))).length; 445 spaces = captureString(() => zeroOrMore(() => consumeChar(SP))).length;
440 if (spaces > maxSpaces) { 446 if (spaces > maxSpaces) {
441 maxSpaces = spaces; 447 maxSpaces = spaces;
442 maxSpacesLine = line; 448 maxSpacesLine = _line;
443 } 449 }
444 } while (b_break()); 450 } while (b_break());
445 return false; 451 return false;
446 }); 452 });
447 453
448 // If the next non-empty line isn't indented further than the start of the 454 // If the next non-empty line isn't indented further than the start of the
449 // block scalar, that means the scalar is going to be empty. Returning any 455 // block scalar, that means the scalar is going to be empty. Returning any
450 // value > 0 will cause the parser not to consume any text. 456 // value > 0 will cause the parser not to consume any text.
451 if (spaces <= indent) return 1; 457 if (spaces <= indent) return 1;
452 458
453 // It's an error for a leading empty line to be indented more than the first 459 // It's an error for a leading empty line to be indented more than the first
454 // non-empty line. 460 // non-empty line.
455 if (maxSpaces > spaces) { 461 if (maxSpaces > spaces) {
456 throw new SyntaxError(maxSpacesLine + 1, maxSpaces, 462 throw new SyntaxError(maxSpacesLine + 1, maxSpaces,
457 "Leading empty lines may not be indented more than the first " 463 "Leading empty lines may not be indented more than the first "
458 "non-empty line."); 464 "non-empty line.");
459 } 465 }
460 466
461 return spaces - indent; 467 return spaces - indent;
462 } 468 }
463 469
464 /// Returns whether the current position is at the beginning of a line. 470 /// Returns whether the current position is at the beginning of a line.
465 bool get atStartOfLine => column == 0; 471 bool get atStartOfLine => _column == 0;
466 472
467 /// Returns whether the current position is at the end of the input. 473 /// Returns whether the current position is at the end of the input.
468 bool get atEndOfFile => pos == len; 474 bool get atEndOfFile => _pos == _len;
469 475
470 /// Given an indicator character, returns the type of that indicator (or null 476 /// Given an indicator character, returns the type of that indicator (or null
471 /// if the indicator isn't found. 477 /// if the indicator isn't found.
472 int indicatorType(int char) { 478 int indicatorType(int char) {
473 switch (char) { 479 switch (char) {
474 case HYPHEN: return C_SEQUENCE_ENTRY; 480 case HYPHEN: return C_SEQUENCE_ENTRY;
475 case QUESTION_MARK: return C_MAPPING_KEY; 481 case QUESTION_MARK: return C_MAPPING_KEY;
476 case COLON: return C_MAPPING_VALUE; 482 case COLON: return C_MAPPING_VALUE;
477 case COMMA: return C_COLLECT_ENTRY; 483 case COMMA: return C_COLLECT_ENTRY;
478 case LEFT_BRACKET: return C_SEQUENCE_START; 484 case LEFT_BRACKET: return C_SEQUENCE_START;
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // 81 795 // 81
790 bool s_separateLines(int indent) { 796 bool s_separateLines(int indent) {
791 return transaction(() => s_l_comments() && s_flowLinePrefix(indent)) || 797 return transaction(() => s_l_comments() && s_flowLinePrefix(indent)) ||
792 s_separateInLine(); 798 s_separateInLine();
793 } 799 }
794 800
795 // 82 801 // 82
796 bool l_directive() => false; // TODO(nweiz): implement 802 bool l_directive() => false; // TODO(nweiz): implement
797 803
798 // 96 804 // 96
799 _Pair<_Tag, String> c_ns_properties(int indent, int ctx) { 805 _Pair<Tag, String> c_ns_properties(int indent, int ctx) {
800 var tag, anchor; 806 var tag, anchor;
801 tag = c_ns_tagProperty(); 807 tag = c_ns_tagProperty();
802 if (truth(tag)) { 808 if (truth(tag)) {
803 anchor = transaction(() { 809 anchor = transaction(() {
804 if (!truth(s_separate(indent, ctx))) return null; 810 if (!truth(s_separate(indent, ctx))) return null;
805 return c_ns_anchorProperty(); 811 return c_ns_anchorProperty();
806 }); 812 });
807 return new _Pair<_Tag, String>(tag, anchor); 813 return new _Pair<Tag, String>(tag, anchor);
808 } 814 }
809 815
810 anchor = c_ns_anchorProperty(); 816 anchor = c_ns_anchorProperty();
811 if (truth(anchor)) { 817 if (truth(anchor)) {
812 tag = transaction(() { 818 tag = transaction(() {
813 if (!truth(s_separate(indent, ctx))) return null; 819 if (!truth(s_separate(indent, ctx))) return null;
814 return c_ns_tagProperty(); 820 return c_ns_tagProperty();
815 }); 821 });
816 return new _Pair<_Tag, String>(tag, anchor); 822 return new _Pair<Tag, String>(tag, anchor);
817 } 823 }
818 824
819 return null; 825 return null;
820 } 826 }
821 827
822 // 97 828 // 97
823 _Tag c_ns_tagProperty() => null; // TODO(nweiz): implement 829 Tag c_ns_tagProperty() => null; // TODO(nweiz): implement
824 830
825 // 101 831 // 101
826 String c_ns_anchorProperty() => null; // TODO(nweiz): implement 832 String c_ns_anchorProperty() => null; // TODO(nweiz): implement
827 833
828 // 102 834 // 102
829 bool isAnchorChar(int char) => isNonSpace(char) && !isFlowIndicator(char); 835 bool isAnchorChar(int char) => isNonSpace(char) && !isFlowIndicator(char);
830 836
831 // 103 837 // 103
832 String ns_anchorName() => 838 String ns_anchorName() =>
833 captureString(() => oneOrMore(() => consume(isAnchorChar))); 839 captureString(() => oneOrMore(() => consume(isAnchorChar)));
834 840
835 // 104 841 // 104
836 _Node c_ns_aliasNode() { 842 Node c_ns_aliasNode() {
837 if (!truth(c_indicator(C_ALIAS))) return null; 843 if (!truth(c_indicator(C_ALIAS))) return null;
838 var name = expect(ns_anchorName(), 'anchor name'); 844 var name = expect(ns_anchorName(), 'anchor name');
839 return new _AliasNode(name); 845 return new AliasNode(name);
840 } 846 }
841 847
842 // 105 848 // 105
843 _ScalarNode e_scalar() => new _ScalarNode("?", content: ""); 849 ScalarNode e_scalar() => new ScalarNode("?", content: "");
844 850
845 // 106 851 // 106
846 _ScalarNode e_node() => e_scalar(); 852 ScalarNode e_node() => e_scalar();
847 853
848 // 107 854 // 107
849 bool nb_doubleChar() => or([ 855 bool nb_doubleChar() => or([
850 c_ns_escChar, 856 c_ns_escChar,
851 () => consume((c) => isJson(c) && c != BACKSLASH && c != DOUBLE_QUOTE) 857 () => consume((c) => isJson(c) && c != BACKSLASH && c != DOUBLE_QUOTE)
852 ]); 858 ]);
853 859
854 // 108 860 // 108
855 bool ns_doubleChar() => !isSpace(peek()) && truth(nb_doubleChar()); 861 bool ns_doubleChar() => !isSpace(peek()) && truth(nb_doubleChar());
856 862
857 // 109 863 // 109
858 _Node c_doubleQuoted(int indent, int ctx) => context('string', () { 864 Node c_doubleQuoted(int indent, int ctx) => context('string', () {
859 return transaction(() { 865 return transaction(() {
860 if (!truth(c_indicator(C_DOUBLE_QUOTE))) return null; 866 if (!truth(c_indicator(C_DOUBLE_QUOTE))) return null;
861 var contents = nb_doubleText(indent, ctx); 867 var contents = nb_doubleText(indent, ctx);
862 if (!truth(c_indicator(C_DOUBLE_QUOTE))) return null; 868 if (!truth(c_indicator(C_DOUBLE_QUOTE))) return null;
863 return new _ScalarNode("!", content: contents); 869 return new ScalarNode("!", content: contents);
864 }); 870 });
865 }); 871 });
866 872
867 // 110 873 // 110
868 String nb_doubleText(int indent, int ctx) => captureString(() { 874 String nb_doubleText(int indent, int ctx) => captureString(() {
869 switch (ctx) { 875 switch (ctx) {
870 case FLOW_OUT: 876 case FLOW_OUT:
871 case FLOW_IN: 877 case FLOW_IN:
872 nb_doubleMultiLine(indent); 878 nb_doubleMultiLine(indent);
873 break; 879 break;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
936 // 118 942 // 118
937 bool nb_singleChar() => or([ 943 bool nb_singleChar() => or([
938 c_quotedQuote, 944 c_quotedQuote,
939 () => consume((c) => isJson(c) && c != SINGLE_QUOTE) 945 () => consume((c) => isJson(c) && c != SINGLE_QUOTE)
940 ]); 946 ]);
941 947
942 // 119 948 // 119
943 bool ns_singleChar() => !isSpace(peek()) && truth(nb_singleChar()); 949 bool ns_singleChar() => !isSpace(peek()) && truth(nb_singleChar());
944 950
945 // 120 951 // 120
946 _Node c_singleQuoted(int indent, int ctx) => context('string', () { 952 Node c_singleQuoted(int indent, int ctx) => context('string', () {
947 return transaction(() { 953 return transaction(() {
948 if (!truth(c_indicator(C_SINGLE_QUOTE))) return null; 954 if (!truth(c_indicator(C_SINGLE_QUOTE))) return null;
949 var contents = nb_singleText(indent, ctx); 955 var contents = nb_singleText(indent, ctx);
950 if (!truth(c_indicator(C_SINGLE_QUOTE))) return null; 956 if (!truth(c_indicator(C_SINGLE_QUOTE))) return null;
951 return new _ScalarNode("!", content: contents); 957 return new ScalarNode("!", content: contents);
952 }); 958 });
953 }); 959 });
954 960
955 // 121 961 // 121
956 String nb_singleText(int indent, int ctx) => captureString(() { 962 String nb_singleText(int indent, int ctx) => captureString(() {
957 switch (ctx) { 963 switch (ctx) {
958 case FLOW_OUT: 964 case FLOW_OUT:
959 case FLOW_IN: 965 case FLOW_IN:
960 nb_singleMultiLine(indent); 966 nb_singleMultiLine(indent);
961 break; 967 break;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 case FLOW_OUT: 1109 case FLOW_OUT:
1104 case FLOW_IN: 1110 case FLOW_IN:
1105 return FLOW_IN; 1111 return FLOW_IN;
1106 case BLOCK_KEY: 1112 case BLOCK_KEY:
1107 case FLOW_KEY: 1113 case FLOW_KEY:
1108 return FLOW_KEY; 1114 return FLOW_KEY;
1109 } 1115 }
1110 } 1116 }
1111 1117
1112 // 137 1118 // 137
1113 _SequenceNode c_flowSequence(int indent, int ctx) => transaction(() { 1119 SequenceNode c_flowSequence(int indent, int ctx) => transaction(() {
1114 if (!truth(c_indicator(C_SEQUENCE_START))) return null; 1120 if (!truth(c_indicator(C_SEQUENCE_START))) return null;
1115 zeroOrOne(() => s_separate(indent, ctx)); 1121 zeroOrOne(() => s_separate(indent, ctx));
1116 var content = zeroOrOne(() => ns_s_flowSeqEntries(indent, inFlow(ctx))); 1122 var content = zeroOrOne(() => ns_s_flowSeqEntries(indent, inFlow(ctx)));
1117 if (!truth(c_indicator(C_SEQUENCE_END))) return null; 1123 if (!truth(c_indicator(C_SEQUENCE_END))) return null;
1118 return new _SequenceNode("?", new List<_Node>.from(content)); 1124 return new SequenceNode("?", new List<Node>.from(content));
1119 }); 1125 });
1120 1126
1121 // 138 1127 // 138
1122 Iterable<_Node> ns_s_flowSeqEntries(int indent, int ctx) { 1128 Iterable<Node> ns_s_flowSeqEntries(int indent, int ctx) {
1123 var first = ns_flowSeqEntry(indent, ctx); 1129 var first = ns_flowSeqEntry(indent, ctx);
1124 if (!truth(first)) return new Queue<_Node>(); 1130 if (!truth(first)) return new Queue<Node>();
1125 zeroOrOne(() => s_separate(indent, ctx)); 1131 zeroOrOne(() => s_separate(indent, ctx));
1126 1132
1127 var rest; 1133 var rest;
1128 if (truth(c_indicator(C_COLLECT_ENTRY))) { 1134 if (truth(c_indicator(C_COLLECT_ENTRY))) {
1129 zeroOrOne(() => s_separate(indent, ctx)); 1135 zeroOrOne(() => s_separate(indent, ctx));
1130 rest = zeroOrOne(() => ns_s_flowSeqEntries(indent, ctx)); 1136 rest = zeroOrOne(() => ns_s_flowSeqEntries(indent, ctx));
1131 } 1137 }
1132 1138
1133 if (rest == null) rest = new Queue<_Node>(); 1139 if (rest == null) rest = new Queue<Node>();
1134 rest.addFirst(first); 1140 rest.addFirst(first);
1135 1141
1136 return rest; 1142 return rest;
1137 } 1143 }
1138 1144
1139 // 139 1145 // 139
1140 _Node ns_flowSeqEntry(int indent, int ctx) => or([ 1146 Node ns_flowSeqEntry(int indent, int ctx) => or([
1141 () => ns_flowPair(indent, ctx), 1147 () => ns_flowPair(indent, ctx),
1142 () => ns_flowNode(indent, ctx) 1148 () => ns_flowNode(indent, ctx)
1143 ]); 1149 ]);
1144 1150
1145 // 140 1151 // 140
1146 _Node c_flowMapping(int indent, int ctx) { 1152 Node c_flowMapping(int indent, int ctx) {
1147 if (!truth(c_indicator(C_MAPPING_START))) return null; 1153 if (!truth(c_indicator(C_MAPPING_START))) return null;
1148 zeroOrOne(() => s_separate(indent, ctx)); 1154 zeroOrOne(() => s_separate(indent, ctx));
1149 var content = zeroOrOne(() => ns_s_flowMapEntries(indent, inFlow(ctx))); 1155 var content = zeroOrOne(() => ns_s_flowMapEntries(indent, inFlow(ctx)));
1150 if (!truth(c_indicator(C_MAPPING_END))) return null; 1156 if (!truth(c_indicator(C_MAPPING_END))) return null;
1151 return new _MappingNode("?", content); 1157 return new MappingNode("?", content);
1152 } 1158 }
1153 1159
1154 // 141 1160 // 141
1155 YamlMap ns_s_flowMapEntries(int indent, int ctx) { 1161 YamlMap ns_s_flowMapEntries(int indent, int ctx) {
1156 var first = ns_flowMapEntry(indent, ctx); 1162 var first = ns_flowMapEntry(indent, ctx);
1157 if (!truth(first)) return new YamlMap(); 1163 if (!truth(first)) return new YamlMap();
1158 zeroOrOne(() => s_separate(indent, ctx)); 1164 zeroOrOne(() => s_separate(indent, ctx));
1159 1165
1160 var rest; 1166 var rest;
1161 if (truth(c_indicator(C_COLLECT_ENTRY))) { 1167 if (truth(c_indicator(C_COLLECT_ENTRY))) {
1162 zeroOrOne(() => s_separate(indent, ctx)); 1168 zeroOrOne(() => s_separate(indent, ctx));
1163 rest = ns_s_flowMapEntries(indent, ctx); 1169 rest = ns_s_flowMapEntries(indent, ctx);
1164 } 1170 }
1165 1171
1166 if (rest == null) rest = new YamlMap(); 1172 if (rest == null) rest = new YamlMap();
1167 1173
1168 // TODO(nweiz): Duplicate keys should be an error. This includes keys with 1174 // TODO(nweiz): Duplicate keys should be an error. This includes keys with
1169 // different representations but the same value (e.g. 10 vs 0xa). To make 1175 // different representations but the same value (e.g. 10 vs 0xa). To make
1170 // this user-friendly we'll probably also want to associate nodes with a 1176 // this user-friendly we'll probably also want to associate nodes with a
1171 // source range. 1177 // source range.
1172 if (!rest.containsKey(first.first)) rest[first.first] = first.last; 1178 if (!rest.containsKey(first.first)) rest[first.first] = first.last;
1173 1179
1174 return rest; 1180 return rest;
1175 } 1181 }
1176 1182
1177 // 142 1183 // 142
1178 _Pair<_Node, _Node> ns_flowMapEntry(int indent, int ctx) => or([ 1184 _Pair<Node, Node> ns_flowMapEntry(int indent, int ctx) => or([
1179 () => transaction(() { 1185 () => transaction(() {
1180 if (!truth(c_indicator(C_MAPPING_KEY))) return false; 1186 if (!truth(c_indicator(C_MAPPING_KEY))) return false;
1181 if (!truth(s_separate(indent, ctx))) return false; 1187 if (!truth(s_separate(indent, ctx))) return false;
1182 return ns_flowMapExplicitEntry(indent, ctx); 1188 return ns_flowMapExplicitEntry(indent, ctx);
1183 }), 1189 }),
1184 () => ns_flowMapImplicitEntry(indent, ctx) 1190 () => ns_flowMapImplicitEntry(indent, ctx)
1185 ]); 1191 ]);
1186 1192
1187 // 143 1193 // 143
1188 _Pair<_Node, _Node> ns_flowMapExplicitEntry(int indent, int ctx) => or([ 1194 _Pair<Node, Node> ns_flowMapExplicitEntry(int indent, int ctx) => or([
1189 () => ns_flowMapImplicitEntry(indent, ctx), 1195 () => ns_flowMapImplicitEntry(indent, ctx),
1190 () => new _Pair<_Node, _Node>(e_node(), e_node()) 1196 () => new _Pair<Node, Node>(e_node(), e_node())
1191 ]); 1197 ]);
1192 1198
1193 // 144 1199 // 144
1194 _Pair<_Node, _Node> ns_flowMapImplicitEntry(int indent, int ctx) => or([ 1200 _Pair<Node, Node> ns_flowMapImplicitEntry(int indent, int ctx) => or([
1195 () => ns_flowMapYamlKeyEntry(indent, ctx), 1201 () => ns_flowMapYamlKeyEntry(indent, ctx),
1196 () => c_ns_flowMapEmptyKeyEntry(indent, ctx), 1202 () => c_ns_flowMapEmptyKeyEntry(indent, ctx),
1197 () => c_ns_flowMapJsonKeyEntry(indent, ctx) 1203 () => c_ns_flowMapJsonKeyEntry(indent, ctx)
1198 ]); 1204 ]);
1199 1205
1200 // 145 1206 // 145
1201 _Pair<_Node, _Node> ns_flowMapYamlKeyEntry(int indent, int ctx) { 1207 _Pair<Node, Node> ns_flowMapYamlKeyEntry(int indent, int ctx) {
1202 var key = ns_flowYamlNode(indent, ctx); 1208 var key = ns_flowYamlNode(indent, ctx);
1203 if (!truth(key)) return null; 1209 if (!truth(key)) return null;
1204 var value = or([ 1210 var value = or([
1205 () => transaction(() { 1211 () => transaction(() {
1206 zeroOrOne(() => s_separate(indent, ctx)); 1212 zeroOrOne(() => s_separate(indent, ctx));
1207 return c_ns_flowMapSeparateValue(indent, ctx); 1213 return c_ns_flowMapSeparateValue(indent, ctx);
1208 }), 1214 }),
1209 e_node 1215 e_node
1210 ]); 1216 ]);
1211 return new _Pair<_Node, _Node>(key, value); 1217 return new _Pair<Node, Node>(key, value);
1212 } 1218 }
1213 1219
1214 // 146 1220 // 146
1215 _Pair<_Node, _Node> c_ns_flowMapEmptyKeyEntry(int indent, int ctx) { 1221 _Pair<Node, Node> c_ns_flowMapEmptyKeyEntry(int indent, int ctx) {
1216 var value = c_ns_flowMapSeparateValue(indent, ctx); 1222 var value = c_ns_flowMapSeparateValue(indent, ctx);
1217 if (!truth(value)) return null; 1223 if (!truth(value)) return null;
1218 return new _Pair<_Node, _Node>(e_node(), value); 1224 return new _Pair<Node, Node>(e_node(), value);
1219 } 1225 }
1220 1226
1221 // 147 1227 // 147
1222 _Node c_ns_flowMapSeparateValue(int indent, int ctx) => transaction(() { 1228 Node c_ns_flowMapSeparateValue(int indent, int ctx) => transaction(() {
1223 if (!truth(c_indicator(C_MAPPING_VALUE))) return null; 1229 if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
1224 if (isPlainSafe(ctx, peek())) return null; 1230 if (isPlainSafe(ctx, peek())) return null;
1225 1231
1226 return or([ 1232 return or([
1227 () => transaction(() { 1233 () => transaction(() {
1228 if (!s_separate(indent, ctx)) return null; 1234 if (!s_separate(indent, ctx)) return null;
1229 return ns_flowNode(indent, ctx); 1235 return ns_flowNode(indent, ctx);
1230 }), 1236 }),
1231 e_node 1237 e_node
1232 ]); 1238 ]);
1233 }); 1239 });
1234 1240
1235 // 148 1241 // 148
1236 _Pair<_Node, _Node> c_ns_flowMapJsonKeyEntry(int indent, int ctx) { 1242 _Pair<Node, Node> c_ns_flowMapJsonKeyEntry(int indent, int ctx) {
1237 var key = c_flowJsonNode(indent, ctx); 1243 var key = c_flowJsonNode(indent, ctx);
1238 if (!truth(key)) return null; 1244 if (!truth(key)) return null;
1239 var value = or([ 1245 var value = or([
1240 () => transaction(() { 1246 () => transaction(() {
1241 zeroOrOne(() => s_separate(indent, ctx)); 1247 zeroOrOne(() => s_separate(indent, ctx));
1242 return c_ns_flowMapAdjacentValue(indent, ctx); 1248 return c_ns_flowMapAdjacentValue(indent, ctx);
1243 }), 1249 }),
1244 e_node 1250 e_node
1245 ]); 1251 ]);
1246 return new _Pair<_Node, _Node>(key, value); 1252 return new _Pair<Node, Node>(key, value);
1247 } 1253 }
1248 1254
1249 // 149 1255 // 149
1250 _Node c_ns_flowMapAdjacentValue(int indent, int ctx) { 1256 Node c_ns_flowMapAdjacentValue(int indent, int ctx) {
1251 if (!truth(c_indicator(C_MAPPING_VALUE))) return null; 1257 if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
1252 return or([ 1258 return or([
1253 () => transaction(() { 1259 () => transaction(() {
1254 zeroOrOne(() => s_separate(indent, ctx)); 1260 zeroOrOne(() => s_separate(indent, ctx));
1255 return ns_flowNode(indent, ctx); 1261 return ns_flowNode(indent, ctx);
1256 }), 1262 }),
1257 e_node 1263 e_node
1258 ]); 1264 ]);
1259 } 1265 }
1260 1266
1261 // 150 1267 // 150
1262 _Node ns_flowPair(int indent, int ctx) { 1268 Node ns_flowPair(int indent, int ctx) {
1263 var pair = or([ 1269 var pair = or([
1264 () => transaction(() { 1270 () => transaction(() {
1265 if (!truth(c_indicator(C_MAPPING_KEY))) return null; 1271 if (!truth(c_indicator(C_MAPPING_KEY))) return null;
1266 if (!truth(s_separate(indent, ctx))) return null; 1272 if (!truth(s_separate(indent, ctx))) return null;
1267 return ns_flowMapExplicitEntry(indent, ctx); 1273 return ns_flowMapExplicitEntry(indent, ctx);
1268 }), 1274 }),
1269 () => ns_flowPairEntry(indent, ctx) 1275 () => ns_flowPairEntry(indent, ctx)
1270 ]); 1276 ]);
1271 if (!truth(pair)) return null; 1277 if (!truth(pair)) return null;
1272 1278
1273 return map([pair]); 1279 return map([pair]);
1274 } 1280 }
1275 1281
1276 // 151 1282 // 151
1277 _Pair<_Node, _Node> ns_flowPairEntry(int indent, int ctx) => or([ 1283 _Pair<Node, Node> ns_flowPairEntry(int indent, int ctx) => or([
1278 () => ns_flowPairYamlKeyEntry(indent, ctx), 1284 () => ns_flowPairYamlKeyEntry(indent, ctx),
1279 () => c_ns_flowMapEmptyKeyEntry(indent, ctx), 1285 () => c_ns_flowMapEmptyKeyEntry(indent, ctx),
1280 () => c_ns_flowPairJsonKeyEntry(indent, ctx) 1286 () => c_ns_flowPairJsonKeyEntry(indent, ctx)
1281 ]); 1287 ]);
1282 1288
1283 // 152 1289 // 152
1284 _Pair<_Node, _Node> ns_flowPairYamlKeyEntry(int indent, int ctx) => 1290 _Pair<Node, Node> ns_flowPairYamlKeyEntry(int indent, int ctx) =>
1285 transaction(() { 1291 transaction(() {
1286 var key = ns_s_implicitYamlKey(FLOW_KEY); 1292 var key = ns_s_implicitYamlKey(FLOW_KEY);
1287 if (!truth(key)) return null; 1293 if (!truth(key)) return null;
1288 var value = c_ns_flowMapSeparateValue(indent, ctx); 1294 var value = c_ns_flowMapSeparateValue(indent, ctx);
1289 if (!truth(value)) return null; 1295 if (!truth(value)) return null;
1290 return new _Pair<_Node, _Node>(key, value); 1296 return new _Pair<Node, Node>(key, value);
1291 }); 1297 });
1292 1298
1293 // 153 1299 // 153
1294 _Pair<_Node, _Node> c_ns_flowPairJsonKeyEntry(int indent, int ctx) => 1300 _Pair<Node, Node> c_ns_flowPairJsonKeyEntry(int indent, int ctx) =>
1295 transaction(() { 1301 transaction(() {
1296 var key = c_s_implicitJsonKey(FLOW_KEY); 1302 var key = c_s_implicitJsonKey(FLOW_KEY);
1297 if (!truth(key)) return null; 1303 if (!truth(key)) return null;
1298 var value = c_ns_flowMapAdjacentValue(indent, ctx); 1304 var value = c_ns_flowMapAdjacentValue(indent, ctx);
1299 if (!truth(value)) return null; 1305 if (!truth(value)) return null;
1300 return new _Pair<_Node, _Node>(key, value); 1306 return new _Pair<Node, Node>(key, value);
1301 }); 1307 });
1302 1308
1303 // 154 1309 // 154
1304 _Node ns_s_implicitYamlKey(int ctx) => transaction(() { 1310 Node ns_s_implicitYamlKey(int ctx) => transaction(() {
1305 // TODO(nweiz): this is supposed to be limited to 1024 characters. 1311 // TODO(nweiz): this is supposed to be limited to 1024 characters.
1306 1312
1307 // The indentation parameter is "null" since it's unused in this path 1313 // The indentation parameter is "null" since it's unused in this path
1308 var node = ns_flowYamlNode(null, ctx); 1314 var node = ns_flowYamlNode(null, ctx);
1309 if (!truth(node)) return null; 1315 if (!truth(node)) return null;
1310 zeroOrOne(s_separateInLine); 1316 zeroOrOne(s_separateInLine);
1311 return node; 1317 return node;
1312 }); 1318 });
1313 1319
1314 // 155 1320 // 155
1315 _Node c_s_implicitJsonKey(int ctx) => transaction(() { 1321 Node c_s_implicitJsonKey(int ctx) => transaction(() {
1316 // TODO(nweiz): this is supposed to be limited to 1024 characters. 1322 // TODO(nweiz): this is supposed to be limited to 1024 characters.
1317 1323
1318 // The indentation parameter is "null" since it's unused in this path 1324 // The indentation parameter is "null" since it's unused in this path
1319 var node = c_flowJsonNode(null, ctx); 1325 var node = c_flowJsonNode(null, ctx);
1320 if (!truth(node)) return null; 1326 if (!truth(node)) return null;
1321 zeroOrOne(s_separateInLine); 1327 zeroOrOne(s_separateInLine);
1322 return node; 1328 return node;
1323 }); 1329 });
1324 1330
1325 // 156 1331 // 156
1326 _Node ns_flowYamlContent(int indent, int ctx) { 1332 Node ns_flowYamlContent(int indent, int ctx) {
1327 var str = ns_plain(indent, ctx); 1333 var str = ns_plain(indent, ctx);
1328 if (!truth(str)) return null; 1334 if (!truth(str)) return null;
1329 return new _ScalarNode("?", content: str); 1335 return new ScalarNode("?", content: str);
1330 } 1336 }
1331 1337
1332 // 157 1338 // 157
1333 _Node c_flowJsonContent(int indent, int ctx) => or([ 1339 Node c_flowJsonContent(int indent, int ctx) => or([
1334 () => c_flowSequence(indent, ctx), 1340 () => c_flowSequence(indent, ctx),
1335 () => c_flowMapping(indent, ctx), 1341 () => c_flowMapping(indent, ctx),
1336 () => c_singleQuoted(indent, ctx), 1342 () => c_singleQuoted(indent, ctx),
1337 () => c_doubleQuoted(indent, ctx) 1343 () => c_doubleQuoted(indent, ctx)
1338 ]); 1344 ]);
1339 1345
1340 // 158 1346 // 158
1341 _Node ns_flowContent(int indent, int ctx) => or([ 1347 Node ns_flowContent(int indent, int ctx) => or([
1342 () => ns_flowYamlContent(indent, ctx), 1348 () => ns_flowYamlContent(indent, ctx),
1343 () => c_flowJsonContent(indent, ctx) 1349 () => c_flowJsonContent(indent, ctx)
1344 ]); 1350 ]);
1345 1351
1346 // 159 1352 // 159
1347 _Node ns_flowYamlNode(int indent, int ctx) => or([ 1353 Node ns_flowYamlNode(int indent, int ctx) => or([
1348 c_ns_aliasNode, 1354 c_ns_aliasNode,
1349 () => ns_flowYamlContent(indent, ctx), 1355 () => ns_flowYamlContent(indent, ctx),
1350 () { 1356 () {
1351 var props = c_ns_properties(indent, ctx); 1357 var props = c_ns_properties(indent, ctx);
1352 if (!truth(props)) return null; 1358 if (!truth(props)) return null;
1353 var node = or([ 1359 var node = or([
1354 () => transaction(() { 1360 () => transaction(() {
1355 if (!truth(s_separate(indent, ctx))) return null; 1361 if (!truth(s_separate(indent, ctx))) return null;
1356 return ns_flowYamlContent(indent, ctx); 1362 return ns_flowYamlContent(indent, ctx);
1357 }), 1363 }),
1358 e_scalar 1364 e_scalar
1359 ]); 1365 ]);
1360 return addProps(node, props); 1366 return addProps(node, props);
1361 } 1367 }
1362 ]); 1368 ]);
1363 1369
1364 // 160 1370 // 160
1365 _Node c_flowJsonNode(int indent, int ctx) => transaction(() { 1371 Node c_flowJsonNode(int indent, int ctx) => transaction(() {
1366 var props; 1372 var props;
1367 zeroOrOne(() => transaction(() { 1373 zeroOrOne(() => transaction(() {
1368 props = c_ns_properties(indent, ctx); 1374 props = c_ns_properties(indent, ctx);
1369 if (!truth(props)) return null; 1375 if (!truth(props)) return null;
1370 return s_separate(indent, ctx); 1376 return s_separate(indent, ctx);
1371 })); 1377 }));
1372 1378
1373 return addProps(c_flowJsonContent(indent, ctx), props); 1379 return addProps(c_flowJsonContent(indent, ctx), props);
1374 }); 1380 });
1375 1381
1376 // 161 1382 // 161
1377 _Node ns_flowNode(int indent, int ctx) => or([ 1383 Node ns_flowNode(int indent, int ctx) => or([
1378 c_ns_aliasNode, 1384 c_ns_aliasNode,
1379 () => ns_flowContent(indent, ctx), 1385 () => ns_flowContent(indent, ctx),
1380 () => transaction(() { 1386 () => transaction(() {
1381 var props = c_ns_properties(indent, ctx); 1387 var props = c_ns_properties(indent, ctx);
1382 if (!truth(props)) return null; 1388 if (!truth(props)) return null;
1383 var node = or([ 1389 var node = or([
1384 () => transaction(() => s_separate(indent, ctx) ? 1390 () => transaction(() => s_separate(indent, ctx) ?
1385 ns_flowContent(indent, ctx) : null), 1391 ns_flowContent(indent, ctx) : null),
1386 e_scalar]); 1392 e_scalar]);
1387 return addProps(node, props); 1393 return addProps(node, props);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 // 169 1470 // 169
1465 bool l_trailComments(int indent) => transaction(() { 1471 bool l_trailComments(int indent) => transaction(() {
1466 if (!truth(s_indentLessThanOrEqualTo(indent))) return false; 1472 if (!truth(s_indentLessThanOrEqualTo(indent))) return false;
1467 if (!truth(c_nb_commentText())) return false; 1473 if (!truth(c_nb_commentText())) return false;
1468 if (!truth(b_comment())) return false; 1474 if (!truth(b_comment())) return false;
1469 zeroOrMore(l_comment); 1475 zeroOrMore(l_comment);
1470 return true; 1476 return true;
1471 }); 1477 });
1472 1478
1473 // 170 1479 // 170
1474 _Node c_l_literal(int indent) => transaction(() { 1480 Node c_l_literal(int indent) => transaction(() {
1475 if (!truth(c_indicator(C_LITERAL))) return null; 1481 if (!truth(c_indicator(C_LITERAL))) return null;
1476 var header = c_b_blockHeader(); 1482 var header = c_b_blockHeader();
1477 if (!truth(header)) return null; 1483 if (!truth(header)) return null;
1478 1484
1479 var additionalIndent = blockScalarAdditionalIndentation(header, indent); 1485 var additionalIndent = blockScalarAdditionalIndentation(header, indent);
1480 var content = l_literalContent(indent + additionalIndent, header.chomping); 1486 var content = l_literalContent(indent + additionalIndent, header.chomping);
1481 if (!truth(content)) return null; 1487 if (!truth(content)) return null;
1482 1488
1483 return new _ScalarNode("!", content: content); 1489 return new ScalarNode("!", content: content);
1484 }); 1490 });
1485 1491
1486 // 171 1492 // 171
1487 bool l_nb_literalText(int indent) => transaction(() { 1493 bool l_nb_literalText(int indent) => transaction(() {
1488 zeroOrMore(() => captureAs("\n", () => l_empty(indent, BLOCK_IN))); 1494 zeroOrMore(() => captureAs("\n", () => l_empty(indent, BLOCK_IN)));
1489 if (!truth(captureAs("", () => s_indent(indent)))) return false; 1495 if (!truth(captureAs("", () => s_indent(indent)))) return false;
1490 return truth(oneOrMore(() => consume(isNonBreak))); 1496 return truth(oneOrMore(() => consume(isNonBreak)));
1491 }); 1497 });
1492 1498
1493 // 172 1499 // 172
1494 bool b_nb_literalNext(int indent) => transaction(() { 1500 bool b_nb_literalNext(int indent) => transaction(() {
1495 if (!truth(b_asLineFeed())) return false; 1501 if (!truth(b_asLineFeed())) return false;
1496 return l_nb_literalText(indent); 1502 return l_nb_literalText(indent);
1497 }); 1503 });
1498 1504
1499 // 173 1505 // 173
1500 String l_literalContent(int indent, int chomping) => captureString(() { 1506 String l_literalContent(int indent, int chomping) => captureString(() {
1501 transaction(() { 1507 transaction(() {
1502 if (!truth(l_nb_literalText(indent))) return false; 1508 if (!truth(l_nb_literalText(indent))) return false;
1503 zeroOrMore(() => b_nb_literalNext(indent)); 1509 zeroOrMore(() => b_nb_literalNext(indent));
1504 return b_chompedLast(chomping); 1510 return b_chompedLast(chomping);
1505 }); 1511 });
1506 l_chompedEmpty(indent, chomping); 1512 l_chompedEmpty(indent, chomping);
1507 return true; 1513 return true;
1508 }); 1514 });
1509 1515
1510 // 174 1516 // 174
1511 _Node c_l_folded(int indent) => transaction(() { 1517 Node c_l_folded(int indent) => transaction(() {
1512 if (!truth(c_indicator(C_FOLDED))) return null; 1518 if (!truth(c_indicator(C_FOLDED))) return null;
1513 var header = c_b_blockHeader(); 1519 var header = c_b_blockHeader();
1514 if (!truth(header)) return null; 1520 if (!truth(header)) return null;
1515 1521
1516 var additionalIndent = blockScalarAdditionalIndentation(header, indent); 1522 var additionalIndent = blockScalarAdditionalIndentation(header, indent);
1517 var content = l_foldedContent(indent + additionalIndent, header.chomping); 1523 var content = l_foldedContent(indent + additionalIndent, header.chomping);
1518 if (!truth(content)) return null; 1524 if (!truth(content)) return null;
1519 1525
1520 return new _ScalarNode("!", content: content); 1526 return new ScalarNode("!", content: content);
1521 }); 1527 });
1522 1528
1523 // 175 1529 // 175
1524 bool s_nb_foldedText(int indent) => transaction(() { 1530 bool s_nb_foldedText(int indent) => transaction(() {
1525 if (!truth(captureAs('', () => s_indent(indent)))) return false; 1531 if (!truth(captureAs('', () => s_indent(indent)))) return false;
1526 if (!truth(consume(isNonSpace))) return false; 1532 if (!truth(consume(isNonSpace))) return false;
1527 zeroOrMore(() => consume(isNonBreak)); 1533 zeroOrMore(() => consume(isNonBreak));
1528 return true; 1534 return true;
1529 }); 1535 });
1530 1536
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 String l_foldedContent(int indent, int chomping) => captureString(() { 1592 String l_foldedContent(int indent, int chomping) => captureString(() {
1587 transaction(() { 1593 transaction(() {
1588 if (!truth(l_nb_diffLines(indent))) return false; 1594 if (!truth(l_nb_diffLines(indent))) return false;
1589 return b_chompedLast(chomping); 1595 return b_chompedLast(chomping);
1590 }); 1596 });
1591 l_chompedEmpty(indent, chomping); 1597 l_chompedEmpty(indent, chomping);
1592 return true; 1598 return true;
1593 }); 1599 });
1594 1600
1595 // 183 1601 // 183
1596 _SequenceNode l_blockSequence(int indent) => context('sequence', () { 1602 SequenceNode l_blockSequence(int indent) => context('sequence', () {
1597 var additionalIndent = countIndentation() - indent; 1603 var additionalIndent = countIndentation() - indent;
1598 if (additionalIndent <= 0) return null; 1604 if (additionalIndent <= 0) return null;
1599 1605
1600 var content = oneOrMore(() => transaction(() { 1606 var content = oneOrMore(() => transaction(() {
1601 if (!truth(s_indent(indent + additionalIndent))) return null; 1607 if (!truth(s_indent(indent + additionalIndent))) return null;
1602 return c_l_blockSeqEntry(indent + additionalIndent); 1608 return c_l_blockSeqEntry(indent + additionalIndent);
1603 })); 1609 }));
1604 if (!truth(content)) return null; 1610 if (!truth(content)) return null;
1605 1611
1606 return new _SequenceNode("?", content); 1612 return new SequenceNode("?", content);
1607 }); 1613 });
1608 1614
1609 // 184 1615 // 184
1610 _Node c_l_blockSeqEntry(int indent) => transaction(() { 1616 Node c_l_blockSeqEntry(int indent) => transaction(() {
1611 if (!truth(c_indicator(C_SEQUENCE_ENTRY))) return null; 1617 if (!truth(c_indicator(C_SEQUENCE_ENTRY))) return null;
1612 if (isNonSpace(peek())) return null; 1618 if (isNonSpace(peek())) return null;
1613 1619
1614 return s_l_blockIndented(indent, BLOCK_IN); 1620 return s_l_blockIndented(indent, BLOCK_IN);
1615 }); 1621 });
1616 1622
1617 // 185 1623 // 185
1618 _Node s_l_blockIndented(int indent, int ctx) { 1624 Node s_l_blockIndented(int indent, int ctx) {
1619 var additionalIndent = countIndentation(); 1625 var additionalIndent = countIndentation();
1620 return or([ 1626 return or([
1621 () => transaction(() { 1627 () => transaction(() {
1622 if (!truth(s_indent(additionalIndent))) return null; 1628 if (!truth(s_indent(additionalIndent))) return null;
1623 return or([ 1629 return or([
1624 () => ns_l_compactSequence(indent + 1 + additionalIndent), 1630 () => ns_l_compactSequence(indent + 1 + additionalIndent),
1625 () => ns_l_compactMapping(indent + 1 + additionalIndent)]); 1631 () => ns_l_compactMapping(indent + 1 + additionalIndent)]);
1626 }), 1632 }),
1627 () => s_l_blockNode(indent, ctx), 1633 () => s_l_blockNode(indent, ctx),
1628 () => s_l_comments() ? e_node() : null]); 1634 () => s_l_comments() ? e_node() : null]);
1629 } 1635 }
1630 1636
1631 // 186 1637 // 186
1632 _Node ns_l_compactSequence(int indent) => context('sequence', () { 1638 Node ns_l_compactSequence(int indent) => context('sequence', () {
1633 var first = c_l_blockSeqEntry(indent); 1639 var first = c_l_blockSeqEntry(indent);
1634 if (!truth(first)) return null; 1640 if (!truth(first)) return null;
1635 1641
1636 var content = zeroOrMore(() => transaction(() { 1642 var content = zeroOrMore(() => transaction(() {
1637 if (!truth(s_indent(indent))) return null; 1643 if (!truth(s_indent(indent))) return null;
1638 return c_l_blockSeqEntry(indent); 1644 return c_l_blockSeqEntry(indent);
1639 })); 1645 }));
1640 content.insert(0, first); 1646 content.insert(0, first);
1641 1647
1642 return new _SequenceNode("?", content); 1648 return new SequenceNode("?", content);
1643 }); 1649 });
1644 1650
1645 // 187 1651 // 187
1646 _Node l_blockMapping(int indent) => context('mapping', () { 1652 Node l_blockMapping(int indent) => context('mapping', () {
1647 var additionalIndent = countIndentation() - indent; 1653 var additionalIndent = countIndentation() - indent;
1648 if (additionalIndent <= 0) return null; 1654 if (additionalIndent <= 0) return null;
1649 1655
1650 var pairs = oneOrMore(() => transaction(() { 1656 var pairs = oneOrMore(() => transaction(() {
1651 if (!truth(s_indent(indent + additionalIndent))) return null; 1657 if (!truth(s_indent(indent + additionalIndent))) return null;
1652 return ns_l_blockMapEntry(indent + additionalIndent); 1658 return ns_l_blockMapEntry(indent + additionalIndent);
1653 })); 1659 }));
1654 if (!truth(pairs)) return null; 1660 if (!truth(pairs)) return null;
1655 1661
1656 return map(pairs); 1662 return map(pairs);
1657 }); 1663 });
1658 1664
1659 // 188 1665 // 188
1660 _Pair<_Node, _Node> ns_l_blockMapEntry(int indent) => or([ 1666 _Pair<Node, Node> ns_l_blockMapEntry(int indent) => or([
1661 () => c_l_blockMapExplicitEntry(indent), 1667 () => c_l_blockMapExplicitEntry(indent),
1662 () => ns_l_blockMapImplicitEntry(indent) 1668 () => ns_l_blockMapImplicitEntry(indent)
1663 ]); 1669 ]);
1664 1670
1665 // 189 1671 // 189
1666 _Pair<_Node, _Node> c_l_blockMapExplicitEntry(int indent) { 1672 _Pair<Node, Node> c_l_blockMapExplicitEntry(int indent) {
1667 var key = c_l_blockMapExplicitKey(indent); 1673 var key = c_l_blockMapExplicitKey(indent);
1668 if (!truth(key)) return null; 1674 if (!truth(key)) return null;
1669 1675
1670 var value = or([ 1676 var value = or([
1671 () => l_blockMapExplicitValue(indent), 1677 () => l_blockMapExplicitValue(indent),
1672 e_node 1678 e_node
1673 ]); 1679 ]);
1674 1680
1675 return new _Pair<_Node, _Node>(key, value); 1681 return new _Pair<Node, Node>(key, value);
1676 } 1682 }
1677 1683
1678 // 190 1684 // 190
1679 _Node c_l_blockMapExplicitKey(int indent) => transaction(() { 1685 Node c_l_blockMapExplicitKey(int indent) => transaction(() {
1680 if (!truth(c_indicator(C_MAPPING_KEY))) return null; 1686 if (!truth(c_indicator(C_MAPPING_KEY))) return null;
1681 return s_l_blockIndented(indent, BLOCK_OUT); 1687 return s_l_blockIndented(indent, BLOCK_OUT);
1682 }); 1688 });
1683 1689
1684 // 191 1690 // 191
1685 _Node l_blockMapExplicitValue(int indent) => transaction(() { 1691 Node l_blockMapExplicitValue(int indent) => transaction(() {
1686 if (!truth(s_indent(indent))) return null; 1692 if (!truth(s_indent(indent))) return null;
1687 if (!truth(c_indicator(C_MAPPING_VALUE))) return null; 1693 if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
1688 return s_l_blockIndented(indent, BLOCK_OUT); 1694 return s_l_blockIndented(indent, BLOCK_OUT);
1689 }); 1695 });
1690 1696
1691 // 192 1697 // 192
1692 _Pair<_Node, _Node> ns_l_blockMapImplicitEntry(int indent) => transaction(() { 1698 _Pair<Node, Node> ns_l_blockMapImplicitEntry(int indent) => transaction(() {
1693 var key = or([ns_s_blockMapImplicitKey, e_node]); 1699 var key = or([ns_s_blockMapImplicitKey, e_node]);
1694 var value = c_l_blockMapImplicitValue(indent); 1700 var value = c_l_blockMapImplicitValue(indent);
1695 return truth(value) ? new _Pair<_Node, _Node>(key, value) : null; 1701 return truth(value) ? new _Pair<Node, Node>(key, value) : null;
1696 }); 1702 });
1697 1703
1698 // 193 1704 // 193
1699 _Node ns_s_blockMapImplicitKey() => context('mapping key', () => or([ 1705 Node ns_s_blockMapImplicitKey() => context('mapping key', () => or([
1700 () => c_s_implicitJsonKey(BLOCK_KEY), 1706 () => c_s_implicitJsonKey(BLOCK_KEY),
1701 () => ns_s_implicitYamlKey(BLOCK_KEY) 1707 () => ns_s_implicitYamlKey(BLOCK_KEY)
1702 ])); 1708 ]));
1703 1709
1704 // 194 1710 // 194
1705 _Node c_l_blockMapImplicitValue(int indent) => context('mapping value', () => 1711 Node c_l_blockMapImplicitValue(int indent) => context('mapping value', () =>
1706 transaction(() { 1712 transaction(() {
1707 if (!truth(c_indicator(C_MAPPING_VALUE))) return null; 1713 if (!truth(c_indicator(C_MAPPING_VALUE))) return null;
1708 return or([ 1714 return or([
1709 () => s_l_blockNode(indent, BLOCK_OUT), 1715 () => s_l_blockNode(indent, BLOCK_OUT),
1710 () => s_l_comments() ? e_node() : null 1716 () => s_l_comments() ? e_node() : null
1711 ]); 1717 ]);
1712 })); 1718 }));
1713 1719
1714 // 195 1720 // 195
1715 _Node ns_l_compactMapping(int indent) => context('mapping', () { 1721 Node ns_l_compactMapping(int indent) => context('mapping', () {
1716 var first = ns_l_blockMapEntry(indent); 1722 var first = ns_l_blockMapEntry(indent);
1717 if (!truth(first)) return null; 1723 if (!truth(first)) return null;
1718 1724
1719 var pairs = zeroOrMore(() => transaction(() { 1725 var pairs = zeroOrMore(() => transaction(() {
1720 if (!truth(s_indent(indent))) return null; 1726 if (!truth(s_indent(indent))) return null;
1721 return ns_l_blockMapEntry(indent); 1727 return ns_l_blockMapEntry(indent);
1722 })); 1728 }));
1723 pairs.insert(0, first); 1729 pairs.insert(0, first);
1724 1730
1725 return map(pairs); 1731 return map(pairs);
1726 }); 1732 });
1727 1733
1728 // 196 1734 // 196
1729 _Node s_l_blockNode(int indent, int ctx) => or([ 1735 Node s_l_blockNode(int indent, int ctx) => or([
1730 () => s_l_blockInBlock(indent, ctx), 1736 () => s_l_blockInBlock(indent, ctx),
1731 () => s_l_flowInBlock(indent) 1737 () => s_l_flowInBlock(indent)
1732 ]); 1738 ]);
1733 1739
1734 // 197 1740 // 197
1735 _Node s_l_flowInBlock(int indent) => transaction(() { 1741 Node s_l_flowInBlock(int indent) => transaction(() {
1736 if (!truth(s_separate(indent + 1, FLOW_OUT))) return null; 1742 if (!truth(s_separate(indent + 1, FLOW_OUT))) return null;
1737 var node = ns_flowNode(indent + 1, FLOW_OUT); 1743 var node = ns_flowNode(indent + 1, FLOW_OUT);
1738 if (!truth(node)) return null; 1744 if (!truth(node)) return null;
1739 if (!truth(s_l_comments())) return null; 1745 if (!truth(s_l_comments())) return null;
1740 return node; 1746 return node;
1741 }); 1747 });
1742 1748
1743 // 198 1749 // 198
1744 _Node s_l_blockInBlock(int indent, int ctx) => or([ 1750 Node s_l_blockInBlock(int indent, int ctx) => or([
1745 () => s_l_blockScalar(indent, ctx), 1751 () => s_l_blockScalar(indent, ctx),
1746 () => s_l_blockCollection(indent, ctx) 1752 () => s_l_blockCollection(indent, ctx)
1747 ]); 1753 ]);
1748 1754
1749 // 199 1755 // 199
1750 _Node s_l_blockScalar(int indent, int ctx) => transaction(() { 1756 Node s_l_blockScalar(int indent, int ctx) => transaction(() {
1751 if (!truth(s_separate(indent + 1, ctx))) return null; 1757 if (!truth(s_separate(indent + 1, ctx))) return null;
1752 var props = transaction(() { 1758 var props = transaction(() {
1753 var innerProps = c_ns_properties(indent + 1, ctx); 1759 var innerProps = c_ns_properties(indent + 1, ctx);
1754 if (!truth(innerProps)) return null; 1760 if (!truth(innerProps)) return null;
1755 if (!truth(s_separate(indent + 1, ctx))) return null; 1761 if (!truth(s_separate(indent + 1, ctx))) return null;
1756 return innerProps; 1762 return innerProps;
1757 }); 1763 });
1758 1764
1759 var node = or([() => c_l_literal(indent), () => c_l_folded(indent)]); 1765 var node = or([() => c_l_literal(indent), () => c_l_folded(indent)]);
1760 if (!truth(node)) return null; 1766 if (!truth(node)) return null;
1761 return addProps(node, props); 1767 return addProps(node, props);
1762 }); 1768 });
1763 1769
1764 // 200 1770 // 200
1765 _Node s_l_blockCollection(int indent, int ctx) => transaction(() { 1771 Node s_l_blockCollection(int indent, int ctx) => transaction(() {
1766 var props = transaction(() { 1772 var props = transaction(() {
1767 if (!truth(s_separate(indent + 1, ctx))) return null; 1773 if (!truth(s_separate(indent + 1, ctx))) return null;
1768 return c_ns_properties(indent + 1, ctx); 1774 return c_ns_properties(indent + 1, ctx);
1769 }); 1775 });
1770 1776
1771 if (!truth(s_l_comments())) return null; 1777 if (!truth(s_l_comments())) return null;
1772 return or([ 1778 return or([
1773 () => l_blockSequence(seqSpaces(indent, ctx)), 1779 () => l_blockSequence(seqSpaces(indent, ctx)),
1774 () => l_blockMapping(indent)]); 1780 () => l_blockMapping(indent)]);
1775 }); 1781 });
(...skipping 13 matching lines...) Expand all
1789 bool c_documentEnd() => rawString("..."); 1795 bool c_documentEnd() => rawString("...");
1790 1796
1791 // 205 1797 // 205
1792 bool l_documentSuffix() => transaction(() { 1798 bool l_documentSuffix() => transaction(() {
1793 if (!truth(c_documentEnd())) return false; 1799 if (!truth(c_documentEnd())) return false;
1794 return s_l_comments(); 1800 return s_l_comments();
1795 }); 1801 });
1796 1802
1797 // 206 1803 // 206
1798 bool c_forbidden() { 1804 bool c_forbidden() {
1799 if (!inBareDocument || !atStartOfLine) return false; 1805 if (!_inBareDocument || !atStartOfLine) return false;
1800 var forbidden = false; 1806 var forbidden = false;
1801 transaction(() { 1807 transaction(() {
1802 if (!truth(or([c_directivesEnd, c_documentEnd]))) return; 1808 if (!truth(or([c_directivesEnd, c_documentEnd]))) return;
1803 var char = peek(); 1809 var char = peek();
1804 forbidden = isBreak(char) || isSpace(char) || atEndOfFile; 1810 forbidden = isBreak(char) || isSpace(char) || atEndOfFile;
1805 return; 1811 return;
1806 }); 1812 });
1807 return forbidden; 1813 return forbidden;
1808 } 1814 }
1809 1815
1810 // 207 1816 // 207
1811 _Node l_bareDocument() { 1817 Node l_bareDocument() {
1812 try { 1818 try {
1813 inBareDocument = true; 1819 _inBareDocument = true;
1814 return s_l_blockNode(-1, BLOCK_IN); 1820 return s_l_blockNode(-1, BLOCK_IN);
1815 } finally { 1821 } finally {
1816 inBareDocument = false; 1822 _inBareDocument = false;
1817 } 1823 }
1818 } 1824 }
1819 1825
1820 // 208 1826 // 208
1821 _Node l_explicitDocument() { 1827 Node l_explicitDocument() {
1822 if (!truth(c_directivesEnd())) return null; 1828 if (!truth(c_directivesEnd())) return null;
1823 var doc = l_bareDocument(); 1829 var doc = l_bareDocument();
1824 if (truth(doc)) return doc; 1830 if (truth(doc)) return doc;
1825 1831
1826 doc = e_node(); 1832 doc = e_node();
1827 s_l_comments(); 1833 s_l_comments();
1828 return doc; 1834 return doc;
1829 } 1835 }
1830 1836
1831 // 209 1837 // 209
1832 _Node l_directiveDocument() { 1838 Node l_directiveDocument() {
1833 if (!truth(oneOrMore(l_directive))) return null; 1839 if (!truth(oneOrMore(l_directive))) return null;
1834 var doc = l_explicitDocument(); 1840 var doc = l_explicitDocument();
1835 if (doc != null) return doc; 1841 if (doc != null) return doc;
1836 parseFailed(); 1842 parseFailed();
1837 return null; // Unreachable. 1843 return null; // Unreachable.
1838 } 1844 }
1839 1845
1840 // 210 1846 // 210
1841 _Node l_anyDocument() => 1847 Node l_anyDocument() =>
1842 or([l_directiveDocument, l_explicitDocument, l_bareDocument]); 1848 or([l_directiveDocument, l_explicitDocument, l_bareDocument]);
1843 1849
1844 // 211 1850 // 211
1845 List<_Node> l_yamlStream() { 1851 List<Node> l_yamlStream() {
1846 var docs = []; 1852 var docs = [];
1847 zeroOrMore(l_documentPrefix); 1853 zeroOrMore(l_documentPrefix);
1848 var first = zeroOrOne(l_anyDocument); 1854 var first = zeroOrOne(l_anyDocument);
1849 if (!truth(first)) first = e_node(); 1855 if (!truth(first)) first = e_node();
1850 docs.add(first); 1856 docs.add(first);
1851 1857
1852 zeroOrMore(() { 1858 zeroOrMore(() {
1853 var doc; 1859 var doc;
1854 if (truth(oneOrMore(l_documentSuffix))) { 1860 if (truth(oneOrMore(l_documentSuffix))) {
1855 zeroOrMore(l_documentPrefix); 1861 zeroOrMore(l_documentPrefix);
1856 doc = zeroOrOne(l_anyDocument); 1862 doc = zeroOrOne(l_anyDocument);
1857 } else { 1863 } else {
1858 zeroOrMore(l_documentPrefix); 1864 zeroOrMore(l_documentPrefix);
1859 doc = zeroOrOne(l_explicitDocument); 1865 doc = zeroOrOne(l_explicitDocument);
1860 } 1866 }
1861 if (truth(doc)) docs.add(doc); 1867 if (truth(doc)) docs.add(doc);
1862 return doc; 1868 return doc;
1863 }); 1869 });
1864 1870
1865 if (!atEndOfFile) parseFailed(); 1871 if (!atEndOfFile) parseFailed();
1866 return docs; 1872 return docs;
1867 } 1873 }
1868 } 1874 }
1869 1875
1870 class SyntaxError extends YamlException { 1876 class SyntaxError extends YamlException {
1871 final int line; 1877 final int _line;
1872 final int column; 1878 final int _column;
1873 1879
1874 SyntaxError(this.line, this.column, String msg) : super(msg); 1880 SyntaxError(this._line, this._column, String msg) : super(msg);
1875 1881
1876 String toString() => "Syntax error on line $line, column $column: $msg"; 1882 String toString() => "Syntax error on line $_line, column $_column: "
1883 "${super.toString()}";
1877 } 1884 }
1878 1885
1879 /// A pair of values. 1886 /// A pair of values.
1880 class _Pair<E, F> { 1887 class _Pair<E, F> {
1881 E first; 1888 E first;
1882 F last; 1889 F last;
1883 1890
1884 _Pair(this.first, this.last); 1891 _Pair(this.first, this.last);
1885 1892
1886 String toString() => '($first, $last)'; 1893 String toString() => '($first, $last)';
(...skipping 22 matching lines...) Expand all
1909 1916
1910 /// Returns whether or not [pos] lies within this range. 1917 /// Returns whether or not [pos] lies within this range.
1911 bool contains(int pos) => pos >= start && pos <= end; 1918 bool contains(int pos) => pos >= start && pos <= end;
1912 } 1919 }
1913 1920
1914 /// A map that associates [E] values with [_Range]s. It's efficient to create 1921 /// A map that associates [E] values with [_Range]s. It's efficient to create
1915 /// new associations, but finding the value associated with a position is more 1922 /// new associations, but finding the value associated with a position is more
1916 /// expensive. 1923 /// expensive.
1917 class _RangeMap<E> { 1924 class _RangeMap<E> {
1918 /// The ranges and their associated elements. 1925 /// The ranges and their associated elements.
1919 final List<_Pair<_Range, E>> contents; 1926 final List<_Pair<_Range, E>> _contents = <_Pair<_Range, E>>[];
1920 1927
1921 _RangeMap() : this.contents = <_Pair<_Range, E>>[]; 1928 _RangeMap();
1922 1929
1923 /// Returns the value associated with the range in which [pos] lies, or null 1930 /// Returns the value associated with the range in which [pos] lies, or null
1924 /// if there is no such range. If there's more than one such range, the most 1931 /// if there is no such range. If there's more than one such range, the most
1925 /// recently set one is used. 1932 /// recently set one is used.
1926 E operator[](int pos) { 1933 E operator[](int pos) {
1927 // Iterate backwards through contents so the more recent range takes 1934 // Iterate backwards through contents so the more recent range takes
1928 // precedence. TODO(nweiz): clean this up when issue 2804 is fixed. 1935 // precedence.
1929 for (var i = contents.length - 1; i >= 0; i--) { 1936 for (var pair in _contents.reversed) {
1930 var pair = contents[i];
1931 if (pair.first.contains(pos)) return pair.last; 1937 if (pair.first.contains(pos)) return pair.last;
1932 } 1938 }
1933 return null; 1939 return null;
1934 } 1940 }
1935 1941
1936 /// Associates [value] with [range]. 1942 /// Associates [value] with [range].
1937 operator[]=(_Range range, E value) => 1943 operator[]=(_Range range, E value) =>
1938 contents.add(new _Pair<_Range, E>(range, value)); 1944 _contents.add(new _Pair<_Range, E>(range, value));
1939 } 1945 }
OLDNEW
« no previous file with comments | « pkg/yaml/lib/src/model.dart ('k') | pkg/yaml/lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698