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

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

Issue 251523002: Improve error-recovery from unmatched braces. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r35370 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/scanner.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart b/dart/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart
index 55eeca95c0fd260d2fa9f6b55a8e50023838cc67..aee544d5a08cb4211ada134823aae17591db49ed 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/scanner/scanner.dart
@@ -1096,29 +1096,63 @@ abstract class AbstractScanner implements Scanner {
}
void unmatchedBeginGroup(BeginGroupToken begin) {
- String error = 'unmatched "${begin.stringValue}"';
- Token close =
- new StringToken.fromString(
- BAD_INPUT_INFO, error, begin.charOffset, canonicalize: true);
-
- // We want to ensure that unmatched BeginGroupTokens are reported
- // as errors. However, the rest of the parser assumes the groups
- // are well-balanced and will never look at the endGroup
- // token. This is a nice property that allows us to skip quickly
- // over correct code. By inserting an additional error token in
- // the stream, we can keep ignoring endGroup tokens.
+ // We want to ensure that unmatched BeginGroupTokens are reported as
+ // errors. However, the diet parser assumes that groups are well-balanced
+ // and will never look at the endGroup token. This is a nice property that
+ // allows us to skip quickly over correct code. By inserting an additional
+ // synthetic token in the stream, we can keep ignoring endGroup tokens.
//
// [begin] --next--> [tail]
- // [begin] --endG--> [close] --next--> [next] --next--> [tail]
+ // [begin] --endG--> [synthetic] --next--> [next] --next--> [tail]
//
- // This allows the parser to skip from [begin] via endGroup to [close] and
- // ignore the [close] token (assuming it's correct), then the error will be
- // reported when parsing the [next] token.
-
- Token next = new StringToken.fromString(
- BAD_INPUT_INFO, error, begin.charOffset, canonicalize: true);
- begin.endGroup = close;
- close.next = next;
- next.next = begin.next;
+ // This allows the diet parser to skip from [begin] via endGroup to
+ // [synthetic] and ignore the [synthetic] token (assuming it's correct),
+ // then the error will be reported when parsing the [next] token.
+ //
+ // For example, tokenize("{[1};") produces:
+ //
+ // SymbolToken({) --endGroup-----+
+ // | |
+ // next |
+ // v |
+ // SymbolToken([) --endGroup--+ |
+ // | | |
+ // next | |
+ // v | |
+ // StringToken(1) | |
+ // | v |
+ // next SymbolToken(]) | <- Synthetic token.
+ // | | |
+ // | next |
+ // v | |
+ // UnmatchedToken([)<---------+ |
+ // | |
+ // next |
+ // v |
+ // SymbolToken(})<---------------+
+ // |
+ // next
+ // v
+ // SymbolToken(;)
+ // |
+ // next
+ // v
+ // EOF
+ Token synthetic =
+ new SymbolToken(closeBraceInfoFor(begin), begin.charOffset);
+ UnmatchedToken next = new UnmatchedToken(begin);
+ begin.endGroup = synthetic;
+ synthetic.next = next;
+ appendErrorToken(next);
}
}
+
+PrecedenceInfo closeBraceInfoFor(BeginGroupToken begin) {
+ return const {
+ '(': CLOSE_PAREN_INFO,
+ '[': CLOSE_SQUARE_BRACKET_INFO,
+ '{': CLOSE_CURLY_BRACKET_INFO,
+ '<': GT_INFO,
+ r'${': CLOSE_CURLY_BRACKET_INFO,
+ }[begin.value];
+}

Powered by Google App Engine
This is Rietveld 408576698