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

Side by Side Diff: utils/pub/yaml/parser.dart

Issue 11638010: Convert /** comments to /// in pub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Respond to review. Created 8 years 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 | « utils/pub/yaml/model.dart ('k') | utils/pub/yaml/visitor.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 part of yaml;
6 6
7 /** 7 /// Translates a string of characters into a YAML serialization tree.
8 * Translates a string of characters into a YAML serialization tree. 8 ///
9 * 9 /// This parser is designed to closely follow the spec. All productions in the
10 * 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
11 * 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
12 * numbers. This is certainly not the most efficient way of parsing YAML, but it 12 /// it is the easiest to write and read in the context of the spec.
13 * is the easiest to write and read in the context of the spec. 13 ///
14 * 14 /// Methods corresponding to productions are also named as in the spec,
15 * Methods corresponding to productions are also named as in the spec, 15 /// translating the name of the method (although not the annotation characters)
16 * 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
17 * into camel-case for dart style.. For example, the spec has a production named 17 /// named `nb-ns-plain-in-line`, and the method implementing it is named
18 * `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
19 * `nb_ns_plainInLine`. The exception to that rule is methods that just 19 /// recognize character classes; these are named `is*`.
20 * recognize character classes; these are named `is*`.
21 */
22 class _Parser { 20 class _Parser {
23 static const TAB = 0x9; 21 static const TAB = 0x9;
24 static const LF = 0xA; 22 static const LF = 0xA;
25 static const CR = 0xD; 23 static const CR = 0xD;
26 static const SP = 0x20; 24 static const SP = 0x20;
27 static const TILDE = 0x7E; 25 static const TILDE = 0x7E;
28 static const NEL = 0x85; 26 static const NEL = 0x85;
29 static const PLUS = 0x2B; 27 static const PLUS = 0x2B;
30 static const HYPHEN = 0x2D; 28 static const HYPHEN = 0x2D;
31 static const QUESTION_MARK = 0x3F; 29 static const QUESTION_MARK = 0x3F;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 static const BLOCK_IN = 1; 103 static const BLOCK_IN = 1;
106 static const FLOW_OUT = 2; 104 static const FLOW_OUT = 2;
107 static const FLOW_IN = 3; 105 static const FLOW_IN = 3;
108 static const BLOCK_KEY = 4; 106 static const BLOCK_KEY = 4;
109 static const FLOW_KEY = 5; 107 static const FLOW_KEY = 5;
110 108
111 static const CHOMPING_STRIP = 0; 109 static const CHOMPING_STRIP = 0;
112 static const CHOMPING_KEEP = 1; 110 static const CHOMPING_KEEP = 1;
113 static const CHOMPING_CLIP = 2; 111 static const CHOMPING_CLIP = 2;
114 112
115 /** The source string being parsed. */ 113 /// The source string being parsed.
116 final String s; 114 final String s;
117 115
118 /** The current position in the source string. */ 116 /// The current position in the source string.
119 int pos = 0; 117 int pos = 0;
120 118
121 /** The length of the string being parsed. */ 119 /// The length of the string being parsed.
122 final int len; 120 final int len;
123 121
124 /** The current (0-based) line in the source string. */ 122 /// The current (0-based) line in the source string.
125 int line = 0; 123 int line = 0;
126 124
127 /** The current (0-based) column in the source string. */ 125 /// The current (0-based) column in the source string.
128 int column = 0; 126 int column = 0;
129 127
130 /** 128 /// Whether we're parsing a bare document (that is, one that doesn't begin
131 * Whether we're parsing a bare document (that is, one that doesn't begin with 129 /// with `---`). Bare documents don't allow `%` immediately following
132 * `---`). Bare documents don't allow `%` immediately following newlines. 130 /// newlines.
133 */
134 bool inBareDocument = false; 131 bool inBareDocument = false;
135 132
136 /** 133 /// The line number of the farthest position that has been parsed successfully
137 * The line number of the farthest position that has been parsed successfully 134 /// before backtracking. Used for error reporting.
138 * before backtracking. Used for error reporting.
139 */
140 int farthestLine = 0; 135 int farthestLine = 0;
141 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.
145 */
146 int farthestColumn = 0; 139 int farthestColumn = 0;
147 140
148 /** 141 /// The farthest position in the source string that has been parsed
149 * The farthest position in the source string that has been parsed 142 /// successfully before backtracking. Used for error reporting.
150 * successfully before backtracking. Used for error reporting.
151 */
152 int farthestPos = 0; 143 int farthestPos = 0;
153 144
154 /** 145 /// The name of the context of the farthest position that has been parsed
155 * The name of the context of the farthest position that has been parsed 146 /// successfully before backtracking. Used for error reporting.
156 * successfully before backtracking. Used for error reporting.
157 */
158 String farthestContext = "document"; 147 String farthestContext = "document";
159 148
160 /** A stack of the names of parse contexts. Used for error reporting. */ 149 /// A stack of the names of parse contexts. Used for error reporting.
161 List<String> contextStack; 150 List<String> contextStack;
162 151
163 /** 152 /// Annotations attached to ranges of the source string that add extra
164 * Annotations attached to ranges of the source string that add extra 153 /// information to any errors that occur in the annotated range.
165 * information to any errors that occur in the annotated range.
166 */
167 _RangeMap<String> errorAnnotations; 154 _RangeMap<String> errorAnnotations;
168 155
169 /** 156 /// The buffer containing the string currently being captured.
170 * The buffer containing the string currently being captured.
171 */
172 StringBuffer capturedString; 157 StringBuffer capturedString;
173 158
174 /** 159 /// The beginning of the current section of the captured string.
175 * The beginning of the current section of the captured string.
176 */
177 int captureStart; 160 int captureStart;
178 161
179 /** 162 /// Whether the current string capture is being overridden.
180 * Whether the current string capture is being overridden.
181 */
182 bool capturingAs = false; 163 bool capturingAs = false;
183 164
184 _Parser(String s) 165 _Parser(String s)
185 : this.s = s, 166 : this.s = s,
186 len = s.length, 167 len = s.length,
187 contextStack = <String>["document"], 168 contextStack = <String>["document"],
188 errorAnnotations = new _RangeMap(); 169 errorAnnotations = new _RangeMap();
189 170
190 /** 171 /// Return the character at the current position, then move that position
191 * Return the character at the current position, then move that position 172 /// forward one character. Also updates the current line and column numbers.
192 * forward one character. Also updates the current line and column numbers.
193 */
194 int next() { 173 int next() {
195 if (pos == len) return -1; 174 if (pos == len) return -1;
196 var char = s.charCodeAt(pos++); 175 var char = s.charCodeAt(pos++);
197 if (isBreak(char)) { 176 if (isBreak(char)) {
198 line++; 177 line++;
199 column = 0; 178 column = 0;
200 } else { 179 } else {
201 column++; 180 column++;
202 } 181 }
203 182
204 if (farthestLine < line) { 183 if (farthestLine < line) {
205 farthestLine = line; 184 farthestLine = line;
206 farthestColumn = column; 185 farthestColumn = column;
207 farthestContext = contextStack.last; 186 farthestContext = contextStack.last;
208 } else if (farthestLine == line && farthestColumn < column) { 187 } else if (farthestLine == line && farthestColumn < column) {
209 farthestColumn = column; 188 farthestColumn = column;
210 farthestContext = contextStack.last; 189 farthestContext = contextStack.last;
211 } 190 }
212 farthestPos = pos; 191 farthestPos = pos;
213 192
214 return char; 193 return char;
215 } 194 }
216 195
217 /** 196 /// Returns the character at the current position, or the character [i]
218 * Returns the character at the current position, or the character [i] 197 /// characters after the current position.
219 * characters after the current position. 198 ///
220 * 199 /// Returns -1 if this would return a character after the end or before the
221 * Returns -1 if this would return a character after the end or before the 200 /// beginning of the input string.
222 * beginning of the input string.
223 */
224 int peek([int i = 0]) { 201 int peek([int i = 0]) {
225 var peekPos = pos + i; 202 var peekPos = pos + i;
226 return (peekPos >= len || peekPos < 0) ? -1 : s.charCodeAt(peekPos); 203 return (peekPos >= len || peekPos < 0) ? -1 : s.charCodeAt(peekPos);
227 } 204 }
228 205
229 /** 206 /// The truthiness operator. Returns `false` if [obj] is `null` or `false`,
230 * The truthiness operator. Returns `false` if [obj] is `null` or `false`, 207 /// `true` otherwise.
231 * `true` otherwise.
232 */
233 bool truth(obj) => obj != null && obj != false; 208 bool truth(obj) => obj != null && obj != false;
234 209
235 /** 210 /// Consumes the current character if it matches [matcher]. Returns the result
236 * Consumes the current character if it matches [matcher]. Returns the result 211 /// of [matcher].
237 * of [matcher].
238 */
239 bool consume(bool matcher(int)) { 212 bool consume(bool matcher(int)) {
240 if (matcher(peek())) { 213 if (matcher(peek())) {
241 next(); 214 next();
242 return true; 215 return true;
243 } 216 }
244 return false; 217 return false;
245 } 218 }
246 219
247 /** 220 /// Consumes the current character if it equals [char].
248 * Consumes the current character if it equals [char].
249 */
250 bool consumeChar(int char) => consume((c) => c == char); 221 bool consumeChar(int char) => consume((c) => c == char);
251 222
252 /** 223 /// Calls [consumer] until it returns a falsey value. Returns a list of all
253 * Calls [consumer] until it returns a falsey value. Returns a list of all 224 /// truthy return values of [consumer], or null if it didn't consume anything.
254 * truthy return values of [consumer], or null if it didn't consume anything. 225 ///
255 * 226 /// Conceptually, repeats a production one or more times.
256 * Conceptually, repeats a production one or more times.
257 */
258 List oneOrMore(consumer()) { 227 List oneOrMore(consumer()) {
259 var first = consumer(); 228 var first = consumer();
260 if (!truth(first)) return null; 229 if (!truth(first)) return null;
261 var out = [first]; 230 var out = [first];
262 while (true) { 231 while (true) {
263 var el = consumer(); 232 var el = consumer();
264 if (!truth(el)) return out; 233 if (!truth(el)) return out;
265 out.add(el); 234 out.add(el);
266 } 235 }
267 return null; // Unreachable. 236 return null; // Unreachable.
268 } 237 }
269 238
270 /** 239 /// Calls [consumer] until it returns a falsey value. Returns a list of all
271 * 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
272 * truthy return values of [consumer], or the empty list if it didn't consume 241 /// anything.
273 * anything. 242 ///
274 * 243 /// Conceptually, repeats a production any number of times.
275 * Conceptually, repeats a production any number of times.
276 */
277 List zeroOrMore(consumer()) { 244 List zeroOrMore(consumer()) {
278 var out = []; 245 var out = [];
279 var oldPos = pos; 246 var oldPos = pos;
280 while (true) { 247 while (true) {
281 var el = consumer(); 248 var el = consumer();
282 if (!truth(el) || oldPos == pos) return out; 249 if (!truth(el) || oldPos == pos) return out;
283 oldPos = pos; 250 oldPos = pos;
284 out.add(el); 251 out.add(el);
285 } 252 }
286 return null; // Unreachable. 253 return null; // Unreachable.
287 } 254 }
288 255
289 /** 256 /// Just calls [consumer] and returns its result. Used to make it explicit
290 * Just calls [consumer] and returns its result. Used to make it explicit that 257 /// that a production is intended to be optional.
291 * a production is intended to be optional.
292 */
293 zeroOrOne(consumer()) => consumer(); 258 zeroOrOne(consumer()) => consumer();
294 259
295 /** 260 /// Calls each function in [consumers] until one returns a truthy value, then
296 * Calls each function in [consumers] until one returns a truthy value, then 261 /// returns that.
297 * returns that.
298 */
299 or(List<Function> consumers) { 262 or(List<Function> consumers) {
300 for (var c in consumers) { 263 for (var c in consumers) {
301 var res = c(); 264 var res = c();
302 if (truth(res)) return res; 265 if (truth(res)) return res;
303 } 266 }
304 return null; 267 return null;
305 } 268 }
306 269
307 /** 270 /// Calls [consumer] and returns its result, but rolls back the parser state
308 * Calls [consumer] and returns its result, but rolls back the parser state if 271 /// if [consumer] returns a falsey value.
309 * [consumer] returns a falsey value.
310 */
311 transaction(consumer()) { 272 transaction(consumer()) {
312 var oldPos = pos; 273 var oldPos = pos;
313 var oldLine = line; 274 var oldLine = line;
314 var oldColumn = column; 275 var oldColumn = column;
315 var oldCaptureStart = captureStart; 276 var oldCaptureStart = captureStart;
316 String capturedSoFar = capturedString == null ? null : 277 String capturedSoFar = capturedString == null ? null :
317 capturedString.toString(); 278 capturedString.toString();
318 var res = consumer(); 279 var res = consumer();
319 if (truth(res)) return res; 280 if (truth(res)) return res;
320 281
321 pos = oldPos; 282 pos = oldPos;
322 line = oldLine; 283 line = oldLine;
323 column = oldColumn; 284 column = oldColumn;
324 captureStart = oldCaptureStart; 285 captureStart = oldCaptureStart;
325 capturedString = capturedSoFar == null ? null : 286 capturedString = capturedSoFar == null ? null :
326 new StringBuffer(capturedSoFar); 287 new StringBuffer(capturedSoFar);
327 return res; 288 return res;
328 } 289 }
329 290
330 /** 291 /// Consumes [n] characters matching [matcher], or none if there isn't a
331 * 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
332 * complete match. The first argument to [matcher] is the character code, the 293 /// second is the index (from 0 to [n] - 1).
333 * second is the index (from 0 to [n] - 1). 294 ///
334 * 295 /// Returns whether or not the characters were consumed.
335 * Returns whether or not the characters were consumed.
336 */
337 bool nAtOnce(int n, bool matcher(int c, int i)) => transaction(() { 296 bool nAtOnce(int n, bool matcher(int c, int i)) => transaction(() {
338 for (int i = 0; i < n; i++) { 297 for (int i = 0; i < n; i++) {
339 if (!consume((c) => matcher(c, i))) return false; 298 if (!consume((c) => matcher(c, i))) return false;
340 } 299 }
341 return true; 300 return true;
342 }); 301 });
343 302
344 /** 303 /// Consumes the exact characters in [str], or nothing.
345 * Consumes the exact characters in [str], or nothing. 304 ///
346 * 305 /// Returns whether or not the string was consumed.
347 * Returns whether or not the string was consumed.
348 */
349 bool rawString(String str) => 306 bool rawString(String str) =>
350 nAtOnce(str.length, (c, i) => str.charCodeAt(i) == c); 307 nAtOnce(str.length, (c, i) => str.charCodeAt(i) == c);
351 308
352 /** 309 /// Consumes and returns a string of characters matching [matcher], or null if
353 * Consumes and returns a string of characters matching [matcher], or null if 310 /// there are no such characters.
354 * there are no such characters.
355 */
356 String stringOf(bool matcher(int)) => 311 String stringOf(bool matcher(int)) =>
357 captureString(() => oneOrMore(() => consume(matcher))); 312 captureString(() => oneOrMore(() => consume(matcher)));
358 313
359 /** 314 /// Calls [consumer] and returns the string that was consumed while doing so,
360 * Calls [consumer] and returns the string that was consumed while doing so, 315 /// or null if [consumer] returned a falsey value. Automatically wraps
361 * or null if [consumer] returned a falsey value. Automatically wraps 316 /// [consumer] in `transaction`.
362 * [consumer] in `transaction`.
363 */
364 String captureString(consumer()) { 317 String captureString(consumer()) {
365 // captureString calls may not be nested 318 // captureString calls may not be nested
366 assert(capturedString == null); 319 assert(capturedString == null);
367 320
368 captureStart = pos; 321 captureStart = pos;
369 capturedString = new StringBuffer(); 322 capturedString = new StringBuffer();
370 var res = transaction(consumer); 323 var res = transaction(consumer);
371 if (!truth(res)) { 324 if (!truth(res)) {
372 captureStart = null; 325 captureStart = null;
373 capturedString = null; 326 capturedString = null;
(...skipping 23 matching lines...) Expand all
397 capturedString.add(transformation(s.substring(captureStart, pos))); 350 capturedString.add(transformation(s.substring(captureStart, pos)));
398 captureStart = pos; 351 captureStart = pos;
399 return res; 352 return res;
400 } 353 }
401 354
402 void flushCapture() { 355 void flushCapture() {
403 capturedString.add(s.substring(captureStart, pos)); 356 capturedString.add(s.substring(captureStart, pos));
404 captureStart = pos; 357 captureStart = pos;
405 } 358 }
406 359
407 /** 360 /// Adds a tag and an anchor to [node], if they're defined.
408 * Adds a tag and an anchor to [node], if they're defined.
409 */
410 _Node addProps(_Node node, _Pair<_Tag, String> props) { 361 _Node addProps(_Node node, _Pair<_Tag, String> props) {
411 if (props == null || node == null) return node; 362 if (props == null || node == null) return node;
412 if (truth(props.first)) node.tag = props.first; 363 if (truth(props.first)) node.tag = props.first;
413 if (truth(props.last)) node.anchor = props.last; 364 if (truth(props.last)) node.anchor = props.last;
414 return node; 365 return node;
415 } 366 }
416 367
417 /** Creates a MappingNode from [pairs]. */ 368 /// Creates a MappingNode from [pairs].
418 _MappingNode map(List<_Pair<_Node, _Node>> pairs) { 369 _MappingNode map(List<_Pair<_Node, _Node>> pairs) {
419 var content = new Map<_Node, _Node>(); 370 var content = new Map<_Node, _Node>();
420 pairs.forEach((pair) => content[pair.first] = pair.last); 371 pairs.forEach((pair) => content[pair.first] = pair.last);
421 return new _MappingNode("?", content); 372 return new _MappingNode("?", content);
422 } 373 }
423 374
424 /** Runs [fn] in a context named [name]. Used for error reporting. */ 375 /// Runs [fn] in a context named [name]. Used for error reporting.
425 context(String name, fn()) { 376 context(String name, fn()) {
426 try { 377 try {
427 contextStack.add(name); 378 contextStack.add(name);
428 return fn(); 379 return fn();
429 } finally { 380 } finally {
430 var popped = contextStack.removeLast(); 381 var popped = contextStack.removeLast();
431 assert(popped == name); 382 assert(popped == name);
432 } 383 }
433 } 384 }
434 385
435 /** 386 /// Adds [message] as extra information to any errors that occur between the
436 * 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
437 * current position and the position of the cursor after running [fn]. The 388 /// cursor is reset after [fn] is run.
438 * cursor is reset after [fn] is run.
439 */
440 annotateError(String message, fn()) { 389 annotateError(String message, fn()) {
441 var start = pos; 390 var start = pos;
442 var end; 391 var end;
443 transaction(() { 392 transaction(() {
444 fn(); 393 fn();
445 end = pos; 394 end = pos;
446 return false; 395 return false;
447 }); 396 });
448 errorAnnotations[new _Range(start, end)] = message; 397 errorAnnotations[new _Range(start, end)] = message;
449 } 398 }
450 399
451 /** Throws an error with additional context information. */ 400 /// Throws an error with additional context information.
452 error(String message) { 401 error(String message) {
453 // Line and column should be one-based. 402 // Line and column should be one-based.
454 throw new SyntaxError(line + 1, column + 1, 403 throw new SyntaxError(line + 1, column + 1,
455 "$message (in $farthestContext)"); 404 "$message (in $farthestContext)");
456 } 405 }
457 406
458 /** 407 /// If [result] is falsey, throws an error saying that [expected] was
459 * If [result] is falsey, throws an error saying that [expected] was 408 /// expected.
460 * expected.
461 */
462 expect(result, String expected) { 409 expect(result, String expected) {
463 if (truth(result)) return result; 410 if (truth(result)) return result;
464 error("expected $expected"); 411 error("expected $expected");
465 } 412 }
466 413
467 /** 414 /// Throws an error saying that the parse failed. Uses [farthestLine],
468 * Throws an error saying that the parse failed. Uses [farthestLine], 415 /// [farthestColumn], and [farthestContext] to provide additional information.
469 * [farthestColumn], and [farthestContext] to provide additional information.
470 */
471 parseFailed() { 416 parseFailed() {
472 var message = "invalid YAML in $farthestContext"; 417 var message = "invalid YAML in $farthestContext";
473 var extraError = errorAnnotations[farthestPos]; 418 var extraError = errorAnnotations[farthestPos];
474 if (extraError != null) message = "$message ($extraError)"; 419 if (extraError != null) message = "$message ($extraError)";
475 throw new SyntaxError(farthestLine + 1, farthestColumn + 1, message); 420 throw new SyntaxError(farthestLine + 1, farthestColumn + 1, message);
476 } 421 }
477 422
478 /** Returns the number of spaces after the current position. */ 423 /// Returns the number of spaces after the current position.
479 int countIndentation() { 424 int countIndentation() {
480 var i = 0; 425 var i = 0;
481 while (peek(i) == SP) i++; 426 while (peek(i) == SP) i++;
482 return i; 427 return i;
483 } 428 }
484 429
485 /** Returns the indentation for a block scalar. */ 430 /// Returns the indentation for a block scalar.
486 int blockScalarAdditionalIndentation(_BlockHeader header, int indent) { 431 int blockScalarAdditionalIndentation(_BlockHeader header, int indent) {
487 if (!header.autoDetectIndent) return header.additionalIndent; 432 if (!header.autoDetectIndent) return header.additionalIndent;
488 433
489 var maxSpaces = 0; 434 var maxSpaces = 0;
490 var maxSpacesLine = 0; 435 var maxSpacesLine = 0;
491 var spaces = 0; 436 var spaces = 0;
492 transaction(() { 437 transaction(() {
493 do { 438 do {
494 spaces = captureString(() => zeroOrMore(() => consumeChar(SP))).length; 439 spaces = captureString(() => zeroOrMore(() => consumeChar(SP))).length;
495 if (spaces > maxSpaces) { 440 if (spaces > maxSpaces) {
(...skipping 13 matching lines...) Expand all
509 // non-empty line. 454 // non-empty line.
510 if (maxSpaces > spaces) { 455 if (maxSpaces > spaces) {
511 throw new SyntaxError(maxSpacesLine + 1, maxSpaces, 456 throw new SyntaxError(maxSpacesLine + 1, maxSpaces,
512 "Leading empty lines may not be indented more than the first " 457 "Leading empty lines may not be indented more than the first "
513 "non-empty line."); 458 "non-empty line.");
514 } 459 }
515 460
516 return spaces - indent; 461 return spaces - indent;
517 } 462 }
518 463
519 /** Returns whether the current position is at the beginning of a line. */ 464 /// Returns whether the current position is at the beginning of a line.
520 bool get atStartOfLine => column == 0; 465 bool get atStartOfLine => column == 0;
521 466
522 /** Returns whether the current position is at the end of the input. */ 467 /// Returns whether the current position is at the end of the input.
523 bool get atEndOfFile => pos == len; 468 bool get atEndOfFile => pos == len;
524 469
525 /** 470 /// Given an indicator character, returns the type of that indicator (or null
526 * Given an indicator character, returns the type of that indicator (or null 471 /// if the indicator isn't found.
527 * if the indicator isn't found.
528 */
529 int indicatorType(int char) { 472 int indicatorType(int char) {
530 switch (char) { 473 switch (char) {
531 case HYPHEN: return C_SEQUENCE_ENTRY; 474 case HYPHEN: return C_SEQUENCE_ENTRY;
532 case QUESTION_MARK: return C_MAPPING_KEY; 475 case QUESTION_MARK: return C_MAPPING_KEY;
533 case COLON: return C_MAPPING_VALUE; 476 case COLON: return C_MAPPING_VALUE;
534 case COMMA: return C_COLLECT_ENTRY; 477 case COMMA: return C_COLLECT_ENTRY;
535 case LEFT_BRACKET: return C_SEQUENCE_START; 478 case LEFT_BRACKET: return C_SEQUENCE_START;
536 case RIGHT_BRACKET: return C_SEQUENCE_END; 479 case RIGHT_BRACKET: return C_SEQUENCE_END;
537 case LEFT_BRACE: return C_MAPPING_START; 480 case LEFT_BRACE: return C_MAPPING_START;
538 case RIGHT_BRACE: return C_MAPPING_END; 481 case RIGHT_BRACE: return C_MAPPING_END;
(...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 1869
1927 class SyntaxError extends YamlException { 1870 class SyntaxError extends YamlException {
1928 final int line; 1871 final int line;
1929 final int column; 1872 final int column;
1930 1873
1931 SyntaxError(this.line, this.column, String msg) : super(msg); 1874 SyntaxError(this.line, this.column, String msg) : super(msg);
1932 1875
1933 String toString() => "Syntax error on line $line, column $column: $msg"; 1876 String toString() => "Syntax error on line $line, column $column: $msg";
1934 } 1877 }
1935 1878
1936 /** A pair of values. */ 1879 /// A pair of values.
1937 class _Pair<E, F> { 1880 class _Pair<E, F> {
1938 E first; 1881 E first;
1939 F last; 1882 F last;
1940 1883
1941 _Pair(this.first, this.last); 1884 _Pair(this.first, this.last);
1942 1885
1943 String toString() => '($first, $last)'; 1886 String toString() => '($first, $last)';
1944 } 1887 }
1945 1888
1946 /** The information in the header for a block scalar. */ 1889 /// The information in the header for a block scalar.
1947 class _BlockHeader { 1890 class _BlockHeader {
1948 final int additionalIndent; 1891 final int additionalIndent;
1949 final int chomping; 1892 final int chomping;
1950 1893
1951 _BlockHeader(this.additionalIndent, this.chomping); 1894 _BlockHeader(this.additionalIndent, this.chomping);
1952 1895
1953 bool get autoDetectIndent => additionalIndent == null; 1896 bool get autoDetectIndent => additionalIndent == null;
1954 } 1897 }
1955 1898
1956 /** 1899 /// A range of characters in the YAML document, from [start] to [end]
1957 * A range of characters in the YAML document, from [start] to [end] (inclusive) . 1900 /// (inclusive).
1958 */
1959 class _Range { 1901 class _Range {
1960 /** The first character in the range. */ 1902 /// The first character in the range.
1961 final int start; 1903 final int start;
1962 1904
1963 /** The last character in the range. */ 1905 /// The last character in the range.
1964 final int end; 1906 final int end;
1965 1907
1966 _Range(this.start, this.end); 1908 _Range(this.start, this.end);
1967 1909
1968 /** Returns whether or not [pos] lies within this range. */ 1910 /// Returns whether or not [pos] lies within this range.
1969 bool contains(int pos) => pos >= start && pos <= end; 1911 bool contains(int pos) => pos >= start && pos <= end;
1970 } 1912 }
1971 1913
1972 /** 1914 /// A map that associates [E] values with [_Range]s. It's efficient to create
1973 * A map that associates [E] values with [_Range]s. It's efficient to create new 1915 /// new associations, but finding the value associated with a position is more
1974 * associations, but finding the value associated with a position is more 1916 /// expensive.
1975 * expensive.
1976 */
1977 class _RangeMap<E> { 1917 class _RangeMap<E> {
1978 /** The ranges and their associated elements. */ 1918 /// The ranges and their associated elements.
1979 final List<_Pair<_Range, E>> contents; 1919 final List<_Pair<_Range, E>> contents;
1980 1920
1981 _RangeMap() : this.contents = <_Pair<_Range, E>>[]; 1921 _RangeMap() : this.contents = <_Pair<_Range, E>>[];
1982 1922
1983 /** 1923 /// Returns the value associated with the range in which [pos] lies, or null
1984 * Returns the value associated with the range in which [pos] lies, or null if 1924 /// if there is no such range. If there's more than one such range, the most
1985 * there is no such range. If there's more than one such range, the most 1925 /// recently set one is used.
1986 * recently set one is used.
1987 */
1988 E operator[](int pos) { 1926 E operator[](int pos) {
1989 // Iterate backwards through contents so the more recent range takes 1927 // Iterate backwards through contents so the more recent range takes
1990 // precedence. TODO(nweiz): clean this up when issue 2804 is fixed. 1928 // precedence. TODO(nweiz): clean this up when issue 2804 is fixed.
1991 for (var i = contents.length - 1; i >= 0; i--) { 1929 for (var i = contents.length - 1; i >= 0; i--) {
1992 var pair = contents[i]; 1930 var pair = contents[i];
1993 if (pair.first.contains(pos)) return pair.last; 1931 if (pair.first.contains(pos)) return pair.last;
1994 } 1932 }
1995 return null; 1933 return null;
1996 } 1934 }
1997 1935
1998 /** Associates [value] with [range]. */ 1936 /// Associates [value] with [range].
1999 operator[]=(_Range range, E value) => 1937 operator[]=(_Range range, E value) =>
2000 contents.add(new _Pair<_Range, E>(range, value)); 1938 contents.add(new _Pair<_Range, E>(range, value));
2001 } 1939 }
OLDNEW
« no previous file with comments | « utils/pub/yaml/model.dart ('k') | utils/pub/yaml/visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698