OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/parser.h" | 5 #include "tools/gn/parser.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 Token::Type types[1] = { type }; | 381 Token::Type types[1] = { type }; |
382 return Consume(types, 1, error_message); | 382 return Consume(types, 1, error_message); |
383 } | 383 } |
384 | 384 |
385 Token Parser::Consume(Token::Type* types, | 385 Token Parser::Consume(Token::Type* types, |
386 size_t num_types, | 386 size_t num_types, |
387 const char* error_message) { | 387 const char* error_message) { |
388 if (has_error()) { | 388 if (has_error()) { |
389 // Don't overwrite current error, but make progress through tokens so that | 389 // Don't overwrite current error, but make progress through tokens so that |
390 // a loop that's expecting a particular token will still terminate. | 390 // a loop that's expecting a particular token will still terminate. |
391 cur_++; | 391 if (!at_end()) |
Nico
2016/08/25 16:07:49
this is unrelated but seems like a good change so
| |
392 cur_++; | |
392 return Token(Location(), Token::INVALID, base::StringPiece()); | 393 return Token(Location(), Token::INVALID, base::StringPiece()); |
393 } | 394 } |
394 if (at_end()) { | 395 if (at_end()) { |
395 const char kEOFMsg[] = "I hit EOF instead."; | 396 const char kEOFMsg[] = "I hit EOF instead."; |
396 if (tokens_.empty()) | 397 if (tokens_.empty()) |
397 *err_ = Err(Location(), error_message, kEOFMsg); | 398 *err_ = Err(Location(), error_message, kEOFMsg); |
398 else | 399 else |
399 *err_ = Err(tokens_[tokens_.size() - 1], error_message, kEOFMsg); | 400 *err_ = Err(tokens_[tokens_.size() - 1], error_message, kEOFMsg); |
400 return Token(Location(), Token::INVALID, base::StringPiece()); | 401 return Token(Location(), Token::INVALID, base::StringPiece()); |
401 } | 402 } |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
701 return BlockComment(Consume()); | 702 return BlockComment(Consume()); |
702 } else { | 703 } else { |
703 // TODO(scottmg): Is this too strict? Just drop all the testing if we want | 704 // TODO(scottmg): Is this too strict? Just drop all the testing if we want |
704 // to allow "pointless" expressions and return ParseExpression() directly. | 705 // to allow "pointless" expressions and return ParseExpression() directly. |
705 std::unique_ptr<ParseNode> stmt = ParseExpression(); | 706 std::unique_ptr<ParseNode> stmt = ParseExpression(); |
706 if (stmt) { | 707 if (stmt) { |
707 if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) | 708 if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) |
708 return stmt; | 709 return stmt; |
709 } | 710 } |
710 if (!has_error()) { | 711 if (!has_error()) { |
711 Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token(); | 712 Token token = cur_or_last_token(); |
Nico
2016/08/25 16:07:49
this is just extract-function
| |
712 *err_ = Err(token, "Expecting assignment or function call."); | 713 *err_ = Err(token, "Expecting assignment or function call."); |
713 } | 714 } |
714 return std::unique_ptr<ParseNode>(); | 715 return std::unique_ptr<ParseNode>(); |
715 } | 716 } |
716 } | 717 } |
717 | 718 |
718 std::unique_ptr<BlockNode> Parser::ParseBlock( | 719 std::unique_ptr<BlockNode> Parser::ParseBlock( |
719 Token begin_brace, | 720 Token begin_brace, |
720 BlockNode::ResultMode result_mode) { | 721 BlockNode::ResultMode result_mode) { |
721 if (has_error()) | 722 if (has_error()) |
(...skipping 26 matching lines...) Expand all Loading... | |
748 condition->set_if_true(ParseBlock( | 749 condition->set_if_true(ParseBlock( |
749 Consume(Token::LEFT_BRACE, "Expected '{' to start 'if' block."), | 750 Consume(Token::LEFT_BRACE, "Expected '{' to start 'if' block."), |
750 BlockNode::DISCARDS_RESULT)); | 751 BlockNode::DISCARDS_RESULT)); |
751 if (Match(Token::ELSE)) { | 752 if (Match(Token::ELSE)) { |
752 if (LookAhead(Token::LEFT_BRACE)) { | 753 if (LookAhead(Token::LEFT_BRACE)) { |
753 condition->set_if_false(ParseBlock(Consume(), | 754 condition->set_if_false(ParseBlock(Consume(), |
754 BlockNode::DISCARDS_RESULT)); | 755 BlockNode::DISCARDS_RESULT)); |
755 } else if (LookAhead(Token::IF)) { | 756 } else if (LookAhead(Token::IF)) { |
756 condition->set_if_false(ParseStatement()); | 757 condition->set_if_false(ParseStatement()); |
757 } else { | 758 } else { |
758 *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'."); | 759 *err_ = Err(cur_or_last_token(), "Expected '{' or 'if' after 'else'."); |
Nico
2016/08/25 16:07:49
this is the fix
| |
759 return std::unique_ptr<ParseNode>(); | 760 return std::unique_ptr<ParseNode>(); |
760 } | 761 } |
761 } | 762 } |
762 if (has_error()) | 763 if (has_error()) |
763 return std::unique_ptr<ParseNode>(); | 764 return std::unique_ptr<ParseNode>(); |
764 return std::move(condition); | 765 return std::move(condition); |
765 } | 766 } |
766 | 767 |
767 void Parser::TraverseOrder(const ParseNode* root, | 768 void Parser::TraverseOrder(const ParseNode* root, |
768 std::vector<const ParseNode*>* pre, | 769 std::vector<const ParseNode*>* pre, |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
868 break; | 869 break; |
869 } | 870 } |
870 } | 871 } |
871 | 872 |
872 // Suffix comments were assigned in reverse, so if there were multiple on | 873 // Suffix comments were assigned in reverse, so if there were multiple on |
873 // the same node, they need to be reversed. | 874 // the same node, they need to be reversed. |
874 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) | 875 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) |
875 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); | 876 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); |
876 } | 877 } |
877 } | 878 } |
OLD | NEW |