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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /** 5 /**
6 * An event generating parser of Dart programs. This parser expects 6 * An event generating parser of Dart programs. This parser expects
7 * all tokens in a linked list (aka a token stream). 7 * all tokens in a linked list (aka a token stream).
8 * 8 *
9 * The class [Scanner] is used to generate a token stream. See the 9 * The class [Scanner] is used to generate a token stream. See the
10 * file scanner.dart. 10 * file scanner.dart.
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 ++caseCount; 1566 ++caseCount;
1567 } 1567 }
1568 listener.endSwitchBlock(caseCount, begin, token); 1568 listener.endSwitchBlock(caseCount, begin, token);
1569 expect('}', token); 1569 expect('}', token);
1570 return token; 1570 return token;
1571 } 1571 }
1572 1572
1573 Token parseSwitchCase(Token token) { 1573 Token parseSwitchCase(Token token) {
1574 Token begin = token; 1574 Token begin = token;
1575 Token defaultKeyword = null; 1575 Token defaultKeyword = null;
1576 Token label = null; 1576
1577 // First an optional label. 1577 /**
1578 if (isIdentifier(token)) { 1578 * Peek ahead in the token stream to see what's after a sequence
1579 label = token; 1579 * of labels. We don't parse the labels before we know whether we
1580 token = parseLabel(token); 1580 * need to call [listener.beginLabeledStatement].
1581 */
1582 Token peekAfterLabels(Token token) {
1583 while (isIdentifier(token) && optional(':', token.next)) {
1584 token = token.next.next;
1585 }
1586 return token;
1581 } 1587 }
1582 // Then one or more case expressions, the last of which may be 1588
1583 // 'default' instead.
1584 int expressionCount = 0; 1589 int expressionCount = 0;
1585 { 1590 int labelCount = 0;
1586 String value = token.stringValue; 1591
1587 do { 1592 Token parseLabelsUntil(Token token, Token limit) {
1588 if (value === 'default') { 1593 while (token !== limit) {
1589 defaultKeyword = token; 1594 token = parseLabel(token);
1590 token = expect(':', token.next); 1595 labelCount++;
1591 break; 1596 }
1592 } 1597 return token;
1593 token = expect('case', token); 1598 }
1594 token = parseExpression(token); 1599
1600 while (true) {
1601 // Look-ahead to after a sequence of labels. The labels can belong to
1602 // either a case or a following statement.
1603 Token peek = peekAfterLabels(token);
1604 // Loop until we find something that can't be part of a switch case.
1605 String value = peek.stringValue;
1606 if (value === 'default') {
1607 token = parseLabelsUntil(token, peek);
1608 defaultKeyword = token;
1609 token = expect(':', token.next);
1610 break;
1611 } else if (value === 'case') {
1612 token = parseLabelsUntil(token, peek);
1613 Token caseKeyword = token;
1614 token = parseExpression(token.next);
1615 Token colon = token;
1595 token = expect(':', token); 1616 token = expect(':', token);
1617 listener.handleCaseMatch(caseKeyword, colon);
1596 expressionCount++; 1618 expressionCount++;
1597 value = token.stringValue; 1619 } else {
1598 } while (value === 'case' || value === 'default'); 1620 break;
1621 }
1599 } 1622 }
1600 // Finally zero or more statements. 1623 // Finally zero or more statements.
1601 int statementCount = 0; 1624 int statementCount = 0;
1602 while (token.kind !== EOF_TOKEN) { 1625 while (token.kind !== EOF_TOKEN) {
1603 String value; 1626 Token peek = peekAfterLabels(token);
1604 if (isIdentifier(token) && optional(':', token.next)) { 1627 String value = peek.stringValue;
1605 // Skip label. 1628 if (value === 'case' || value === 'default' ||
1606 value = token.next.next.stringValue; 1629 (value === '}' && peek === token)) {
1607 } else { 1630 // A label just before "}" will be handled as a statement error.
1608 value = token.stringValue;
1609 }
1610 if (value === 'case' || value === 'default' || value === '}') {
1611 break; 1631 break;
1612 } else { 1632 } else {
1613 token = parseStatement(token); 1633 token = parseStatement(token);
1614 ++statementCount; 1634 ++statementCount;
1615 } 1635 }
1616 } 1636 }
1617 listener.handleSwitchCase(label, expressionCount, defaultKeyword, 1637 listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
1618 statementCount, begin, token); 1638 statementCount, begin, token);
1619 return token; 1639 return token;
1620 } 1640 }
1621 1641
1622 Token parseBreakStatement(Token token) { 1642 Token parseBreakStatement(Token token) {
1623 assert(optional('break', token)); 1643 assert(optional('break', token));
1624 Token breakKeyword = token; 1644 Token breakKeyword = token;
1625 token = token.next; 1645 token = token.next;
1626 bool hasTarget = false; 1646 bool hasTarget = false;
1627 if (isIdentifier(token)) { 1647 if (isIdentifier(token)) {
(...skipping 15 matching lines...) Expand all
1643 } 1663 }
1644 listener.handleContinueStatement(hasTarget, continueKeyword, token); 1664 listener.handleContinueStatement(hasTarget, continueKeyword, token);
1645 return expectSemicolon(token); 1665 return expectSemicolon(token);
1646 } 1666 }
1647 1667
1648 Token parseEmptyStatement(Token token) { 1668 Token parseEmptyStatement(Token token) {
1649 listener.handleEmptyStatement(token); 1669 listener.handleEmptyStatement(token);
1650 return expectSemicolon(token); 1670 return expectSemicolon(token);
1651 } 1671 }
1652 } 1672 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698