| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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. | 7 * all tokens in a linked list. |
| 8 */ | 8 */ |
| 9 class Parser { | 9 class Parser { |
| 10 final Listener listener; | 10 final Listener listener; |
| (...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 listener.beginSwitchStatement(switchKeyword); | 1529 listener.beginSwitchStatement(switchKeyword); |
| 1530 token = parseParenthesizedExpression(token.next); | 1530 token = parseParenthesizedExpression(token.next); |
| 1531 token = parseSwitchBlock(token); | 1531 token = parseSwitchBlock(token); |
| 1532 listener.endSwitchStatement(switchKeyword, token); | 1532 listener.endSwitchStatement(switchKeyword, token); |
| 1533 return token.next; | 1533 return token.next; |
| 1534 } | 1534 } |
| 1535 | 1535 |
| 1536 Token parseSwitchBlock(Token token) { | 1536 Token parseSwitchBlock(Token token) { |
| 1537 Token begin = token; | 1537 Token begin = token; |
| 1538 listener.beginSwitchBlock(begin); | 1538 listener.beginSwitchBlock(begin); |
| 1539 token = expect('{', token); |
| 1539 int caseCount = 0; | 1540 int caseCount = 0; |
| 1540 token = expect('{', token); | |
| 1541 while (token.kind !== EOF_TOKEN) { | 1541 while (token.kind !== EOF_TOKEN) { |
| 1542 String value; | 1542 if (optional('}', token)) { |
| 1543 if (isIdentifier(token) && optional(':', token.next)) { | |
| 1544 // Skip label. | |
| 1545 value = token.next.next.stringValue; | |
| 1546 } else { | |
| 1547 value = token.stringValue; | |
| 1548 } | |
| 1549 if (value === 'case') { | |
| 1550 token = parseSwitchCase(token); | |
| 1551 ++caseCount; | |
| 1552 } else if (value === 'default') { | |
| 1553 token = parseDefaultCase(token); | |
| 1554 ++caseCount; | |
| 1555 } else { | |
| 1556 break; | 1543 break; |
| 1557 } | 1544 } |
| 1545 token = parseSwitchCase(token); |
| 1546 ++caseCount; |
| 1558 } | 1547 } |
| 1559 listener.endSwitchBlock(caseCount, begin, token); | 1548 listener.endSwitchBlock(caseCount, begin, token); |
| 1560 expect('}', token); | 1549 expect('}', token); |
| 1561 return token; | 1550 return token; |
| 1562 } | 1551 } |
| 1563 | 1552 |
| 1564 Token parseSwitchCase(Token token) { | 1553 Token parseSwitchCase(Token token) { |
| 1565 Token begin = token; | 1554 Token begin = token; |
| 1566 Token colon; | 1555 Token defaultKeyword = null; |
| 1556 Token label = null; |
| 1557 // First an optional label. |
| 1567 if (isIdentifier(token)) { | 1558 if (isIdentifier(token)) { |
| 1568 token = parseIdentifier(token); | 1559 token = parseIdentifier(token); |
| 1569 colon = token; | 1560 label = token; |
| 1570 token = expect(':', token); | 1561 token = expect(':', token); |
| 1571 } | 1562 } |
| 1572 Token caseKeyword = token; | 1563 // Then one or more case expressions, the last of which may be |
| 1573 token = expect('case', token); | 1564 // 'default' instead. |
| 1574 token = parseExpression(token); | 1565 int expressionCount = 0; |
| 1575 token = expect(':', token); | 1566 String tokenValue = token.stringValue; |
| 1567 do { |
| 1568 if (tokenValue === 'default') { |
| 1569 defaultKeyword = token; |
| 1570 token = expect(':', token.next); |
| 1571 break; |
| 1572 } |
| 1573 token = expect('case', token); |
| 1574 token = parseExpression(token); |
| 1575 token = expect(':', token); |
| 1576 expressionCount++; |
| 1577 tokenValue = token.stringValue; |
| 1578 } while (tokenValue === 'case' || tokenValue === 'default'); |
| 1579 // Finally zero or more statements. |
| 1576 int statementCount = 0; | 1580 int statementCount = 0; |
| 1577 while (token.kind !== EOF_TOKEN) { | 1581 while (token.kind !== EOF_TOKEN) { |
| 1578 String value; | 1582 String value; |
| 1579 if (isIdentifier(token) && optional(':', token.next)) { | |
| 1580 // Skip label. | |
| 1581 value = token.next.next.stringValue; | |
| 1582 } else { | |
| 1583 value = token.stringValue; | |
| 1584 } | |
| 1585 if (value === 'case' || value === 'default' || value === '}') { | |
| 1586 break; | |
| 1587 } else { | |
| 1588 token = parseStatement(token); | |
| 1589 ++statementCount; | |
| 1590 } | |
| 1591 } | |
| 1592 listener.handleSwitchCase(colon, caseKeyword, statementCount, token); | |
| 1593 return token; | |
| 1594 } | |
| 1595 | |
| 1596 Token parseDefaultCase(Token token) { | |
| 1597 Token begin = token; | |
| 1598 Token colon; | |
| 1599 if (isIdentifier(token)) { | |
| 1600 token = parseIdentifier(token); | |
| 1601 colon = token; | |
| 1602 token = expect(':', token); | |
| 1603 } | |
| 1604 Token defaultKeyword = token; | |
| 1605 token = expect('default', token); | |
| 1606 token = expect(':', token); | |
| 1607 int statementCount = 0; | |
| 1608 while (token.kind !== EOF_TOKEN) { | |
| 1609 String value; | |
| 1610 if (isIdentifier(token) && optional(':', token.next)) { | 1583 if (isIdentifier(token) && optional(':', token.next)) { |
| 1611 // Skip label. | 1584 // Skip label. |
| 1612 value = token.next.next.stringValue; | 1585 value = token.next.next.stringValue; |
| 1613 } else { | 1586 } else { |
| 1614 value = token.stringValue; | 1587 value = token.stringValue; |
| 1615 } | 1588 } |
| 1616 if (value === '}') { | 1589 if (value === 'case' || value === 'default' || value === '}') { |
| 1617 break; | |
| 1618 } else if (value === 'case' || value === 'default') { | |
| 1619 // The default case should be the last case in a switch. | |
| 1620 listener.recoverableError("expected '}'", token: token); | |
| 1621 break; | 1590 break; |
| 1622 } else { | 1591 } else { |
| 1623 token = parseStatement(token); | 1592 token = parseStatement(token); |
| 1624 ++statementCount; | 1593 ++statementCount; |
| 1625 } | 1594 } |
| 1626 } | 1595 } |
| 1627 listener.handleDefaultCase(colon, defaultKeyword, statementCount, token); | 1596 listener.handleSwitchCase(label, expressionCount, defaultKeyword, |
| 1597 statementCount, begin, token); |
| 1628 return token; | 1598 return token; |
| 1629 } | 1599 } |
| 1630 | 1600 |
| 1631 Token parseBreakStatement(Token token) { | 1601 Token parseBreakStatement(Token token) { |
| 1632 assert(optional('break', token)); | 1602 assert(optional('break', token)); |
| 1633 Token breakKeyword = token; | 1603 Token breakKeyword = token; |
| 1634 token = token.next; | 1604 token = token.next; |
| 1635 bool hasTarget = false; | 1605 bool hasTarget = false; |
| 1636 if (isIdentifier(token)) { | 1606 if (isIdentifier(token)) { |
| 1637 token = parseIdentifier(token); | 1607 token = parseIdentifier(token); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1652 } | 1622 } |
| 1653 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1623 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1654 return expectSemicolon(token); | 1624 return expectSemicolon(token); |
| 1655 } | 1625 } |
| 1656 | 1626 |
| 1657 Token parseEmptyStatement(Token token) { | 1627 Token parseEmptyStatement(Token token) { |
| 1658 listener.handleEmptyStatement(token); | 1628 listener.handleEmptyStatement(token); |
| 1659 return expectSemicolon(token); | 1629 return expectSemicolon(token); |
| 1660 } | 1630 } |
| 1661 } | 1631 } |
| OLD | NEW |