Chromium Code Reviews| 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 if (value === 'default') return true; | 181 if (value === 'default') return true; |
| 182 if (value === 'factory') { | 182 if (value === 'factory') { |
| 183 listener.recoverableError("expected 'default'", token: token); | 183 listener.recoverableError("expected 'default'", token: token); |
| 184 return true; | 184 return true; |
| 185 } | 185 } |
| 186 return false; | 186 return false; |
| 187 } | 187 } |
| 188 | 188 |
| 189 Token skipBlock(Token token) { | 189 Token skipBlock(Token token) { |
| 190 if (!optional('{', token)) { | 190 if (!optional('{', token)) { |
| 191 return listener.expectedBlock(token); | 191 return listener.unexpected(token); |
| 192 } | 192 } |
| 193 BeginGroupToken beginGroupToken = token; | 193 BeginGroupToken beginGroupToken = token; |
| 194 assert(beginGroupToken.endGroup === null || | 194 assert(beginGroupToken.endGroup === null || |
| 195 beginGroupToken.endGroup.kind === $CLOSE_CURLY_BRACKET); | 195 beginGroupToken.endGroup.kind === $CLOSE_CURLY_BRACKET); |
| 196 return beginGroupToken.endGroup; | 196 return beginGroupToken.endGroup; |
| 197 } | 197 } |
| 198 | 198 |
| 199 Token parseClass(Token token) { | 199 Token parseClass(Token token) { |
| 200 Token begin = token; | 200 Token begin = token; |
| 201 listener.beginClassDeclaration(token); | 201 listener.beginClassDeclaration(token); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 if (value === '(') { | 361 if (value === '(') { |
| 362 isField = false; | 362 isField = false; |
| 363 break; | 363 break; |
| 364 } else if ((value === '=') || (value === ';') || (value === ',')) { | 364 } else if ((value === '=') || (value === ';') || (value === ',')) { |
| 365 isField = true; | 365 isField = true; |
| 366 break; | 366 break; |
| 367 } else { | 367 } else { |
| 368 token = listener.unexpected(token); | 368 token = listener.unexpected(token); |
| 369 if (token.kind === EOF_TOKEN) { | 369 if (token.kind === EOF_TOKEN) { |
| 370 // TODO(ahe): This is a hack. It would be better to tell the | 370 // TODO(ahe): This is a hack. It would be better to tell the |
| 371 // listener more explicitly that it must pop an identifier. | 371 // listener more explicitly that it must pop an identifier. |
|
ngeoffray
2012/01/10 07:49:45
Is that still a hack?
ahe
2012/01/10 08:02:28
Yes. Something is wrong here, but we don't know wh
ngeoffray
2012/01/10 08:07:09
So should you do the same line 555?
ahe
2012/01/10 08:32:33
Done.
| |
| 372 listener.endTopLevelFields(0, start, token); | 372 listener.endTopLevelFields(1, start, token); |
| 373 return token; | 373 return token; |
| 374 } | 374 } |
| 375 } | 375 } |
| 376 } | 376 } |
| 377 if (isField) { | 377 if (isField) { |
| 378 int fieldCount = 1; | 378 int fieldCount = 1; |
| 379 token = parseVariableInitializerOpt(token); | 379 token = parseVariableInitializerOpt(token); |
| 380 while (optional(',', token)) { | 380 while (optional(',', token)) { |
| 381 token = parseIdentifier(token.next); | 381 token = parseIdentifier(token.next); |
| 382 token = parseVariableInitializerOpt(token); | 382 token = parseVariableInitializerOpt(token); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 472 token = parseModifier(token); | 472 token = parseModifier(token); |
| 473 count++; | 473 count++; |
| 474 } | 474 } |
| 475 listener.handleModifiers(count); | 475 listener.handleModifiers(count); |
| 476 return token; | 476 return token; |
| 477 } | 477 } |
| 478 | 478 |
| 479 Token peekAfterType(Token token) { | 479 Token peekAfterType(Token token) { |
| 480 // TODO(ahe): Also handle var? | 480 // TODO(ahe): Also handle var? |
| 481 if ('void' !== token.stringValue && !isIdentifier(token)) { | 481 if ('void' !== token.stringValue && !isIdentifier(token)) { |
| 482 listener.expectedIdentifier(token); | 482 listener.unexpected(token); |
| 483 } | 483 } |
| 484 // We are looking at "identifier ...". | 484 // We are looking at "identifier ...". |
| 485 Token peek = token.next; | 485 Token peek = token.next; |
| 486 if (peek.kind === PERIOD_TOKEN) { | 486 if (peek.kind === PERIOD_TOKEN) { |
| 487 if (isIdentifier(peek.next)) { | 487 if (isIdentifier(peek.next)) { |
| 488 // Look past a library prefix. | 488 // Look past a library prefix. |
| 489 peek = peek.next.next; | 489 peek = peek.next.next; |
| 490 } | 490 } |
| 491 } | 491 } |
| 492 // We are looking at "qualified ...". | 492 // We are looking at "qualified ...". |
| 493 if (peek.kind === LT_TOKEN) { | 493 if (peek.kind === LT_TOKEN) { |
| 494 // Possibly generic type. | 494 // Possibly generic type. |
| 495 // We are looking at "qualified '<'". | 495 // We are looking at "qualified '<'". |
| 496 BeginGroupToken beginGroupToken = peek; | 496 BeginGroupToken beginGroupToken = peek; |
| 497 Token gtToken = beginGroupToken.endGroup; | 497 Token gtToken = beginGroupToken.endGroup; |
| 498 if (gtToken !== null) { | 498 if (gtToken !== null) { |
| 499 // We are looking at "qualified '<' ... '>' ...". | 499 // We are looking at "qualified '<' ... '>' ...". |
| 500 return gtToken.next; | 500 return gtToken.next; |
| 501 } | 501 } |
| 502 } | 502 } |
| 503 return peek; | 503 return peek; |
| 504 } | 504 } |
| 505 | 505 |
| 506 Token parseClassBody(Token token) { | 506 Token parseClassBody(Token token) { |
| 507 Token begin = token; | 507 Token begin = token; |
| 508 listener.beginClassBody(token); | 508 listener.beginClassBody(token); |
| 509 if (!optional('{', token)) { | 509 if (!optional('{', token)) { |
| 510 return listener.expectedBlock(token); | 510 token = listener.unexpected(token); |
| 511 listener.endClassBody(0, begin, null); | |
| 512 return token; | |
| 511 } | 513 } |
| 512 token = token.next; | 514 token = token.next; |
| 513 int count = 0; | 515 int count = 0; |
| 514 while (notEofOrValue('}', token)) { | 516 while (notEofOrValue('}', token)) { |
| 515 token = parseMember(token); | 517 token = parseMember(token); |
| 516 ++count; | 518 ++count; |
| 517 } | 519 } |
| 518 listener.endClassBody(count, begin, token); | 520 listener.endClassBody(count, begin, token); |
| 519 return token; | 521 return token; |
| 520 } | 522 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 542 // error handling. | 544 // error handling. |
| 543 final String value = token.stringValue; | 545 final String value = token.stringValue; |
| 544 if ((value === '(') || (value === '.')) { | 546 if ((value === '(') || (value === '.')) { |
| 545 isField = false; | 547 isField = false; |
| 546 break; | 548 break; |
| 547 } else if ((value === '=') || (value === ';') || (value === ',')) { | 549 } else if ((value === '=') || (value === ';') || (value === ',')) { |
| 548 isField = true; | 550 isField = true; |
| 549 break; | 551 break; |
| 550 } else { | 552 } else { |
| 551 token = listener.unexpected(token); | 553 token = listener.unexpected(token); |
| 554 if (token.kind === EOF_TOKEN) { | |
| 555 listener.endFields(1, start, token); | |
| 556 return token; | |
| 557 } | |
| 552 } | 558 } |
| 553 } | 559 } |
| 554 if (isField) { | 560 if (isField) { |
| 555 int fieldCount = 1; | 561 int fieldCount = 1; |
| 556 token = parseVariableInitializerOpt(token); | 562 token = parseVariableInitializerOpt(token); |
| 557 while (optional(',', token)) { | 563 while (optional(',', token)) { |
| 558 // TODO(ahe): Count these. | 564 // TODO(ahe): Count these. |
| 559 token = parseIdentifier(token.next); | 565 token = parseIdentifier(token.next); |
| 560 token = parseVariableInitializerOpt(token); | 566 token = parseVariableInitializerOpt(token); |
| 561 ++fieldCount; | 567 ++fieldCount; |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 988 token = parseParenthesizedExpression(token); | 994 token = parseParenthesizedExpression(token); |
| 989 mayParseFunctionExpressions = old; | 995 mayParseFunctionExpressions = old; |
| 990 return token; | 996 return token; |
| 991 } | 997 } |
| 992 } | 998 } |
| 993 | 999 |
| 994 Token parseParenthesizedExpression(Token token) { | 1000 Token parseParenthesizedExpression(Token token) { |
| 995 BeginGroupToken begin = token; | 1001 BeginGroupToken begin = token; |
| 996 token = expect('(', token); | 1002 token = expect('(', token); |
| 997 token = parseExpression(token); | 1003 token = parseExpression(token); |
| 998 assert(begin.endGroup === token); | 1004 if (begin.endGroup !== token) { |
| 1005 listener.unexpected(token); | |
| 1006 token = begin.endGroup; | |
| 1007 } | |
| 999 listener.handleParenthesizedExpression(begin); | 1008 listener.handleParenthesizedExpression(begin); |
| 1000 return expect(')', token); | 1009 return expect(')', token); |
| 1001 } | 1010 } |
| 1002 | 1011 |
| 1003 Token parseThisExpression(Token token) { | 1012 Token parseThisExpression(Token token) { |
| 1004 listener.handleThisExpression(token); | 1013 listener.handleThisExpression(token); |
| 1005 token = token.next; | 1014 token = token.next; |
| 1006 if (optional('(', token)) { | 1015 if (optional('(', token)) { |
| 1007 // Constructor forwarding. | 1016 // Constructor forwarding. |
| 1008 token = parseArguments(token); | 1017 token = parseArguments(token); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1103 | 1112 |
| 1104 Token parseNewExpression(Token token) { | 1113 Token parseNewExpression(Token token) { |
| 1105 Token newKeyword = token; | 1114 Token newKeyword = token; |
| 1106 token = expect('new', token); | 1115 token = expect('new', token); |
| 1107 token = parseType(token); | 1116 token = parseType(token); |
| 1108 bool named = false; | 1117 bool named = false; |
| 1109 if (optional('.', token)) { | 1118 if (optional('.', token)) { |
| 1110 named = true; | 1119 named = true; |
| 1111 token = parseIdentifier(token.next); | 1120 token = parseIdentifier(token.next); |
| 1112 } | 1121 } |
| 1113 token = parseArguments(token); | 1122 if (optional('(', token)) { |
| 1123 token = parseArguments(token); | |
| 1124 } else { | |
| 1125 listener.handleNoArguments(token); | |
| 1126 token = listener.unexpected(token); | |
| 1127 } | |
| 1114 listener.handleNewExpression(newKeyword, named); | 1128 listener.handleNewExpression(newKeyword, named); |
| 1115 return token; | 1129 return token; |
| 1116 } | 1130 } |
| 1117 | 1131 |
| 1118 Token parseConstExpression(Token token) { | 1132 Token parseConstExpression(Token token) { |
| 1119 Token constKeyword = token; | 1133 Token constKeyword = token; |
| 1120 token = expect('const', token); | 1134 token = expect('const', token); |
| 1121 final String value = token.stringValue; | 1135 final String value = token.stringValue; |
| 1122 if ((value === '<') || | 1136 if ((value === '<') || |
| 1123 (value === '[') || | 1137 (value === '[') || |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1453 } | 1467 } |
| 1454 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1468 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1455 return expectSemicolon(token); | 1469 return expectSemicolon(token); |
| 1456 } | 1470 } |
| 1457 | 1471 |
| 1458 Token parseEmptyStatement(Token token) { | 1472 Token parseEmptyStatement(Token token) { |
| 1459 listener.handleEmptyStatement(token); | 1473 listener.handleEmptyStatement(token); |
| 1460 return expectSemicolon(token); | 1474 return expectSemicolon(token); |
| 1461 } | 1475 } |
| 1462 } | 1476 } |
| OLD | NEW |