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

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: Remove debug-print. 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..5f4cd49d5bea9958e0a0ada3a67f404a8bcdce99 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;
}
@@ -1554,10 +1558,85 @@ class Parser {
}
Token parseSwitchBlock(Token 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 peek) {
ahe 2012/05/14 09:24:25 I would prefer if this function's argument was nam
Lasse Reichstein Nielsen 2012/05/14 10:34:58 It's now a top-level function. I'll rename "peek"
+ Token pre = peek;
ahe 2012/05/14 09:24:25 Unused variable?
Lasse Reichstein Nielsen 2012/05/14 10:34:58 Done.
+ while (isIdentifier(peek) && optional(':', peek.next)) {
+ peek = peek.next.next;
+ }
+ return peek;
+ }
+
+ // When entering or leaving [parseSwitchCase], peek points to the first
+ // token that isn't a label.
+ Token peek;
ahe 2012/05/14 09:24:25 It is confusing that peekPastLabels has "peek" par
Lasse Reichstein Nielsen 2012/05/14 10:34:58 It was actually deliberate. Alas, parameter is now
+
+ /**
+ * Parse a group of labels, cases and possibly a default keyword and
+ * the statements that they select.
+ */
+ Token parseSwitchCase(Token token) {
ahe 2012/05/14 09:24:25 This method is definitely something that I think a
Lasse Reichstein Nielsen 2012/05/14 10:34:58 It's avoided, but at the cost of potentially peeki
+ Token begin = token;
+ Token defaultKeyword = null;
+ int expressionCount = 0;
+ int labelCount = 0;
+
+ 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 caseKeyword = token;
+ token = parseExpression(token.next);
+ Token colonToken = token;
+ token = expect(':', token);
+ listener.handleCaseMatch(caseKeyword, colonToken);
+ expressionCount++;
+ peek = peekPastLabels(token);
+ } else {
+ break;
+ }
+ }
+ // Finally zero or more statements.
+ int statementCount = 0;
+ while (token.kind !== EOF_TOKEN) {
+ 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++;
+ peek = peekPastLabels(token);
+ }
+ listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
+ statementCount, begin, token);
+ return token;
+ }
+
Token begin = token;
listener.beginSwitchBlock(begin);
token = expect('{', token);
int caseCount = 0;
+ peek = peekPastLabels(token);
while (token.kind !== EOF_TOKEN) {
if (optional('}', token)) {
break;
@@ -1570,54 +1649,6 @@ class Parser {
return token;
}
- 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;
- }
- token = expect('case', token);
- token = parseExpression(token);
- token = expect(':', token);
- expressionCount++;
- value = token.stringValue;
- } while (value === 'case' || value === 'default');
- }
- // 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 === '}') {
- break;
- } else {
- token = parseStatement(token);
- ++statementCount;
- }
- }
- listener.handleSwitchCase(label, expressionCount, defaultKeyword,
- statementCount, begin, token);
- return token;
- }
Token parseBreakStatement(Token token) {
assert(optional('break', token));

Powered by Google App Engine
This is Rietveld 408576698