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

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: 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 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 833 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 844
845 Token parseLabel(Token token) { 845 Token parseLabel(Token token) {
846 token = parseIdentifier(token); 846 token = parseIdentifier(token);
847 Token colon = token; 847 Token colon = token;
848 token = expect(':', token); 848 token = expect(':', token);
849 listener.handleLabel(colon); 849 listener.handleLabel(colon);
850 return token; 850 return token;
851 } 851 }
852 852
853 Token parseLabeledStatement(Token token) { 853 Token parseLabeledStatement(Token token) {
854 listener.beginLabeledStatement(token); 854 int labelCount = 0;
855 token = parseLabel(token); 855 do {
856 token = parseLabel(token);
857 labelCount++;
858 } while (isIdentifier(token) && optional(':', token.next));
859 listener.beginLabeledStatement(token, labelCount);
856 token = parseStatement(token); 860 token = parseStatement(token);
857 listener.endLabeledStatement(); 861 listener.endLabeledStatement(labelCount);
858 return token; 862 return token;
859 } 863 }
860 864
861 Token parseExpressionStatement(Token token) { 865 Token parseExpressionStatement(Token token) {
862 listener.beginExpressionStatement(token); 866 listener.beginExpressionStatement(token);
863 token = parseExpression(token); 867 token = parseExpression(token);
864 listener.endExpressionStatement(token); 868 listener.endExpressionStatement(token);
865 return expectSemicolon(token); 869 return expectSemicolon(token);
866 } 870 }
867 871
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 break; 1567 break;
1564 } 1568 }
1565 token = parseSwitchCase(token); 1569 token = parseSwitchCase(token);
1566 ++caseCount; 1570 ++caseCount;
1567 } 1571 }
1568 listener.endSwitchBlock(caseCount, begin, token); 1572 listener.endSwitchBlock(caseCount, begin, token);
1569 expect('}', token); 1573 expect('}', token);
1570 return token; 1574 return token;
1571 } 1575 }
1572 1576
1577 /**
1578 * Peek after the following labels (if any). The following token
1579 * is used to determine if the labels belong to a statement or a
1580 * switch case.
1581 */
1582 Token peekPastLabels(Token token) {
1583 while (isIdentifier(token) && optional(':', token.next)) {
1584 token = token.next.next;
1585 }
1586 return token;
1587 }
1588
1589 /**
1590 * Parse a group of labels, cases and possibly a default keyword and
1591 * the statements that they select.
1592 */
1573 Token parseSwitchCase(Token token) { 1593 Token parseSwitchCase(Token token) {
1574 Token begin = token; 1594 Token begin = token;
1575 Token defaultKeyword = null; 1595 Token defaultKeyword = null;
1576 Token label = null;
1577 // First an optional label.
1578 if (isIdentifier(token)) {
1579 label = token;
1580 token = parseLabel(token);
1581 }
1582 // Then one or more case expressions, the last of which may be
1583 // 'default' instead.
1584 int expressionCount = 0; 1596 int expressionCount = 0;
1585 { 1597 int labelCount = 0;
1586 String value = token.stringValue; 1598 Token peek = peekPastLabels(token);
1587 do { 1599 while (true) {
1588 if (value === 'default') { 1600 // Loop until we find something that can't be part of a switch case.
1589 defaultKeyword = token; 1601 String value = peek.stringValue;
1590 token = expect(':', token.next); 1602 if (value === 'default') {
1591 break; 1603 while (token !== peek) {
1604 token = parseLabel(token);
1605 labelCount++;
1592 } 1606 }
1593 token = expect('case', token); 1607 defaultKeyword = token;
1594 token = parseExpression(token); 1608 token = expect(':', token.next);
1609 peek = token;
1610 break;
1611 } else if (value === 'case') {
1612 while (token !== peek) {
1613 token = parseLabel(token);
1614 labelCount++;
1615 }
1616 Token caseKeyword = token;
1617 token = parseExpression(token.next);
1618 Token colonToken = token;
1595 token = expect(':', token); 1619 token = expect(':', token);
1620 listener.handleCaseMatch(caseKeyword, colonToken);
1596 expressionCount++; 1621 expressionCount++;
1597 value = token.stringValue; 1622 peek = peekPastLabels(token);
1598 } while (value === 'case' || value === 'default'); 1623 } else {
1624 if (expressionCount == 0) {
1625 listener.expected("case", token);
1626 }
1627 break;
1628 }
1599 } 1629 }
1600 // Finally zero or more statements. 1630 // Finally zero or more statements.
1601 int statementCount = 0; 1631 int statementCount = 0;
1602 while (token.kind !== EOF_TOKEN) { 1632 while (token.kind !== EOF_TOKEN) {
1603 String value; 1633 String value = peek.stringValue;
1604 if (isIdentifier(token) && optional(':', token.next)) { 1634 if ((value === 'case') ||
1605 // Skip label. 1635 (value === 'default') ||
1606 value = token.next.next.stringValue; 1636 ((value === '}') && (token === peek))) {
1607 } else { 1637 // 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; 1638 break;
1612 } else { 1639 } else {
1613 token = parseStatement(token); 1640 token = parseStatement(token);
1614 ++statementCount;
1615 } 1641 }
1642 statementCount++;
1643 peek = peekPastLabels(token);
1616 } 1644 }
1617 listener.handleSwitchCase(label, expressionCount, defaultKeyword, 1645 listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
1618 statementCount, begin, token); 1646 statementCount, begin, token);
1619 return token; 1647 return token;
1620 } 1648 }
1621 1649
1622 Token parseBreakStatement(Token token) { 1650 Token parseBreakStatement(Token token) {
1623 assert(optional('break', token)); 1651 assert(optional('break', token));
1624 Token breakKeyword = token; 1652 Token breakKeyword = token;
1625 token = token.next; 1653 token = token.next;
1626 bool hasTarget = false; 1654 bool hasTarget = false;
1627 if (isIdentifier(token)) { 1655 if (isIdentifier(token)) {
(...skipping 15 matching lines...) Expand all
1643 } 1671 }
1644 listener.handleContinueStatement(hasTarget, continueKeyword, token); 1672 listener.handleContinueStatement(hasTarget, continueKeyword, token);
1645 return expectSemicolon(token); 1673 return expectSemicolon(token);
1646 } 1674 }
1647 1675
1648 Token parseEmptyStatement(Token token) { 1676 Token parseEmptyStatement(Token token) {
1649 listener.handleEmptyStatement(token); 1677 listener.handleEmptyStatement(token);
1650 return expectSemicolon(token); 1678 return expectSemicolon(token);
1651 } 1679 }
1652 } 1680 }
OLDNEW
« 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