OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |