| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 library fasta.scanner.array_based_scanner; | 5 library fasta.scanner.array_based_scanner; |
| 6 | 6 |
| 7 import 'error_token.dart' show ErrorToken, UnmatchedToken; | 7 import 'error_token.dart' show ErrorToken, UnmatchedToken; |
| 8 | 8 |
| 9 import '../../scanner/token.dart' | 9 import '../../scanner/token.dart' |
| 10 show | 10 show |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 void discardOpenLt() { | 272 void discardOpenLt() { |
| 273 while (!groupingStack.isEmpty && | 273 while (!groupingStack.isEmpty && |
| 274 identical(groupingStack.head.kind, LT_TOKEN)) { | 274 identical(groupingStack.head.kind, LT_TOKEN)) { |
| 275 groupingStack = groupingStack.tail; | 275 groupingStack = groupingStack.tail; |
| 276 } | 276 } |
| 277 } | 277 } |
| 278 | 278 |
| 279 /** | 279 /** |
| 280 * This method is called to discard '${' from the "grouping" stack. | 280 * This method is called to discard '${' from the "grouping" stack. |
| 281 * | 281 * |
| 282 * This method is called when the scanner finds the end of a string | 282 * This method is called when the scanner finds an unterminated |
| 283 * or an unterminated string. | 283 * interpolation expression. |
| 284 */ | 284 */ |
| 285 void discardInterpolation() { | 285 void discardInterpolation() { |
| 286 if (groupingStack.isEmpty) return; | 286 while (!groupingStack.isEmpty) { |
| 287 BeginToken begin = groupingStack.head; | 287 BeginToken beginToken = groupingStack.head; |
| 288 if (begin.kind != STRING_INTERPOLATION_TOKEN) return; | 288 unmatchedBeginGroup(beginToken); |
| 289 unmatchedBeginGroup(begin); | 289 groupingStack = groupingStack.tail; |
| 290 groupingStack = groupingStack.tail; | 290 if (identical(beginToken.kind, STRING_INTERPOLATION_TOKEN)) break; |
| 291 } |
| 291 } | 292 } |
| 292 | 293 |
| 293 void unmatchedBeginGroup(BeginToken begin) { | 294 void unmatchedBeginGroup(BeginToken begin) { |
| 294 // We want to ensure that unmatched BeginTokens are reported as | 295 // We want to ensure that unmatched BeginTokens are reported as |
| 295 // errors. However, the diet parser assumes that groups are well-balanced | 296 // errors. However, the diet parser assumes that groups are well-balanced |
| 296 // and will never look at the endGroup token. This is a nice property that | 297 // and will never look at the endGroup token. This is a nice property that |
| 297 // allows us to skip quickly over correct code. By inserting an additional | 298 // allows us to skip quickly over correct code. By inserting an additional |
| 298 // synthetic token in the stream, we can keep ignoring endGroup tokens. | 299 // synthetic token in the stream, we can keep ignoring endGroup tokens. |
| 299 // | 300 // |
| 300 // [begin] --next--> [tail] | 301 // [begin] --next--> [tail] |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 // | | 335 // | |
| 335 // next | 336 // next |
| 336 // v | 337 // v |
| 337 // EOF | 338 // EOF |
| 338 TokenType type = closeBraceInfoFor(begin); | 339 TokenType type = closeBraceInfoFor(begin); |
| 339 appendToken(new SyntheticToken(type, tokenStart)); | 340 appendToken(new SyntheticToken(type, tokenStart)); |
| 340 begin.endGroup = tail; | 341 begin.endGroup = tail; |
| 341 appendErrorToken(new UnmatchedToken(begin)); | 342 appendErrorToken(new UnmatchedToken(begin)); |
| 342 } | 343 } |
| 343 } | 344 } |
| OLD | NEW |