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

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

Issue 9158001: Better error recovery. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix typo and update test status Created 8 years, 11 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
« no previous file with comments | « dart/frog/leg/scanner/listener.dart ('k') | dart/frog/leg/tools/find_file_to_parse.sh » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « dart/frog/leg/scanner/listener.dart ('k') | dart/frog/leg/tools/find_file_to_parse.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698