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

Unified Diff: dart/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart

Issue 251523002: Improve error-recovery from unmatched braces. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Updated parser_test.dart Created 6 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 side-by-side diff with in-line comments
Download patch
Index: dart/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart b/dart/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
index d1daab119fb905c1992a6497fec53f2f1c450dcd..8894cd50c3adf809dbda94d92f6da9ba7702031c 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/scanner/array_based_scanner.dart
@@ -72,15 +72,15 @@ abstract class ArrayBasedScanner extends AbstractScanner {
void appendEofToken() {
beginToken();
- tail.next = new SymbolToken(EOF_INFO, tokenStart);
- tail = tail.next;
- // EOF points to itself so there's always infinite look-ahead.
- tail.next = tail;
discardOpenLt();
while (!groupingStack.isEmpty) {
unmatchedBeginGroup(groupingStack.head);
groupingStack = groupingStack.tail;
}
+ tail.next = new SymbolToken(EOF_INFO, tokenStart);
+ tail = tail.next;
+ // EOF points to itself so there's always infinite look-ahead.
+ tail.next = tail;
}
/**
@@ -129,33 +129,47 @@ abstract class ArrayBasedScanner extends AbstractScanner {
*/
int appendEndGroup(PrecedenceInfo info, int openKind) {
assert(!identical(openKind, LT_TOKEN)); // openKind is < for > and >>
+ discardBeginGroupUntil(openKind);
appendPrecedenceToken(info);
- // Don't report unmatched errors for <; it is also the less-than operator.
- discardOpenLt();
+ Token close = tail;
if (groupingStack.isEmpty) {
return advance();
}
BeginGroupToken begin = groupingStack.head;
if (!identical(begin.kind, openKind)) {
- if (!identical(openKind, OPEN_CURLY_BRACKET_TOKEN) ||
- !identical(begin.kind, STRING_INTERPOLATION_TOKEN)) {
- // Not ending string interpolation.
- unmatchedBeginGroup(begin);
- return advance();
- }
+ assert(begin.kind == STRING_INTERPOLATION_TOKEN &&
+ openKind == OPEN_CURLY_BRACKET_TOKEN);
// We're ending an interpolated expression.
- begin.endGroup = tail;
+ begin.endGroup = close;
groupingStack = groupingStack.tail;
// Using "start-of-text" to signal that we're back in string
// scanning mode.
return $STX;
}
- begin.endGroup = tail;
+ begin.endGroup = close;
groupingStack = groupingStack.tail;
return advance();
}
/**
+ * Discards begin group tokens until a match with [openKind] is found.
+ * This recovers nicely from from a situation like "{[}".
+ */
+ void discardBeginGroupUntil(int openKind) {
+ while (!groupingStack.isEmpty) {
+ // Don't report unmatched errors for <; it is also the less-than operator.
+ discardOpenLt();
+ if (groupingStack.isEmpty) return;
+ BeginGroupToken begin = groupingStack.head;
+ if (openKind == begin.kind) return;
+ if (openKind == OPEN_CURLY_BRACKET_TOKEN &&
+ begin.kind == STRING_INTERPOLATION_TOKEN) return;
+ unmatchedBeginGroup(begin);
+ groupingStack = groupingStack.tail;
+ }
+ }
+
+ /**
* Appends a token for '>'.
* This method does not issue unmatched errors, because > is also the
* greater-than operator. It does not necessarily have to close a group.

Powered by Google App Engine
This is Rietveld 408576698