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

Side by Side Diff: runtime/vm/parser.cc

Issue 1054893003: Better error messages when matching parens and braces (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 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 | « runtime/vm/parser.h ('k') | no next file » | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/ast_transformer.h" 9 #include "vm/ast_transformer.h"
10 #include "vm/bootstrap.h" 10 #include "vm/bootstrap.h"
(...skipping 1526 matching lines...) Expand 10 before | Expand all | Expand 10 after
1537 AstNode* Parser::BuildClosureCall(intptr_t token_pos, 1537 AstNode* Parser::BuildClosureCall(intptr_t token_pos,
1538 AstNode* closure, 1538 AstNode* closure,
1539 ArgumentListNode* arguments) { 1539 ArgumentListNode* arguments) {
1540 return new InstanceCallNode(token_pos, 1540 return new InstanceCallNode(token_pos,
1541 closure, 1541 closure,
1542 Symbols::Call(), 1542 Symbols::Call(),
1543 arguments); 1543 arguments);
1544 } 1544 }
1545 1545
1546 1546
1547 void Parser::SkipBlock() { 1547 void Parser::SkipToMatching() {
1548 ASSERT(CurrentToken() == Token::kLBRACE); 1548 Token::Kind opening_token = CurrentToken();
1549 ASSERT((opening_token == Token::kLBRACE) ||
1550 (opening_token == Token::kLPAREN));
1549 GrowableArray<Token::Kind> token_stack(8); 1551 GrowableArray<Token::Kind> token_stack(8);
1550 // Adding the first kLBRACE here, because it will be consumed in the loop 1552 GrowableArray<intptr_t> token_pos_stack(8);
1551 // right away. 1553 // Adding the first opening brace here, because it will be consumed
1552 token_stack.Add(CurrentToken()); 1554 // in the loop right away.
1553 const intptr_t block_start_pos = TokenPos(); 1555 token_stack.Add(opening_token);
1556 const intptr_t start_pos = TokenPos();
1557 intptr_t opening_pos = start_pos;
1558 token_pos_stack.Add(start_pos);
1554 bool is_match = true; 1559 bool is_match = true;
1555 bool unexpected_token_found = false; 1560 bool unexpected_token_found = false;
1556 Token::Kind token; 1561 Token::Kind token = opening_token;
1557 intptr_t token_pos; 1562 intptr_t token_pos;
1558 do { 1563 do {
1559 ConsumeToken(); 1564 ConsumeToken();
1560 token = CurrentToken(); 1565 token = CurrentToken();
1561 token_pos = TokenPos(); 1566 token_pos = TokenPos();
1562 switch (token) { 1567 switch (token) {
1563 case Token::kLBRACE: 1568 case Token::kLBRACE:
1564 case Token::kLPAREN: 1569 case Token::kLPAREN:
1565 case Token::kLBRACK: 1570 case Token::kLBRACK:
1566 token_stack.Add(token); 1571 token_stack.Add(token);
1572 token_pos_stack.Add(token_pos);
1567 break; 1573 break;
1568 case Token::kRBRACE: 1574 case Token::kRBRACE:
1569 is_match = token_stack.RemoveLast() == Token::kLBRACE; 1575 opening_token = token_stack.RemoveLast();
1576 opening_pos = token_pos_stack.RemoveLast();
1577 is_match = opening_token == Token::kLBRACE;
1570 break; 1578 break;
1571 case Token::kRPAREN: 1579 case Token::kRPAREN:
1572 is_match = token_stack.RemoveLast() == Token::kLPAREN; 1580 opening_token = token_stack.RemoveLast();
1581 opening_pos = token_pos_stack.RemoveLast();
1582 is_match = opening_token == Token::kLPAREN;
1573 break; 1583 break;
1574 case Token::kRBRACK: 1584 case Token::kRBRACK:
1575 is_match = token_stack.RemoveLast() == Token::kLBRACK; 1585 opening_token = token_stack.RemoveLast();
1586 opening_pos = token_pos_stack.RemoveLast();
1587 is_match = opening_token == Token::kLBRACK;
1576 break; 1588 break;
1577 case Token::kEOS: 1589 case Token::kEOS:
1578 unexpected_token_found = true; 1590 unexpected_token_found = true;
1579 break; 1591 break;
1580 default: 1592 default:
1581 // nothing. 1593 // nothing.
1582 break; 1594 break;
1583 } 1595 }
1584 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); 1596 } while (!token_stack.is_empty() && is_match && !unexpected_token_found);
1585 if (!is_match) { 1597 if (!is_match) {
1586 ReportError(token_pos, "unbalanced '%s'", Token::Str(token)); 1598 const Error& error = Error::Handle(
1599 LanguageError::NewFormatted(Error::Handle(), // No previous error.
1600 script_, opening_pos,
1601 Report::kWarning,
1602 Heap::kNew,
1603 "unbalanced '%s' opens here",
1604 Token::Str(opening_token)));
1605 ReportErrors(error, script_, token_pos,
1606 "unbalanced '%s'", Token::Str(token));
1587 } else if (unexpected_token_found) { 1607 } else if (unexpected_token_found) {
1588 ReportError(block_start_pos, "unterminated block"); 1608 ReportError(start_pos, "unterminated '%s'", Token::Str(opening_token));
1589 } 1609 }
1590 } 1610 }
1591 1611
1592 1612
1613
1614 void Parser::SkipBlock() {
1615 ASSERT(CurrentToken() == Token::kLBRACE);
1616 SkipToMatching();
1617 }
1618
1619
1620 // Skips tokens up to and including matching closing parenthesis.
1621 void Parser::SkipToMatchingParenthesis() {
1622 ASSERT(CurrentToken() == Token::kLPAREN);
1623 SkipToMatching();
1624 ASSERT(CurrentToken() == Token::kRPAREN);
1625 ConsumeToken();
1626 }
1627
1628
1593 void Parser::ParseFormalParameter(bool allow_explicit_default_value, 1629 void Parser::ParseFormalParameter(bool allow_explicit_default_value,
1594 bool evaluate_metadata, 1630 bool evaluate_metadata,
1595 ParamList* params) { 1631 ParamList* params) {
1596 TRACE_PARSER("ParseFormalParameter"); 1632 TRACE_PARSER("ParseFormalParameter");
1597 ParamDesc parameter; 1633 ParamDesc parameter;
1598 bool var_seen = false; 1634 bool var_seen = false;
1599 bool this_seen = false; 1635 bool this_seen = false;
1600 1636
1601 if (evaluate_metadata && (CurrentToken() == Token::kAT)) { 1637 if (evaluate_metadata && (CurrentToken() == Token::kAT)) {
1602 parameter.metadata = &Array::ZoneHandle(Z, EvaluateMetadata()); 1638 parameter.metadata = &Array::ZoneHandle(Z, EvaluateMetadata());
(...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 } 3396 }
3361 3397
3362 3398
3363 void Parser::SkipIf(Token::Kind token) { 3399 void Parser::SkipIf(Token::Kind token) {
3364 if (CurrentToken() == token) { 3400 if (CurrentToken() == token) {
3365 ConsumeToken(); 3401 ConsumeToken();
3366 } 3402 }
3367 } 3403 }
3368 3404
3369 3405
3370 // Skips tokens up to matching closing parenthesis.
3371 void Parser::SkipToMatchingParenthesis() {
3372 Token::Kind current_token = CurrentToken();
3373 ASSERT(current_token == Token::kLPAREN);
3374 int level = 0;
3375 do {
3376 if (current_token == Token::kLPAREN) {
3377 level++;
3378 } else if (current_token == Token::kRPAREN) {
3379 level--;
3380 }
3381 ConsumeToken();
3382 current_token = CurrentToken();
3383 } while ((level > 0) && (current_token != Token::kEOS));
3384 }
3385
3386
3387 void Parser::SkipInitializers() { 3406 void Parser::SkipInitializers() {
3388 ASSERT(CurrentToken() == Token::kCOLON); 3407 ASSERT(CurrentToken() == Token::kCOLON);
3389 do { 3408 do {
3390 ConsumeToken(); // Colon or comma. 3409 ConsumeToken(); // Colon or comma.
3391 if (CurrentToken() == Token::kSUPER) { 3410 if (CurrentToken() == Token::kSUPER) {
3392 ConsumeToken(); 3411 ConsumeToken();
3393 if (CurrentToken() == Token::kPERIOD) { 3412 if (CurrentToken() == Token::kPERIOD) {
3394 ConsumeToken(); 3413 ConsumeToken();
3395 ExpectIdentifier("identifier expected"); 3414 ExpectIdentifier("identifier expected");
3396 } 3415 }
(...skipping 10011 matching lines...) Expand 10 before | Expand all | Expand 10 after
13408 void Parser::SkipQualIdent() { 13427 void Parser::SkipQualIdent() {
13409 ASSERT(IsIdentifier()); 13428 ASSERT(IsIdentifier());
13410 ConsumeToken(); 13429 ConsumeToken();
13411 if (CurrentToken() == Token::kPERIOD) { 13430 if (CurrentToken() == Token::kPERIOD) {
13412 ConsumeToken(); // Consume the kPERIOD token. 13431 ConsumeToken(); // Consume the kPERIOD token.
13413 ExpectIdentifier("identifier expected after '.'"); 13432 ExpectIdentifier("identifier expected after '.'");
13414 } 13433 }
13415 } 13434 }
13416 13435
13417 } // namespace dart 13436 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698