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

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: Address review comments. 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
« no previous file with comments | « lib/compiler/implementation/scanner/listener.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..0bf9fe69f5cbbf40212f429ba6f7ea8f9e1f1862 100644
--- a/lib/compiler/implementation/scanner/parser.dart
+++ b/lib/compiler/implementation/scanner/parser.dart
@@ -851,10 +851,14 @@ class Parser {
}
Token parseLabeledStatement(Token token) {
- listener.beginLabeledStatement(token);
- token = parseLabel(token);
+ int labelCount = 0;
+ do {
+ token = parseLabel(token);
+ labelCount++;
+ } while (isIdentifier(token) && optional(':', token.next));
+ listener.beginLabeledStatement(token, labelCount);
token = parseStatement(token);
- listener.endLabeledStatement();
+ listener.endLabeledStatement(labelCount);
return token;
}
@@ -1570,51 +1574,75 @@ class Parser {
return token;
}
+ /**
+ * Peek after the following labels (if any). The following token
+ * is used to determine if the labels belong to a statement or a
+ * switch case.
+ */
+ Token peekPastLabels(Token token) {
+ while (isIdentifier(token) && optional(':', token.next)) {
+ token = token.next.next;
+ }
+ return token;
+ }
+
+ /**
+ * Parse a group of labels, cases and possibly a default keyword and
+ * the statements that they select.
+ */
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);
- }
- // 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;
+ int labelCount = 0;
+ Token peek = peekPastLabels(token);
+ while (true) {
+ // Loop until we find something that can't be part of a switch case.
+ String value = peek.stringValue;
+ if (value === 'default') {
+ while (token !== peek) {
+ token = parseLabel(token);
+ labelCount++;
+ }
+ defaultKeyword = token;
+ token = expect(':', token.next);
+ peek = token;
+ break;
+ } else if (value === 'case') {
+ while (token !== peek) {
+ token = parseLabel(token);
+ labelCount++;
}
- token = expect('case', token);
- token = parseExpression(token);
+ Token caseKeyword = token;
+ token = parseExpression(token.next);
+ Token colonToken = token;
token = expect(':', token);
+ listener.handleCaseMatch(caseKeyword, colonToken);
expressionCount++;
- value = token.stringValue;
- } while (value === 'case' || value === 'default');
+ peek = peekPastLabels(token);
+ } else {
+ if (expressionCount == 0) {
+ listener.expected("case", token);
+ }
+ 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 === '}') {
+ String value = peek.stringValue;
+ if ((value === 'case') ||
+ (value === 'default') ||
+ ((value === '}') && (token === peek))) {
+ // A label just before "}" will be handled as a statement error.
break;
} else {
token = parseStatement(token);
- ++statementCount;
}
+ statementCount++;
+ peek = peekPastLabels(token);
}
- listener.handleSwitchCase(label, expressionCount, defaultKeyword,
+ listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
statementCount, begin, token);
return token;
}
« no previous file with comments | « lib/compiler/implementation/scanner/listener.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698