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

Side by Side Diff: tools/gn/parser.cc

Issue 1869503004: Convert //tools to use std::unique_ptr (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase, change iwyu fixes for converted directories to include <memory> Created 4 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
« no previous file with comments | « tools/gn/parser.h ('k') | tools/gn/parser_unittest.cc » ('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) 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 "tools/gn/functions.h" 11 #include "tools/gn/functions.h"
11 #include "tools/gn/operators.h" 12 #include "tools/gn/operators.h"
12 #include "tools/gn/token.h" 13 #include "tools/gn/token.h"
13 14
14 const char kGrammar_Help[] = 15 const char kGrammar_Help[] =
15 "GN build language grammar\n" 16 "GN build language grammar\n"
16 "\n" 17 "\n"
17 "Tokens\n" 18 "Tokens\n"
18 "\n" 19 "\n"
19 " GN build files are read as sequences of tokens. While splitting the\n" 20 " GN build files are read as sequences of tokens. While splitting the\n"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 tokens_.push_back(token); 200 tokens_.push_back(token);
200 break; 201 break;
201 } 202 }
202 } 203 }
203 } 204 }
204 205
205 Parser::~Parser() { 206 Parser::~Parser() {
206 } 207 }
207 208
208 // static 209 // static
209 scoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens, 210 std::unique_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens,
210 Err* err) { 211 Err* err) {
211 Parser p(tokens, err); 212 Parser p(tokens, err);
212 return p.ParseFile(); 213 return p.ParseFile();
213 } 214 }
214 215
215 // static 216 // static
216 scoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens, 217 std::unique_ptr<ParseNode> Parser::ParseExpression(
217 Err* err) { 218 const std::vector<Token>& tokens,
219 Err* err) {
218 Parser p(tokens, err); 220 Parser p(tokens, err);
219 scoped_ptr<ParseNode> expr = p.ParseExpression(); 221 std::unique_ptr<ParseNode> expr = p.ParseExpression();
220 if (!p.at_end() && !err->has_error()) { 222 if (!p.at_end() && !err->has_error()) {
221 *err = Err(p.cur_token(), "Trailing garbage"); 223 *err = Err(p.cur_token(), "Trailing garbage");
222 return nullptr; 224 return nullptr;
223 } 225 }
224 return expr; 226 return expr;
225 } 227 }
226 228
227 // static 229 // static
228 scoped_ptr<ParseNode> Parser::ParseValue(const std::vector<Token>& tokens, 230 std::unique_ptr<ParseNode> Parser::ParseValue(const std::vector<Token>& tokens,
229 Err* err) { 231 Err* err) {
230 for (const Token& token : tokens) { 232 for (const Token& token : tokens) {
231 switch (token.type()) { 233 switch (token.type()) {
232 case Token::INTEGER: 234 case Token::INTEGER:
233 case Token::STRING: 235 case Token::STRING:
234 case Token::TRUE_TOKEN: 236 case Token::TRUE_TOKEN:
235 case Token::FALSE_TOKEN: 237 case Token::FALSE_TOKEN:
236 case Token::LEFT_BRACKET: 238 case Token::LEFT_BRACKET:
237 case Token::RIGHT_BRACKET: 239 case Token::RIGHT_BRACKET:
238 case Token::COMMA: 240 case Token::COMMA:
239 continue; 241 continue;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 return Consume(); 309 return Consume();
308 } 310 }
309 *err_ = Err(cur_token(), error_message); 311 *err_ = Err(cur_token(), error_message);
310 return Token(Location(), Token::INVALID, base::StringPiece()); 312 return Token(Location(), Token::INVALID, base::StringPiece());
311 } 313 }
312 314
313 Token Parser::Consume() { 315 Token Parser::Consume() {
314 return tokens_[cur_++]; 316 return tokens_[cur_++];
315 } 317 }
316 318
317 scoped_ptr<ParseNode> Parser::ParseExpression() { 319 std::unique_ptr<ParseNode> Parser::ParseExpression() {
318 return ParseExpression(0); 320 return ParseExpression(0);
319 } 321 }
320 322
321 scoped_ptr<ParseNode> Parser::ParseExpression(int precedence) { 323 std::unique_ptr<ParseNode> Parser::ParseExpression(int precedence) {
322 if (at_end()) 324 if (at_end())
323 return scoped_ptr<ParseNode>(); 325 return std::unique_ptr<ParseNode>();
324 326
325 Token token = Consume(); 327 Token token = Consume();
326 PrefixFunc prefix = expressions_[token.type()].prefix; 328 PrefixFunc prefix = expressions_[token.type()].prefix;
327 329
328 if (prefix == nullptr) { 330 if (prefix == nullptr) {
329 *err_ = Err(token, 331 *err_ = Err(token,
330 std::string("Unexpected token '") + token.value().as_string() + 332 std::string("Unexpected token '") + token.value().as_string() +
331 std::string("'")); 333 std::string("'"));
332 return scoped_ptr<ParseNode>(); 334 return std::unique_ptr<ParseNode>();
333 } 335 }
334 336
335 scoped_ptr<ParseNode> left = (this->*prefix)(token); 337 std::unique_ptr<ParseNode> left = (this->*prefix)(token);
336 if (has_error()) 338 if (has_error())
337 return left; 339 return left;
338 340
339 while (!at_end() && !IsStatementBreak(cur_token().type()) && 341 while (!at_end() && !IsStatementBreak(cur_token().type()) &&
340 precedence <= expressions_[cur_token().type()].precedence) { 342 precedence <= expressions_[cur_token().type()].precedence) {
341 token = Consume(); 343 token = Consume();
342 InfixFunc infix = expressions_[token.type()].infix; 344 InfixFunc infix = expressions_[token.type()].infix;
343 if (infix == nullptr) { 345 if (infix == nullptr) {
344 *err_ = Err(token, 346 *err_ = Err(token,
345 std::string("Unexpected token '") + 347 std::string("Unexpected token '") +
346 token.value().as_string() + std::string("'")); 348 token.value().as_string() + std::string("'"));
347 return scoped_ptr<ParseNode>(); 349 return std::unique_ptr<ParseNode>();
348 } 350 }
349 left = (this->*infix)(std::move(left), token); 351 left = (this->*infix)(std::move(left), token);
350 if (has_error()) 352 if (has_error())
351 return scoped_ptr<ParseNode>(); 353 return std::unique_ptr<ParseNode>();
352 } 354 }
353 355
354 return left; 356 return left;
355 } 357 }
356 358
357 scoped_ptr<ParseNode> Parser::Literal(Token token) { 359 std::unique_ptr<ParseNode> Parser::Literal(Token token) {
358 return make_scoped_ptr(new LiteralNode(token)); 360 return base::WrapUnique(new LiteralNode(token));
359 } 361 }
360 362
361 scoped_ptr<ParseNode> Parser::Name(Token token) { 363 std::unique_ptr<ParseNode> Parser::Name(Token token) {
362 return IdentifierOrCall(scoped_ptr<ParseNode>(), token); 364 return IdentifierOrCall(std::unique_ptr<ParseNode>(), token);
363 } 365 }
364 366
365 scoped_ptr<ParseNode> Parser::BlockComment(Token token) { 367 std::unique_ptr<ParseNode> Parser::BlockComment(Token token) {
366 scoped_ptr<BlockCommentNode> comment(new BlockCommentNode()); 368 std::unique_ptr<BlockCommentNode> comment(new BlockCommentNode());
367 comment->set_comment(token); 369 comment->set_comment(token);
368 return std::move(comment); 370 return std::move(comment);
369 } 371 }
370 372
371 scoped_ptr<ParseNode> Parser::Group(Token token) { 373 std::unique_ptr<ParseNode> Parser::Group(Token token) {
372 scoped_ptr<ParseNode> expr = ParseExpression(); 374 std::unique_ptr<ParseNode> expr = ParseExpression();
373 if (has_error()) 375 if (has_error())
374 return scoped_ptr<ParseNode>(); 376 return std::unique_ptr<ParseNode>();
375 Consume(Token::RIGHT_PAREN, "Expected ')'"); 377 Consume(Token::RIGHT_PAREN, "Expected ')'");
376 return expr; 378 return expr;
377 } 379 }
378 380
379 scoped_ptr<ParseNode> Parser::Not(Token token) { 381 std::unique_ptr<ParseNode> Parser::Not(Token token) {
380 scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1); 382 std::unique_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1);
381 if (has_error()) 383 if (has_error())
382 return scoped_ptr<ParseNode>(); 384 return std::unique_ptr<ParseNode>();
383 if (!expr) { 385 if (!expr) {
384 if (!has_error()) 386 if (!has_error())
385 *err_ = Err(token, "Expected right-hand side for '!'."); 387 *err_ = Err(token, "Expected right-hand side for '!'.");
386 return scoped_ptr<ParseNode>(); 388 return std::unique_ptr<ParseNode>();
387 } 389 }
388 scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode); 390 std::unique_ptr<UnaryOpNode> unary_op(new UnaryOpNode);
389 unary_op->set_op(token); 391 unary_op->set_op(token);
390 unary_op->set_operand(std::move(expr)); 392 unary_op->set_operand(std::move(expr));
391 return std::move(unary_op); 393 return std::move(unary_op);
392 } 394 }
393 395
394 scoped_ptr<ParseNode> Parser::List(Token node) { 396 std::unique_ptr<ParseNode> Parser::List(Token node) {
395 scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true)); 397 std::unique_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true));
396 if (!has_error() && !at_end()) 398 if (!has_error() && !at_end())
397 Consume(Token::RIGHT_BRACKET, "Expected ']'"); 399 Consume(Token::RIGHT_BRACKET, "Expected ']'");
398 return list; 400 return list;
399 } 401 }
400 402
401 scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left, 403 std::unique_ptr<ParseNode> Parser::BinaryOperator(
402 Token token) { 404 std::unique_ptr<ParseNode> left,
403 scoped_ptr<ParseNode> right = 405 Token token) {
406 std::unique_ptr<ParseNode> right =
404 ParseExpression(expressions_[token.type()].precedence + 1); 407 ParseExpression(expressions_[token.type()].precedence + 1);
405 if (!right) { 408 if (!right) {
406 if (!has_error()) { 409 if (!has_error()) {
407 *err_ = Err(token, "Expected right-hand side for '" + 410 *err_ = Err(token, "Expected right-hand side for '" +
408 token.value().as_string() + "'"); 411 token.value().as_string() + "'");
409 } 412 }
410 return scoped_ptr<ParseNode>(); 413 return std::unique_ptr<ParseNode>();
411 } 414 }
412 scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode); 415 std::unique_ptr<BinaryOpNode> binary_op(new BinaryOpNode);
413 binary_op->set_op(token); 416 binary_op->set_op(token);
414 binary_op->set_left(std::move(left)); 417 binary_op->set_left(std::move(left));
415 binary_op->set_right(std::move(right)); 418 binary_op->set_right(std::move(right));
416 return std::move(binary_op); 419 return std::move(binary_op);
417 } 420 }
418 421
419 scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left, 422 std::unique_ptr<ParseNode> Parser::IdentifierOrCall(
420 Token token) { 423 std::unique_ptr<ParseNode> left,
421 scoped_ptr<ListNode> list(new ListNode); 424 Token token) {
425 std::unique_ptr<ListNode> list(new ListNode);
422 list->set_begin_token(token); 426 list->set_begin_token(token);
423 list->set_end(make_scoped_ptr(new EndNode(token))); 427 list->set_end(base::WrapUnique(new EndNode(token)));
424 scoped_ptr<BlockNode> block; 428 std::unique_ptr<BlockNode> block;
425 bool has_arg = false; 429 bool has_arg = false;
426 if (LookAhead(Token::LEFT_PAREN)) { 430 if (LookAhead(Token::LEFT_PAREN)) {
427 Token start_token = Consume(); 431 Token start_token = Consume();
428 // Parsing a function call. 432 // Parsing a function call.
429 has_arg = true; 433 has_arg = true;
430 if (Match(Token::RIGHT_PAREN)) { 434 if (Match(Token::RIGHT_PAREN)) {
431 // Nothing, just an empty call. 435 // Nothing, just an empty call.
432 } else { 436 } else {
433 list = ParseList(start_token, Token::RIGHT_PAREN, false); 437 list = ParseList(start_token, Token::RIGHT_PAREN, false);
434 if (has_error()) 438 if (has_error())
435 return scoped_ptr<ParseNode>(); 439 return std::unique_ptr<ParseNode>();
436 Consume(Token::RIGHT_PAREN, "Expected ')' after call"); 440 Consume(Token::RIGHT_PAREN, "Expected ')' after call");
437 } 441 }
438 // Optionally with a scope. 442 // Optionally with a scope.
439 if (LookAhead(Token::LEFT_BRACE)) { 443 if (LookAhead(Token::LEFT_BRACE)) {
440 block = ParseBlock(); 444 block = ParseBlock();
441 if (has_error()) 445 if (has_error())
442 return scoped_ptr<ParseNode>(); 446 return std::unique_ptr<ParseNode>();
443 } 447 }
444 } 448 }
445 449
446 if (!left && !has_arg) { 450 if (!left && !has_arg) {
447 // Not a function call, just a standalone identifier. 451 // Not a function call, just a standalone identifier.
448 return scoped_ptr<ParseNode>(new IdentifierNode(token)); 452 return std::unique_ptr<ParseNode>(new IdentifierNode(token));
449 } 453 }
450 scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode); 454 std::unique_ptr<FunctionCallNode> func_call(new FunctionCallNode);
451 func_call->set_function(token); 455 func_call->set_function(token);
452 func_call->set_args(std::move(list)); 456 func_call->set_args(std::move(list));
453 if (block) 457 if (block)
454 func_call->set_block(std::move(block)); 458 func_call->set_block(std::move(block));
455 return std::move(func_call); 459 return std::move(func_call);
456 } 460 }
457 461
458 scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left, 462 std::unique_ptr<ParseNode> Parser::Assignment(std::unique_ptr<ParseNode> left,
459 Token token) { 463 Token token) {
460 if (left->AsIdentifier() == nullptr) { 464 if (left->AsIdentifier() == nullptr) {
461 *err_ = Err(left.get(), "Left-hand side of assignment must be identifier."); 465 *err_ = Err(left.get(), "Left-hand side of assignment must be identifier.");
462 return scoped_ptr<ParseNode>(); 466 return std::unique_ptr<ParseNode>();
463 } 467 }
464 scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT); 468 std::unique_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT);
465 if (!value) { 469 if (!value) {
466 if (!has_error()) 470 if (!has_error())
467 *err_ = Err(token, "Expected right-hand side for assignment."); 471 *err_ = Err(token, "Expected right-hand side for assignment.");
468 return scoped_ptr<ParseNode>(); 472 return std::unique_ptr<ParseNode>();
469 } 473 }
470 scoped_ptr<BinaryOpNode> assign(new BinaryOpNode); 474 std::unique_ptr<BinaryOpNode> assign(new BinaryOpNode);
471 assign->set_op(token); 475 assign->set_op(token);
472 assign->set_left(std::move(left)); 476 assign->set_left(std::move(left));
473 assign->set_right(std::move(value)); 477 assign->set_right(std::move(value));
474 return std::move(assign); 478 return std::move(assign);
475 } 479 }
476 480
477 scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left, 481 std::unique_ptr<ParseNode> Parser::Subscript(std::unique_ptr<ParseNode> left,
478 Token token) { 482 Token token) {
479 // TODO: Maybe support more complex expressions like a[0][0]. This would 483 // TODO: Maybe support more complex expressions like a[0][0]. This would
480 // require work on the evaluator too. 484 // require work on the evaluator too.
481 if (left->AsIdentifier() == nullptr) { 485 if (left->AsIdentifier() == nullptr) {
482 *err_ = Err(left.get(), "May only subscript identifiers.", 486 *err_ = Err(left.get(), "May only subscript identifiers.",
483 "The thing on the left hand side of the [] must be an identifier\n" 487 "The thing on the left hand side of the [] must be an identifier\n"
484 "and not an expression. If you need this, you'll have to assign the\n" 488 "and not an expression. If you need this, you'll have to assign the\n"
485 "value to a temporary before subscripting. Sorry."); 489 "value to a temporary before subscripting. Sorry.");
486 return scoped_ptr<ParseNode>(); 490 return std::unique_ptr<ParseNode>();
487 } 491 }
488 scoped_ptr<ParseNode> value = ParseExpression(); 492 std::unique_ptr<ParseNode> value = ParseExpression();
489 Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript."); 493 Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript.");
490 scoped_ptr<AccessorNode> accessor(new AccessorNode); 494 std::unique_ptr<AccessorNode> accessor(new AccessorNode);
491 accessor->set_base(left->AsIdentifier()->value()); 495 accessor->set_base(left->AsIdentifier()->value());
492 accessor->set_index(std::move(value)); 496 accessor->set_index(std::move(value));
493 return std::move(accessor); 497 return std::move(accessor);
494 } 498 }
495 499
496 scoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left, 500 std::unique_ptr<ParseNode> Parser::DotOperator(std::unique_ptr<ParseNode> left,
497 Token token) { 501 Token token) {
498 if (left->AsIdentifier() == nullptr) { 502 if (left->AsIdentifier() == nullptr) {
499 *err_ = Err(left.get(), "May only use \".\" for identifiers.", 503 *err_ = Err(left.get(), "May only use \".\" for identifiers.",
500 "The thing on the left hand side of the dot must be an identifier\n" 504 "The thing on the left hand side of the dot must be an identifier\n"
501 "and not an expression. If you need this, you'll have to assign the\n" 505 "and not an expression. If you need this, you'll have to assign the\n"
502 "value to a temporary first. Sorry."); 506 "value to a temporary first. Sorry.");
503 return scoped_ptr<ParseNode>(); 507 return std::unique_ptr<ParseNode>();
504 } 508 }
505 509
506 scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT); 510 std::unique_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT);
507 if (!right || !right->AsIdentifier()) { 511 if (!right || !right->AsIdentifier()) {
508 *err_ = Err(token, "Expected identifier for right-hand-side of \".\"", 512 *err_ = Err(token, "Expected identifier for right-hand-side of \".\"",
509 "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()"); 513 "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()");
510 return scoped_ptr<ParseNode>(); 514 return std::unique_ptr<ParseNode>();
511 } 515 }
512 516
513 scoped_ptr<AccessorNode> accessor(new AccessorNode); 517 std::unique_ptr<AccessorNode> accessor(new AccessorNode);
514 accessor->set_base(left->AsIdentifier()->value()); 518 accessor->set_base(left->AsIdentifier()->value());
515 accessor->set_member(scoped_ptr<IdentifierNode>( 519 accessor->set_member(std::unique_ptr<IdentifierNode>(
516 static_cast<IdentifierNode*>(right.release()))); 520 static_cast<IdentifierNode*>(right.release())));
517 return std::move(accessor); 521 return std::move(accessor);
518 } 522 }
519 523
520 // Does not Consume the start or end token. 524 // Does not Consume the start or end token.
521 scoped_ptr<ListNode> Parser::ParseList(Token start_token, 525 std::unique_ptr<ListNode> Parser::ParseList(Token start_token,
522 Token::Type stop_before, 526 Token::Type stop_before,
523 bool allow_trailing_comma) { 527 bool allow_trailing_comma) {
524 scoped_ptr<ListNode> list(new ListNode); 528 std::unique_ptr<ListNode> list(new ListNode);
525 list->set_begin_token(start_token); 529 list->set_begin_token(start_token);
526 bool just_got_comma = false; 530 bool just_got_comma = false;
527 bool first_time = true; 531 bool first_time = true;
528 while (!LookAhead(stop_before)) { 532 while (!LookAhead(stop_before)) {
529 if (!first_time) { 533 if (!first_time) {
530 if (!just_got_comma) { 534 if (!just_got_comma) {
531 // Require commas separate things in lists. 535 // Require commas separate things in lists.
532 *err_ = Err(cur_token(), "Expected comma between items."); 536 *err_ = Err(cur_token(), "Expected comma between items.");
533 return scoped_ptr<ListNode>(); 537 return std::unique_ptr<ListNode>();
534 } 538 }
535 } 539 }
536 first_time = false; 540 first_time = false;
537 541
538 // Why _OR? We're parsing things that are higher precedence than the , 542 // Why _OR? We're parsing things that are higher precedence than the ,
539 // that separates the items of the list. , should appear lower than 543 // that separates the items of the list. , should appear lower than
540 // boolean expressions (the lowest of which is OR), but above assignments. 544 // boolean expressions (the lowest of which is OR), but above assignments.
541 list->append_item(ParseExpression(PRECEDENCE_OR)); 545 list->append_item(ParseExpression(PRECEDENCE_OR));
542 if (has_error()) 546 if (has_error())
543 return scoped_ptr<ListNode>(); 547 return std::unique_ptr<ListNode>();
544 if (at_end()) { 548 if (at_end()) {
545 *err_ = 549 *err_ =
546 Err(tokens_[tokens_.size() - 1], "Unexpected end of file in list."); 550 Err(tokens_[tokens_.size() - 1], "Unexpected end of file in list.");
547 return scoped_ptr<ListNode>(); 551 return std::unique_ptr<ListNode>();
548 } 552 }
549 if (list->contents().back()->AsBlockComment()) { 553 if (list->contents().back()->AsBlockComment()) {
550 // If there was a comment inside the list, we don't need a comma to the 554 // If there was a comment inside the list, we don't need a comma to the
551 // next item, so pretend we got one, if we're expecting one. 555 // next item, so pretend we got one, if we're expecting one.
552 just_got_comma = allow_trailing_comma; 556 just_got_comma = allow_trailing_comma;
553 } else { 557 } else {
554 just_got_comma = Match(Token::COMMA); 558 just_got_comma = Match(Token::COMMA);
555 } 559 }
556 } 560 }
557 if (just_got_comma && !allow_trailing_comma) { 561 if (just_got_comma && !allow_trailing_comma) {
558 *err_ = Err(cur_token(), "Trailing comma"); 562 *err_ = Err(cur_token(), "Trailing comma");
559 return scoped_ptr<ListNode>(); 563 return std::unique_ptr<ListNode>();
560 } 564 }
561 list->set_end(make_scoped_ptr(new EndNode(cur_token()))); 565 list->set_end(base::WrapUnique(new EndNode(cur_token())));
562 return list; 566 return list;
563 } 567 }
564 568
565 scoped_ptr<ParseNode> Parser::ParseFile() { 569 std::unique_ptr<ParseNode> Parser::ParseFile() {
566 scoped_ptr<BlockNode> file(new BlockNode); 570 std::unique_ptr<BlockNode> file(new BlockNode);
567 for (;;) { 571 for (;;) {
568 if (at_end()) 572 if (at_end())
569 break; 573 break;
570 scoped_ptr<ParseNode> statement = ParseStatement(); 574 std::unique_ptr<ParseNode> statement = ParseStatement();
571 if (!statement) 575 if (!statement)
572 break; 576 break;
573 file->append_statement(std::move(statement)); 577 file->append_statement(std::move(statement));
574 } 578 }
575 if (!at_end() && !has_error()) 579 if (!at_end() && !has_error())
576 *err_ = Err(cur_token(), "Unexpected here, should be newline."); 580 *err_ = Err(cur_token(), "Unexpected here, should be newline.");
577 if (has_error()) 581 if (has_error())
578 return scoped_ptr<ParseNode>(); 582 return std::unique_ptr<ParseNode>();
579 583
580 // TODO(scottmg): If this is measurably expensive, it could be done only 584 // TODO(scottmg): If this is measurably expensive, it could be done only
581 // when necessary (when reformatting, or during tests). Comments are 585 // when necessary (when reformatting, or during tests). Comments are
582 // separate from the parse tree at this point, so downstream code can remain 586 // separate from the parse tree at this point, so downstream code can remain
583 // ignorant of them. 587 // ignorant of them.
584 AssignComments(file.get()); 588 AssignComments(file.get());
585 589
586 return std::move(file); 590 return std::move(file);
587 } 591 }
588 592
589 scoped_ptr<ParseNode> Parser::ParseStatement() { 593 std::unique_ptr<ParseNode> Parser::ParseStatement() {
590 if (LookAhead(Token::IF)) { 594 if (LookAhead(Token::IF)) {
591 return ParseCondition(); 595 return ParseCondition();
592 } else if (LookAhead(Token::BLOCK_COMMENT)) { 596 } else if (LookAhead(Token::BLOCK_COMMENT)) {
593 return BlockComment(Consume()); 597 return BlockComment(Consume());
594 } else { 598 } else {
595 // TODO(scottmg): Is this too strict? Just drop all the testing if we want 599 // TODO(scottmg): Is this too strict? Just drop all the testing if we want
596 // to allow "pointless" expressions and return ParseExpression() directly. 600 // to allow "pointless" expressions and return ParseExpression() directly.
597 scoped_ptr<ParseNode> stmt = ParseExpression(); 601 std::unique_ptr<ParseNode> stmt = ParseExpression();
598 if (stmt) { 602 if (stmt) {
599 if (stmt->AsFunctionCall() || IsAssignment(stmt.get())) 603 if (stmt->AsFunctionCall() || IsAssignment(stmt.get()))
600 return stmt; 604 return stmt;
601 } 605 }
602 if (!has_error()) { 606 if (!has_error()) {
603 Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token(); 607 Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token();
604 *err_ = Err(token, "Expecting assignment or function call."); 608 *err_ = Err(token, "Expecting assignment or function call.");
605 } 609 }
606 return scoped_ptr<ParseNode>(); 610 return std::unique_ptr<ParseNode>();
607 } 611 }
608 } 612 }
609 613
610 scoped_ptr<BlockNode> Parser::ParseBlock() { 614 std::unique_ptr<BlockNode> Parser::ParseBlock() {
611 Token begin_token = 615 Token begin_token =
612 Consume(Token::LEFT_BRACE, "Expected '{' to start a block."); 616 Consume(Token::LEFT_BRACE, "Expected '{' to start a block.");
613 if (has_error()) 617 if (has_error())
614 return scoped_ptr<BlockNode>(); 618 return std::unique_ptr<BlockNode>();
615 scoped_ptr<BlockNode> block(new BlockNode); 619 std::unique_ptr<BlockNode> block(new BlockNode);
616 block->set_begin_token(begin_token); 620 block->set_begin_token(begin_token);
617 621
618 for (;;) { 622 for (;;) {
619 if (LookAhead(Token::RIGHT_BRACE)) { 623 if (LookAhead(Token::RIGHT_BRACE)) {
620 block->set_end(make_scoped_ptr(new EndNode(Consume()))); 624 block->set_end(base::WrapUnique(new EndNode(Consume())));
621 break; 625 break;
622 } 626 }
623 627
624 scoped_ptr<ParseNode> statement = ParseStatement(); 628 std::unique_ptr<ParseNode> statement = ParseStatement();
625 if (!statement) 629 if (!statement)
626 return scoped_ptr<BlockNode>(); 630 return std::unique_ptr<BlockNode>();
627 block->append_statement(std::move(statement)); 631 block->append_statement(std::move(statement));
628 } 632 }
629 return block; 633 return block;
630 } 634 }
631 635
632 scoped_ptr<ParseNode> Parser::ParseCondition() { 636 std::unique_ptr<ParseNode> Parser::ParseCondition() {
633 scoped_ptr<ConditionNode> condition(new ConditionNode); 637 std::unique_ptr<ConditionNode> condition(new ConditionNode);
634 condition->set_if_token(Consume(Token::IF, "Expected 'if'")); 638 condition->set_if_token(Consume(Token::IF, "Expected 'if'"));
635 Consume(Token::LEFT_PAREN, "Expected '(' after 'if'."); 639 Consume(Token::LEFT_PAREN, "Expected '(' after 'if'.");
636 condition->set_condition(ParseExpression()); 640 condition->set_condition(ParseExpression());
637 if (IsAssignment(condition->condition())) 641 if (IsAssignment(condition->condition()))
638 *err_ = Err(condition->condition(), "Assignment not allowed in 'if'."); 642 *err_ = Err(condition->condition(), "Assignment not allowed in 'if'.");
639 Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'."); 643 Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'.");
640 condition->set_if_true(ParseBlock()); 644 condition->set_if_true(ParseBlock());
641 if (Match(Token::ELSE)) { 645 if (Match(Token::ELSE)) {
642 if (LookAhead(Token::LEFT_BRACE)) { 646 if (LookAhead(Token::LEFT_BRACE)) {
643 condition->set_if_false(ParseBlock()); 647 condition->set_if_false(ParseBlock());
644 } else if (LookAhead(Token::IF)) { 648 } else if (LookAhead(Token::IF)) {
645 condition->set_if_false(ParseStatement()); 649 condition->set_if_false(ParseStatement());
646 } else { 650 } else {
647 *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'."); 651 *err_ = Err(cur_token(), "Expected '{' or 'if' after 'else'.");
648 return scoped_ptr<ParseNode>(); 652 return std::unique_ptr<ParseNode>();
649 } 653 }
650 } 654 }
651 if (has_error()) 655 if (has_error())
652 return scoped_ptr<ParseNode>(); 656 return std::unique_ptr<ParseNode>();
653 return std::move(condition); 657 return std::move(condition);
654 } 658 }
655 659
656 void Parser::TraverseOrder(const ParseNode* root, 660 void Parser::TraverseOrder(const ParseNode* root,
657 std::vector<const ParseNode*>* pre, 661 std::vector<const ParseNode*>* pre,
658 std::vector<const ParseNode*>* post) { 662 std::vector<const ParseNode*>* post) {
659 if (root) { 663 if (root) {
660 pre->push_back(root); 664 pre->push_back(root);
661 665
662 if (const AccessorNode* accessor = root->AsAccessor()) { 666 if (const AccessorNode* accessor = root->AsAccessor()) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 break; 761 break;
758 } 762 }
759 } 763 }
760 764
761 // Suffix comments were assigned in reverse, so if there were multiple on 765 // Suffix comments were assigned in reverse, so if there were multiple on
762 // the same node, they need to be reversed. 766 // the same node, they need to be reversed.
763 if ((*i)->comments() && !(*i)->comments()->suffix().empty()) 767 if ((*i)->comments() && !(*i)->comments()->suffix().empty())
764 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix(); 768 const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix();
765 } 769 }
766 } 770 }
OLDNEW
« no previous file with comments | « tools/gn/parser.h ('k') | tools/gn/parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698