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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "tools/gn/functions.h" | 8 #include "tools/gn/functions.h" |
9 #include "tools/gn/operators.h" | 9 #include "tools/gn/operators.h" |
10 #include "tools/gn/token.h" | 10 #include "tools/gn/token.h" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 {&Parser::Name, &Parser::IdentifierOrCall, PRECEDENCE_CALL}, // IDENTIFIER | 75 {&Parser::Name, &Parser::IdentifierOrCall, PRECEDENCE_CALL}, // IDENTIFIER |
76 {NULL, NULL, -1}, // COMMA | 76 {NULL, NULL, -1}, // COMMA |
77 {NULL, NULL, -1}, // UNCLASSIFIED_COMMENT | 77 {NULL, NULL, -1}, // UNCLASSIFIED_COMMENT |
78 {NULL, NULL, -1}, // LINE_COMMENT | 78 {NULL, NULL, -1}, // LINE_COMMENT |
79 {NULL, NULL, -1}, // SUFFIX_COMMENT | 79 {NULL, NULL, -1}, // SUFFIX_COMMENT |
80 {&Parser::BlockComment, NULL, -1}, // BLOCK_COMMENT | 80 {&Parser::BlockComment, NULL, -1}, // BLOCK_COMMENT |
81 }; | 81 }; |
82 | 82 |
83 Parser::Parser(const std::vector<Token>& tokens, Err* err) | 83 Parser::Parser(const std::vector<Token>& tokens, Err* err) |
84 : err_(err), cur_(0) { | 84 : err_(err), cur_(0) { |
85 for (std::vector<Token>::const_iterator i(tokens.begin()); i != tokens.end(); | 85 for (const auto& token : tokens) { |
86 ++i) { | 86 switch(token.type()) { |
87 switch(i->type()) { | |
88 case Token::LINE_COMMENT: | 87 case Token::LINE_COMMENT: |
89 line_comment_tokens_.push_back(*i); | 88 line_comment_tokens_.push_back(token); |
90 break; | 89 break; |
91 case Token::SUFFIX_COMMENT: | 90 case Token::SUFFIX_COMMENT: |
92 suffix_comment_tokens_.push_back(*i); | 91 suffix_comment_tokens_.push_back(token); |
93 break; | 92 break; |
94 default: | 93 default: |
95 // Note that BLOCK_COMMENTs (top-level standalone comments) are passed | 94 // Note that BLOCK_COMMENTs (top-level standalone comments) are passed |
96 // through the real parser. | 95 // through the real parser. |
97 tokens_.push_back(*i); | 96 tokens_.push_back(token); |
98 break; | 97 break; |
99 } | 98 } |
100 } | 99 } |
101 } | 100 } |
102 | 101 |
103 Parser::~Parser() { | 102 Parser::~Parser() { |
104 } | 103 } |
105 | 104 |
106 // static | 105 // static |
107 scoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens, | 106 scoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens, |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 if (root) { | 512 if (root) { |
514 pre->push_back(root); | 513 pre->push_back(root); |
515 | 514 |
516 if (const AccessorNode* accessor = root->AsAccessor()) { | 515 if (const AccessorNode* accessor = root->AsAccessor()) { |
517 TraverseOrder(accessor->index(), pre, post); | 516 TraverseOrder(accessor->index(), pre, post); |
518 TraverseOrder(accessor->member(), pre, post); | 517 TraverseOrder(accessor->member(), pre, post); |
519 } else if (const BinaryOpNode* binop = root->AsBinaryOp()) { | 518 } else if (const BinaryOpNode* binop = root->AsBinaryOp()) { |
520 TraverseOrder(binop->left(), pre, post); | 519 TraverseOrder(binop->left(), pre, post); |
521 TraverseOrder(binop->right(), pre, post); | 520 TraverseOrder(binop->right(), pre, post); |
522 } else if (const BlockNode* block = root->AsBlock()) { | 521 } else if (const BlockNode* block = root->AsBlock()) { |
523 const std::vector<ParseNode*>& statements = block->statements(); | 522 for (const auto& statement : block->statements()) |
524 for (std::vector<ParseNode*>::const_iterator i(statements.begin()); | 523 TraverseOrder(statement, pre, post); |
525 i != statements.end(); | |
526 ++i) { | |
527 TraverseOrder(*i, pre, post); | |
528 } | |
529 TraverseOrder(block->End(), pre, post); | 524 TraverseOrder(block->End(), pre, post); |
530 } else if (const ConditionNode* condition = root->AsConditionNode()) { | 525 } else if (const ConditionNode* condition = root->AsConditionNode()) { |
531 TraverseOrder(condition->condition(), pre, post); | 526 TraverseOrder(condition->condition(), pre, post); |
532 TraverseOrder(condition->if_true(), pre, post); | 527 TraverseOrder(condition->if_true(), pre, post); |
533 TraverseOrder(condition->if_false(), pre, post); | 528 TraverseOrder(condition->if_false(), pre, post); |
534 } else if (const FunctionCallNode* func_call = root->AsFunctionCall()) { | 529 } else if (const FunctionCallNode* func_call = root->AsFunctionCall()) { |
535 TraverseOrder(func_call->args(), pre, post); | 530 TraverseOrder(func_call->args(), pre, post); |
536 TraverseOrder(func_call->block(), pre, post); | 531 TraverseOrder(func_call->block(), pre, post); |
537 } else if (root->AsIdentifier()) { | 532 } else if (root->AsIdentifier()) { |
538 // Nothing. | 533 // Nothing. |
539 } else if (const ListNode* list = root->AsList()) { | 534 } else if (const ListNode* list = root->AsList()) { |
540 const std::vector<const ParseNode*>& contents = list->contents(); | 535 for (const auto& node : list->contents()) |
541 for (std::vector<const ParseNode*>::const_iterator i(contents.begin()); | 536 TraverseOrder(node, pre, post); |
542 i != contents.end(); | |
543 ++i) { | |
544 TraverseOrder(*i, pre, post); | |
545 } | |
546 TraverseOrder(list->End(), pre, post); | 537 TraverseOrder(list->End(), pre, post); |
547 } else if (root->AsLiteral()) { | 538 } else if (root->AsLiteral()) { |
548 // Nothing. | 539 // Nothing. |
549 } else if (const UnaryOpNode* unaryop = root->AsUnaryOp()) { | 540 } else if (const UnaryOpNode* unaryop = root->AsUnaryOp()) { |
550 TraverseOrder(unaryop->operand(), pre, post); | 541 TraverseOrder(unaryop->operand(), pre, post); |
551 } else if (root->AsBlockComment()) { | 542 } else if (root->AsBlockComment()) { |
552 // Nothing. | 543 // Nothing. |
553 } else if (root->AsEnd()) { | 544 } else if (root->AsEnd()) { |
554 // Nothing. | 545 // Nothing. |
555 } else { | 546 } else { |
556 CHECK(false) << "Unhandled case in TraverseOrder."; | 547 CHECK(false) << "Unhandled case in TraverseOrder."; |
557 } | 548 } |
558 | 549 |
559 post->push_back(root); | 550 post->push_back(root); |
560 } | 551 } |
561 } | 552 } |
562 | 553 |
563 void Parser::AssignComments(ParseNode* file) { | 554 void Parser::AssignComments(ParseNode* file) { |
564 // Start by generating a pre- and post- order traversal of the tree so we | 555 // Start by generating a pre- and post- order traversal of the tree so we |
565 // can determine what's before and after comments. | 556 // can determine what's before and after comments. |
566 std::vector<const ParseNode*> pre; | 557 std::vector<const ParseNode*> pre; |
567 std::vector<const ParseNode*> post; | 558 std::vector<const ParseNode*> post; |
568 TraverseOrder(file, &pre, &post); | 559 TraverseOrder(file, &pre, &post); |
569 | 560 |
570 // Assign line comments to syntax immediately following. | 561 // Assign line comments to syntax immediately following. |
571 int cur_comment = 0; | 562 int cur_comment = 0; |
572 for (std::vector<const ParseNode*>::const_iterator i = pre.begin(); | 563 for (const auto& node : pre) { |
573 i != pre.end(); | 564 const Location& start = node->GetRange().begin(); |
574 ++i) { | |
575 const Location& start = (*i)->GetRange().begin(); | |
576 while (cur_comment < static_cast<int>(line_comment_tokens_.size())) { | 565 while (cur_comment < static_cast<int>(line_comment_tokens_.size())) { |
577 if (start.byte() >= line_comment_tokens_[cur_comment].location().byte()) { | 566 if (start.byte() >= line_comment_tokens_[cur_comment].location().byte()) { |
578 const_cast<ParseNode*>(*i)->comments_mutable()->append_before( | 567 const_cast<ParseNode*>(node)->comments_mutable()->append_before( |
579 line_comment_tokens_[cur_comment]); | 568 line_comment_tokens_[cur_comment]); |
580 ++cur_comment; | 569 ++cur_comment; |
581 } else { | 570 } else { |
582 break; | 571 break; |
583 } | 572 } |
584 } | 573 } |
585 } | 574 } |
586 | 575 |
587 // Remaining line comments go at end of file. | 576 // Remaining line comments go at end of file. |
588 for (; cur_comment < static_cast<int>(line_comment_tokens_.size()); | 577 for (; cur_comment < static_cast<int>(line_comment_tokens_.size()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 break; | 610 break; |
622 } | 611 } |
623 } | 612 } |
624 | 613 |
625 // Suffix comments were assigned in reverse, so if there were multiple on | 614 // Suffix comments were assigned in reverse, so if there were multiple on |
626 // the same node, they need to be reversed. | 615 // the same node, they need to be reversed. |
627 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) | 616 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) |
628 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); | 617 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); |
629 } | 618 } |
630 } | 619 } |
OLD | NEW |