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

Side by Side Diff: frog/leg/scanner/parser.dart

Issue 9632018: Switch-implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Finished implementation Created 8 years, 9 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) 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
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)) {
1541 token = parseIdentifier(token); 1532 token = parseIdentifier(token);
1542 colon = token; 1533 label = 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 tokenValue = token.stringValue;
1540 do {
1541 if (tokenValue === 'default') {
1542 defaultKeyword = token;
1543 token = expect(':', token.next);
1544 break;
1545 }
1546 token = expect('case', token);
ahe 2012/03/09 13:58:32 Where do you store the case token?
Lasse Reichstein Nielsen 2012/03/12 13:05:23 I don't. You can find it, if you need it, from the
1547 token = parseExpression(token);
1548 token = expect(':', token);
1549 expressionCount++;
1550 tokenValue = token.stringValue;
1551 } while (tokenValue === 'case' || tokenValue === 'default');
ahe 2012/03/09 13:58:32 What happens if I write: switch (expr) { default:
Lasse Reichstein Nielsen 2012/03/12 13:05:23 The "default:" always ends the case, so this is eq
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698