| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |