| 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 1491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 listener.beginSwitchStatement(switchKeyword); | 1502 listener.beginSwitchStatement(switchKeyword); |
| 1503 token = parseParenthesizedExpression(token.next); | 1503 token = parseParenthesizedExpression(token.next); |
| 1504 token = parseSwitchBlock(token); | 1504 token = parseSwitchBlock(token); |
| 1505 listener.endSwitchStatement(switchKeyword, token); | 1505 listener.endSwitchStatement(switchKeyword, token); |
| 1506 return token.next; | 1506 return token.next; |
| 1507 } | 1507 } |
| 1508 | 1508 |
| 1509 Token parseSwitchBlock(Token token) { | 1509 Token parseSwitchBlock(Token token) { |
| 1510 Token begin = token; | 1510 Token begin = token; |
| 1511 listener.beginSwitchBlock(begin); | 1511 listener.beginSwitchBlock(begin); |
| 1512 token = expect('{', token); |
| 1512 int caseCount = 0; | 1513 int caseCount = 0; |
| 1513 token = expect('{', token); | |
| 1514 while (token.kind !== EOF_TOKEN) { | 1514 while (token.kind !== EOF_TOKEN) { |
| 1515 String value; | 1515 if (optional('}', token)) { |
| 1516 if (isIdentifier(token) && optional(':', token.next)) { | |
| 1517 // Skip label. | |
| 1518 value = token.next.next.stringValue; | |
| 1519 } else { | |
| 1520 value = token.stringValue; | |
| 1521 } | |
| 1522 if (value === 'case') { | |
| 1523 token = parseSwitchCase(token); | |
| 1524 ++caseCount; | |
| 1525 } else if (value === 'default') { | |
| 1526 token = parseDefaultCase(token); | |
| 1527 ++caseCount; | |
| 1528 } else { | |
| 1529 break; | 1516 break; |
| 1530 } | 1517 } |
| 1518 token = parseSwitchCase(token); |
| 1519 ++caseCount; |
| 1531 } | 1520 } |
| 1532 listener.endSwitchBlock(caseCount, begin, token); | 1521 listener.endSwitchBlock(caseCount, begin, token); |
| 1533 expect('}', token); | 1522 expect('}', token); |
| 1534 return token; | 1523 return token; |
| 1535 } | 1524 } |
| 1536 | 1525 |
| 1537 Token parseSwitchCase(Token token) { | 1526 Token parseSwitchCase(Token token) { |
| 1538 Token begin = token; | 1527 Token begin = token; |
| 1539 Token colon; | 1528 Token defaultKeyword = null; |
| 1529 Token label = null; |
| 1530 // First an optional label. |
| 1540 if (isIdentifier(token)) { | 1531 if (isIdentifier(token)) { |
| 1532 label = token; |
| 1541 token = parseIdentifier(token); | 1533 token = parseIdentifier(token); |
| 1542 colon = token; | |
| 1543 token = expect(':', token); | 1534 token = expect(':', token); |
| 1544 } | 1535 } |
| 1545 Token caseKeyword = token; | 1536 // Then one or more case expressions, the last of which may be |
| 1546 token = expect('case', token); | 1537 // 'default' instead. |
| 1547 token = parseExpression(token); | 1538 int expressionCount = 0; |
| 1548 token = expect(':', token); | 1539 String value = token.stringValue; |
| 1540 do { |
| 1541 if (value === 'default') { |
| 1542 defaultKeyword = token; |
| 1543 token = expect(':', token.next); |
| 1544 break; |
| 1545 } |
| 1546 token = expect('case', token); |
| 1547 token = parseExpression(token); |
| 1548 token = expect(':', token); |
| 1549 expressionCount++; |
| 1550 value = token.stringValue; |
| 1551 } while (value === 'case' || value === 'default'); |
| 1552 // Finally zero or more statements. |
| 1549 int statementCount = 0; | 1553 int statementCount = 0; |
| 1550 while (token.kind !== EOF_TOKEN) { | 1554 while (token.kind !== EOF_TOKEN) { |
| 1551 String value; | 1555 String value; |
| 1552 if (isIdentifier(token) && optional(':', token.next)) { | |
| 1553 // Skip label. | |
| 1554 value = token.next.next.stringValue; | |
| 1555 } else { | |
| 1556 value = token.stringValue; | |
| 1557 } | |
| 1558 if (value === 'case' || value === 'default' || value === '}') { | |
| 1559 break; | |
| 1560 } else { | |
| 1561 token = parseStatement(token); | |
| 1562 ++statementCount; | |
| 1563 } | |
| 1564 } | |
| 1565 listener.handleSwitchCase(colon, caseKeyword, statementCount, token); | |
| 1566 return token; | |
| 1567 } | |
| 1568 | |
| 1569 Token parseDefaultCase(Token token) { | |
| 1570 Token begin = token; | |
| 1571 Token colon; | |
| 1572 if (isIdentifier(token)) { | |
| 1573 token = parseIdentifier(token); | |
| 1574 colon = token; | |
| 1575 token = expect(':', token); | |
| 1576 } | |
| 1577 Token defaultKeyword = token; | |
| 1578 token = expect('default', token); | |
| 1579 token = expect(':', token); | |
| 1580 int statementCount = 0; | |
| 1581 while (token.kind !== EOF_TOKEN) { | |
| 1582 String value; | |
| 1583 if (isIdentifier(token) && optional(':', token.next)) { | 1556 if (isIdentifier(token) && optional(':', token.next)) { |
| 1584 // Skip label. | 1557 // Skip label. |
| 1585 value = token.next.next.stringValue; | 1558 value = token.next.next.stringValue; |
| 1586 } else { | 1559 } else { |
| 1587 value = token.stringValue; | 1560 value = token.stringValue; |
| 1588 } | 1561 } |
| 1589 if (value === '}') { | 1562 if (value === 'case' || value === 'default' || value === '}') { |
| 1590 break; | |
| 1591 } else if (value === 'case' || value === 'default') { | |
| 1592 // The default case should be the last case in a switch. | |
| 1593 listener.recoverableError("expected '}'", token: token); | |
| 1594 break; | 1563 break; |
| 1595 } else { | 1564 } else { |
| 1596 token = parseStatement(token); | 1565 token = parseStatement(token); |
| 1597 ++statementCount; | 1566 ++statementCount; |
| 1598 } | 1567 } |
| 1599 } | 1568 } |
| 1600 listener.handleDefaultCase(colon, defaultKeyword, statementCount, token); | 1569 listener.handleSwitchCase(label, expressionCount, defaultKeyword, |
| 1570 statementCount, begin, token); |
| 1601 return token; | 1571 return token; |
| 1602 } | 1572 } |
| 1603 | 1573 |
| 1604 Token parseBreakStatement(Token token) { | 1574 Token parseBreakStatement(Token token) { |
| 1605 assert(optional('break', token)); | 1575 assert(optional('break', token)); |
| 1606 Token breakKeyword = token; | 1576 Token breakKeyword = token; |
| 1607 token = token.next; | 1577 token = token.next; |
| 1608 bool hasTarget = false; | 1578 bool hasTarget = false; |
| 1609 if (isIdentifier(token)) { | 1579 if (isIdentifier(token)) { |
| 1610 token = parseIdentifier(token); | 1580 token = parseIdentifier(token); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1625 } | 1595 } |
| 1626 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1596 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1627 return expectSemicolon(token); | 1597 return expectSemicolon(token); |
| 1628 } | 1598 } |
| 1629 | 1599 |
| 1630 Token parseEmptyStatement(Token token) { | 1600 Token parseEmptyStatement(Token token) { |
| 1631 listener.handleEmptyStatement(token); | 1601 listener.handleEmptyStatement(token); |
| 1632 return expectSemicolon(token); | 1602 return expectSemicolon(token); |
| 1633 } | 1603 } |
| 1634 } | 1604 } |
| OLD | NEW |