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

Unified Diff: lib/compiler/implementation/scanner/parser.dart

Issue 10387080: Accept more labels per switch case. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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: lib/compiler/implementation/scanner/parser.dart
diff --git a/lib/compiler/implementation/scanner/parser.dart b/lib/compiler/implementation/scanner/parser.dart
index c24ed64610a41cc6d9f619825bef173ec89626dd..debe508636c87cc45f25396eac87b468e05b2da7 100644
--- a/lib/compiler/implementation/scanner/parser.dart
+++ b/lib/compiler/implementation/scanner/parser.dart
@@ -1573,48 +1573,68 @@ class Parser {
Token parseSwitchCase(Token token) {
Token begin = token;
Token defaultKeyword = null;
- Token label = null;
- // First an optional label.
- if (isIdentifier(token)) {
- label = token;
- token = parseLabel(token);
+
+ /**
+ * Peek ahead in the token stream to see what's after a sequence
+ * of labels. We don't parse the labels before we know whether we
+ * need to call [listener.beginLabeledStatement].
+ */
+ Token peekAfterLabels(Token token) {
+ while (isIdentifier(token) && optional(':', token.next)) {
+ token = token.next.next;
+ }
+ return token;
}
- // Then one or more case expressions, the last of which may be
- // 'default' instead.
+
int expressionCount = 0;
- {
- String value = token.stringValue;
- do {
- if (value === 'default') {
- defaultKeyword = token;
- token = expect(':', token.next);
- break;
- }
- token = expect('case', token);
- token = parseExpression(token);
+ int labelCount = 0;
+
+ Token parseLabelsUntil(Token token, Token limit) {
+ while (token !== limit) {
+ token = parseLabel(token);
+ labelCount++;
+ }
+ return token;
+ }
+
+ while (true) {
+ // Look-ahead to after a sequence of labels. The labels can belong to
+ // either a case or a following statement.
+ Token peek = peekAfterLabels(token);
+ // Loop until we find something that can't be part of a switch case.
+ String value = peek.stringValue;
+ if (value === 'default') {
+ token = parseLabelsUntil(token, peek);
+ defaultKeyword = token;
+ token = expect(':', token.next);
+ break;
+ } else if (value === 'case') {
+ token = parseLabelsUntil(token, peek);
+ Token caseKeyword = token;
+ token = parseExpression(token.next);
+ Token colon = token;
token = expect(':', token);
+ listener.handleCaseMatch(caseKeyword, colon);
expressionCount++;
- value = token.stringValue;
- } while (value === 'case' || value === 'default');
+ } else {
+ break;
+ }
}
// Finally zero or more statements.
int statementCount = 0;
while (token.kind !== EOF_TOKEN) {
- String value;
- if (isIdentifier(token) && optional(':', token.next)) {
- // Skip label.
- value = token.next.next.stringValue;
- } else {
- value = token.stringValue;
- }
- if (value === 'case' || value === 'default' || value === '}') {
+ Token peek = peekAfterLabels(token);
+ String value = peek.stringValue;
+ if (value === 'case' || value === 'default' ||
+ (value === '}' && peek === token)) {
+ // A label just before "}" will be handled as a statement error.
break;
} else {
token = parseStatement(token);
++statementCount;
}
}
- listener.handleSwitchCase(label, expressionCount, defaultKeyword,
+ listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
statementCount, begin, token);
return token;
}

Powered by Google App Engine
This is Rietveld 408576698