1d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// found in the LICENSE file.
4d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
5d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/parser.h"
6d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
7d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "base/logging.h"
8d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/functions.h"
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/operators.h"
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch#include "tools/gn/token.h"
11d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// grammar:
133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// file       := (statement)*
153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// statement  := block | if | assignment
163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// block      := '{' statement* '}'
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// if         := 'if' '(' expr ')' statement [ else ]
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// else       := 'else' (if | statement)*
193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// assignment := ident {'=' | '+=' | '-='} expr
203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)enum Precedence {
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PRECEDENCE_ASSIGNMENT = 1,  // Lowest precedence.
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_OR = 2,
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_AND = 3,
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_EQUALITY = 4,
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_RELATION = 5,
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_SUM = 6,
283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_PREFIX = 7,
293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PRECEDENCE_CALL = 8,
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PRECEDENCE_DOT = 9,         // Highest precedence.
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// The top-level for blocks/ifs is recursive descent, the expression parser is
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// a Pratt parser. The basic idea there is to have the precedences (and
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// associativities) encoded relative to each other and only parse up until you
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// hit something of that precedence. There's a dispatch table in expressions_
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// at the top of parser.cc that describes how each token dispatches if it's
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// seen as either a prefix or infix operator, and if it's infix, what its
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// precedence is.
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Refs:
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - http://javascript.crockford.com/tdop/tdop.html
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Indexed by Token::Type.
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ParserHelper Parser::expressions_[] = {
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // INVALID
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Literal, NULL, -1},                                 // INTEGER
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Literal, NULL, -1},                                 // STRING
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Literal, NULL, -1},                                 // TRUE_TOKEN
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Literal, NULL, -1},                                 // FALSE_TOKEN
523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::Assignment, PRECEDENCE_ASSIGNMENT},           // EQUAL
533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_SUM},              // PLUS
543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_SUM},              // MINUS
553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::Assignment, PRECEDENCE_ASSIGNMENT},           // PLUS_EQUALS
563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::Assignment, PRECEDENCE_ASSIGNMENT},           // MINUS_EQUALS
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_EQUALITY},         // EQUAL_EQUAL
583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_EQUALITY},         // NOT_EQUAL
593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_RELATION},         // LESS_EQUAL
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_RELATION},         // GREATER_EQUAL
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_RELATION},         // LESS_THAN
623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_RELATION},         // GREATER_THAN
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_AND},              // BOOLEAN_AND
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, &Parser::BinaryOperator, PRECEDENCE_OR},               // BOOLEAN_OR
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Not, NULL, -1},                                     // BANG
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  {NULL, &Parser::DotOperator, PRECEDENCE_DOT},                 // DOT
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Group, NULL, -1},                                   // LEFT_PAREN
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // RIGHT_PAREN
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::List, &Parser::Subscript, PRECEDENCE_CALL},         // LEFT_BRACKET
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // RIGHT_BRACKET
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // LEFT_BRACE
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // RIGHT_BRACE
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // IF
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // ELSE
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {&Parser::Name, &Parser::IdentifierOrCall, PRECEDENCE_CALL},  // IDENTIFIER
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  {NULL, NULL, -1},                                             // COMMA
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {NULL, NULL, -1},                   // UNCLASSIFIED_COMMENT
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {NULL, NULL, -1},                   // LINE_COMMENT
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {NULL, NULL, -1},                   // SUFFIX_COMMENT
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  {&Parser::BlockComment, NULL, -1},  // BLOCK_COMMENT
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
83d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochParser::Parser(const std::vector<Token>& tokens, Err* err)
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : err_(err), cur_(0) {
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (std::vector<Token>::const_iterator i(tokens.begin()); i != tokens.end();
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++i) {
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    switch(i->type()) {
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      case Token::LINE_COMMENT:
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        line_comment_tokens_.push_back(*i);
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      case Token::SUFFIX_COMMENT:
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        suffix_comment_tokens_.push_back(*i);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      default:
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // Note that BLOCK_COMMENTs (top-level standalone comments) are passed
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        // through the real parser.
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        tokens_.push_back(*i);
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
101d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
102d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
103d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochParser::~Parser() {
104d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
105d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
106d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static
107d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochscoped_ptr<ParseNode> Parser::Parse(const std::vector<Token>& tokens,
108d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                    Err* err) {
109d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Parser p(tokens, err);
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return p.ParseFile().PassAs<ParseNode>();
111d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
112d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
113d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch// static
114d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochscoped_ptr<ParseNode> Parser::ParseExpression(const std::vector<Token>& tokens,
115d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch                                              Err* err) {
116d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  Parser p(tokens, err);
117d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return p.ParseExpression().Pass();
118d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
119d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Parser::IsAssignment(const ParseNode* node) const {
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return node && node->AsBinaryOp() &&
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         (node->AsBinaryOp()->op().type() == Token::EQUAL ||
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          node->AsBinaryOp()->op().type() == Token::PLUS_EQUALS ||
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          node->AsBinaryOp()->op().type() == Token::MINUS_EQUALS);
125d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
126d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Parser::IsStatementBreak(Token::Type token_type) const {
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  switch (token_type) {
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case Token::IDENTIFIER:
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case Token::LEFT_BRACE:
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case Token::RIGHT_BRACE:
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case Token::IF:
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case Token::ELSE:
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return true;
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    default:
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return false;
137d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
138d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
139d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Parser::LookAhead(Token::Type type) {
1413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (at_end())
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return cur_token().type() == type;
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
145d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool Parser::Match(Token::Type type) {
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!LookAhead(type))
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Consume();
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return true;
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
152d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Token Parser::Consume(Token::Type type, const char* error_message) {
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Token::Type types[1] = { type };
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return Consume(types, 1, error_message);
156d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
157d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Token Parser::Consume(Token::Type* types,
1593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      size_t num_types,
1603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      const char* error_message) {
1613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (has_error()) {
1623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Don't overwrite current error, but make progress through tokens so that
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // a loop that's expecting a particular token will still terminate.
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    cur_++;
1653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return Token(Location(), Token::INVALID, base::StringPiece());
166d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
167d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (at_end()) {
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const char kEOFMsg[] = "I hit EOF instead.";
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (tokens_.empty())
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *err_ = Err(Location(), error_message, kEOFMsg);
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    else
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *err_ = Err(tokens_[tokens_.size() - 1], error_message, kEOFMsg);
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return Token(Location(), Token::INVALID, base::StringPiece());
174d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
175d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < num_types; ++i) {
1773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (cur_token().type() == types[i])
1783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return tokens_[cur_++];
179d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  *err_ = Err(cur_token(), error_message);
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return Token(Location(), Token::INVALID, base::StringPiece());
1823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
183d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)Token Parser::Consume() {
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return tokens_[cur_++];
186d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
187d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
188d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochscoped_ptr<ParseNode> Parser::ParseExpression() {
1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return ParseExpression(0);
1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
191d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::ParseExpression(int precedence) {
193d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (at_end())
1943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
195d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Token token = Consume();
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  PrefixFunc prefix = expressions_[token.type()].prefix;
198d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (prefix == NULL) {
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err_ = Err(token,
2013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                std::string("Unexpected token '") + token.value().as_string() +
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    std::string("'"));
2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ParseNode> left = (this->*prefix)(token);
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (has_error())
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return left.Pass();
2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  while (!at_end() && !IsStatementBreak(cur_token().type()) &&
2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)         precedence <= expressions_[cur_token().type()].precedence) {
2123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    token = Consume();
2133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    InfixFunc infix = expressions_[token.type()].infix;
2143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (infix == NULL) {
2153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *err_ = Err(token,
2163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                  std::string("Unexpected token '") +
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      token.value().as_string() + std::string("'"));
218d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return scoped_ptr<ParseNode>();
219d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    }
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    left = (this->*infix)(left.Pass(), token);
221d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (has_error())
222d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return scoped_ptr<ParseNode>();
223d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
224d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return left.Pass();
226d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::Literal(Token token) {
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scoped_ptr<ParseNode>(new LiteralNode(token)).Pass();
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
231d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::Name(Token token) {
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IdentifierOrCall(scoped_ptr<ParseNode>(), token).Pass();
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
235d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<ParseNode> Parser::BlockComment(Token token) {
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<BlockCommentNode> comment(new BlockCommentNode());
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  comment->set_comment(token);
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return comment.PassAs<ParseNode>();
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::Group(Token token) {
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ParseNode> expr = ParseExpression();
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (has_error())
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Consume(Token::RIGHT_PAREN, "Expected ')'");
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return expr.Pass();
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
249d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::Not(Token token) {
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ParseNode> expr = ParseExpression(PRECEDENCE_PREFIX + 1);
2523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (has_error())
2533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<UnaryOpNode> unary_op(new UnaryOpNode);
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  unary_op->set_op(token);
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  unary_op->set_operand(expr.Pass());
2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return unary_op.PassAs<ParseNode>();
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
259d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::List(Token node) {
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<ParseNode> list(ParseList(node, Token::RIGHT_BRACKET, true));
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!has_error() && !at_end())
2633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    Consume(Token::RIGHT_BRACKET, "Expected ']'");
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return list.Pass();
2653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
266d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::BinaryOperator(scoped_ptr<ParseNode> left,
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                             Token token) {
2693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ParseNode> right =
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ParseExpression(expressions_[token.type()].precedence + 1);
2713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!right) {
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err_ =
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        Err(token,
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            "Expected right hand side for '" + token.value().as_string() + "'");
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
276d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<BinaryOpNode> binary_op(new BinaryOpNode);
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  binary_op->set_op(token);
2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  binary_op->set_left(left.Pass());
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  binary_op->set_right(right.Pass());
2813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return binary_op.PassAs<ParseNode>();
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
283d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::IdentifierOrCall(scoped_ptr<ParseNode> left,
2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                               Token token) {
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ListNode> list(new ListNode);
2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  list->set_begin_token(token);
2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  list->set_end_token(token);
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<BlockNode> block;
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool has_arg = false;
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (LookAhead(Token::LEFT_PAREN)) {
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Token start_token = Consume();
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Parsing a function call.
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    has_arg = true;
2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (Match(Token::RIGHT_PAREN)) {
2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      // Nothing, just an empty call.
2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      list = ParseList(start_token, Token::RIGHT_PAREN, false);
2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (has_error())
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return scoped_ptr<ParseNode>();
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      Consume(Token::RIGHT_PAREN, "Expected ')' after call");
3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Optionally with a scope.
3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (LookAhead(Token::LEFT_BRACE)) {
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      block = ParseBlock();
3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (has_error())
3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return scoped_ptr<ParseNode>();
3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
309d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
310d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!left && !has_arg) {
3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Not a function call, just a standalone identifier.
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>(new IdentifierNode(token)).Pass();
314d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FunctionCallNode> func_call(new FunctionCallNode);
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  func_call->set_function(token);
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  func_call->set_args(list.Pass());
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (block)
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    func_call->set_block(block.Pass());
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return func_call.PassAs<ParseNode>();
321d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
322d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::Assignment(scoped_ptr<ParseNode> left,
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                         Token token) {
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (left->AsIdentifier() == NULL) {
3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err_ = Err(left.get(), "Left-hand side of assignment must be identifier.");
3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
328d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ParseNode> value = ParseExpression(PRECEDENCE_ASSIGNMENT);
3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<BinaryOpNode> assign(new BinaryOpNode);
3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  assign->set_op(token);
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  assign->set_left(left.Pass());
3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  assign->set_right(value.Pass());
3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return assign.PassAs<ParseNode>();
3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
336d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::Subscript(scoped_ptr<ParseNode> left,
3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        Token token) {
3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO: Maybe support more complex expressions like a[0][0]. This would
3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // require work on the evaluator too.
3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (left->AsIdentifier() == NULL) {
342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *err_ = Err(left.get(), "May only subscript identifiers.",
343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "The thing on the left hand side of the [] must be an identifier\n"
344effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "and not an expression. If you need this, you'll have to assign the\n"
345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "value to a temporary before subscripting. Sorry.");
3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
347d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ParseNode> value = ParseExpression();
3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Consume(Token::RIGHT_BRACKET, "Expecting ']' after subscript.");
3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<AccessorNode> accessor(new AccessorNode);
3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  accessor->set_base(left->AsIdentifier()->value());
3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  accessor->set_index(value.Pass());
3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return accessor.PassAs<ParseNode>();
354d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
355d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochscoped_ptr<ParseNode> Parser::DotOperator(scoped_ptr<ParseNode> left,
357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                          Token token) {
358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (left->AsIdentifier() == NULL) {
359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *err_ = Err(left.get(), "May only use \".\" for identifiers.",
360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "The thing on the left hand side of the dot must be an identifier\n"
361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "and not an expression. If you need this, you'll have to assign the\n"
362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "value to a temporary first. Sorry.");
363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return scoped_ptr<ParseNode>();
364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<ParseNode> right = ParseExpression(PRECEDENCE_DOT);
367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!right || !right->AsIdentifier()) {
368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *err_ = Err(token, "Expected identifier for right-hand-side of \".\"",
369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        "Good: a.cookies\nBad: a.42\nLooks good but still bad: a.cookies()");
370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    return scoped_ptr<ParseNode>();
371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<AccessorNode> accessor(new AccessorNode);
374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  accessor->set_base(left->AsIdentifier()->value());
375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  accessor->set_member(scoped_ptr<IdentifierNode>(
376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      static_cast<IdentifierNode*>(right.release())));
377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return accessor.PassAs<ParseNode>();
378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Does not Consume the start or end token.
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<ListNode> Parser::ParseList(Token start_token,
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       Token::Type stop_before,
3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                       bool allow_trailing_comma) {
384d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  scoped_ptr<ListNode> list(new ListNode);
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  list->set_begin_token(start_token);
3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool just_got_comma = false;
3875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool first_time = true;
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  while (!LookAhead(stop_before)) {
3895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!first_time) {
3905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (!just_got_comma) {
3915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        // Require commas separate things in lists.
3925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        *err_ = Err(cur_token(), "Expected comma between items.");
3935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        return scoped_ptr<ListNode>();
3945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      }
3955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
3965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    first_time = false;
3975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Why _OR? We're parsing things that are higher precedence than the ,
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // that separates the items of the list. , should appear lower than
4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // boolean expressions (the lowest of which is OR), but above assignments.
4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    list->append_item(ParseExpression(PRECEDENCE_OR));
402d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    if (has_error())
403d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      return scoped_ptr<ListNode>();
4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (at_end()) {
4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *err_ =
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          Err(tokens_[tokens_.size() - 1], "Unexpected end of file in list.");
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return scoped_ptr<ListNode>();
408d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    }
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (list->contents().back()->AsBlockComment()) {
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // If there was a comment inside the list, we don't need a comma to the
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // next item, so pretend we got one, if we're expecting one.
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      just_got_comma = allow_trailing_comma;
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      just_got_comma = Match(Token::COMMA);
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (just_got_comma && !allow_trailing_comma) {
4183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err_ = Err(cur_token(), "Trailing comma");
4193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ListNode>();
420d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
4213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  list->set_end_token(cur_token());
422d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  return list.Pass();
423d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
424d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
4253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::ParseFile() {
4263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<BlockNode> file(new BlockNode(false));
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (;;) {
4283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (at_end())
4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    scoped_ptr<ParseNode> statement = ParseStatement();
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!statement)
4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    file->append_statement(statement.Pass());
4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!at_end() && !has_error())
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err_ = Err(cur_token(), "Unexpected here, should be newline.");
437d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  if (has_error())
438d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return scoped_ptr<ParseNode>();
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(scottmg): If this is measurably expensive, it could be done only
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // when necessary (when reformatting, or during tests). Comments are
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // separate from the parse tree at this point, so downstream code can remain
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ignorant of them.
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AssignComments(file.get());
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return file.PassAs<ParseNode>();
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
448d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::ParseStatement() {
4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (LookAhead(Token::LEFT_BRACE)) {
4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ParseBlock().PassAs<ParseNode>();
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else if (LookAhead(Token::IF)) {
4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ParseCondition();
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else if (LookAhead(Token::BLOCK_COMMENT)) {
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return BlockComment(Consume());
4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  } else {
4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // TODO(scottmg): Is this too strict? Just drop all the testing if we want
4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // to allow "pointless" expressions and return ParseExpression() directly.
4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    scoped_ptr<ParseNode> stmt = ParseExpression();
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (stmt) {
4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (stmt->AsFunctionCall() || IsAssignment(stmt.get()))
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        return stmt.Pass();
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!has_error()) {
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      Token token = at_end() ? tokens_[tokens_.size() - 1] : cur_token();
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      *err_ = Err(token, "Expecting assignment or function call.");
4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
468d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return scoped_ptr<ParseNode>();
469d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
470d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
471d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<BlockNode> Parser::ParseBlock() {
4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Token begin_token =
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      Consume(Token::LEFT_BRACE, "Expected '{' to start a block.");
4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (has_error())
4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<BlockNode>();
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<BlockNode> block(new BlockNode(true));
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  block->set_begin_token(begin_token);
479d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (;;) {
4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (LookAhead(Token::RIGHT_BRACE)) {
4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      block->set_end_token(Consume());
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
485d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    scoped_ptr<ParseNode> statement = ParseStatement();
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!statement)
4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return scoped_ptr<BlockNode>();
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    block->append_statement(statement.Pass());
490d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  }
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return block.Pass();
492d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
493d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ParseNode> Parser::ParseCondition() {
4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ConditionNode> condition(new ConditionNode);
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  condition->set_if_token(Consume(Token::IF, "Expected 'if'"));
4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Consume(Token::LEFT_PAREN, "Expected '(' after 'if'.");
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  condition->set_condition(ParseExpression());
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsAssignment(condition->condition()))
5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    *err_ = Err(condition->condition(), "Assignment not allowed in 'if'.");
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  Consume(Token::RIGHT_PAREN, "Expected ')' after condition of 'if'.");
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  condition->set_if_true(ParseBlock().Pass());
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (Match(Token::ELSE))
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    condition->set_if_false(ParseStatement().Pass());
5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (has_error())
5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<ParseNode>();
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return condition.PassAs<ParseNode>();
508d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch}
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Parser::TraverseOrder(const ParseNode* root,
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           std::vector<const ParseNode*>* pre,
5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           std::vector<const ParseNode*>* post) {
5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (root) {
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pre->push_back(root);
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (const AccessorNode* accessor = root->AsAccessor()) {
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(accessor->index(), pre, post);
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(accessor->member(), pre, post);
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (const BinaryOpNode* binop = root->AsBinaryOp()) {
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(binop->left(), pre, post);
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(binop->right(), pre, post);
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (const BlockNode* block = root->AsBlock()) {
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::vector<ParseNode*>& statements = block->statements();
5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      for (std::vector<ParseNode*>::const_iterator i(statements.begin());
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          i != statements.end();
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ++i) {
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TraverseOrder(*i, pre, post);
5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (const ConditionNode* condition = root->AsConditionNode()) {
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(condition->condition(), pre, post);
5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(condition->if_true(), pre, post);
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(condition->if_false(), pre, post);
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (const FunctionCallNode* func_call = root->AsFunctionCall()) {
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(func_call->args(), pre, post);
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(func_call->block(), pre, post);
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (root->AsIdentifier()) {
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Nothing.
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (const ListNode* list = root->AsList()) {
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::vector<const ParseNode*>& contents = list->contents();
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      for (std::vector<const ParseNode*>::const_iterator i(contents.begin());
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          i != contents.end();
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ++i) {
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        TraverseOrder(*i, pre, post);
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (root->AsLiteral()) {
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Nothing.
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (const UnaryOpNode* unaryop = root->AsUnaryOp()) {
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      TraverseOrder(unaryop->operand(), pre, post);
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else if (root->AsBlockComment()) {
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Nothing.
5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    } else {
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CHECK(false) << "Unhandled case in TraverseOrder.";
5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
5541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    post->push_back(root);
5561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid Parser::AssignComments(ParseNode* file) {
5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Start by generating a pre- and post- order traversal of the tree so we
5611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // can determine what's before and after comments.
5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<const ParseNode*> pre;
5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<const ParseNode*> post;
5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TraverseOrder(file, &pre, &post);
5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Assign line comments to syntax immediately following.
5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int cur_comment = 0;
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (std::vector<const ParseNode*>::const_iterator i = pre.begin();
5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       i != pre.end();
5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++i) {
5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Location& start = (*i)->GetRange().begin();
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    while (cur_comment < static_cast<int>(line_comment_tokens_.size())) {
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (start.byte() >= line_comment_tokens_[cur_comment].location().byte()) {
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        const_cast<ParseNode*>(*i)->comments_mutable()->append_before(
5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            line_comment_tokens_[cur_comment]);
5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        ++cur_comment;
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      } else {
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Remaining line comments go at end of file.
5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (; cur_comment < static_cast<int>(line_comment_tokens_.size());
5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++cur_comment)
5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    file->comments_mutable()->append_after(line_comment_tokens_[cur_comment]);
5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Assign suffix to syntax immediately before.
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  cur_comment = static_cast<int>(suffix_comment_tokens_.size() - 1);
5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (std::vector<const ParseNode*>::const_reverse_iterator i = post.rbegin();
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       i != post.rend();
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++i) {
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Don't assign suffix comments to the function call or list, but instead
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // to the last thing inside.
5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if ((*i)->AsFunctionCall() || (*i)->AsList())
5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      continue;
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Location& start = (*i)->GetRange().begin();
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Location& end = (*i)->GetRange().end();
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Don't assign suffix comments to something that starts on an earlier
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // line, so that in:
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // sources = [ "a",
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //     "b" ] # comment
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // it's attached to "b", not sources = [ ... ].
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (start.line_number() != end.line_number())
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      continue;
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    while (cur_comment >= 0) {
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (end.byte() <= suffix_comment_tokens_[cur_comment].location().byte()) {
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        const_cast<ParseNode*>(*i)->comments_mutable()->append_suffix(
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            suffix_comment_tokens_[cur_comment]);
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        --cur_comment;
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      } else {
6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        break;
6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Suffix comments were assigned in reverse, so if there were multiple on
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // the same node, they need to be reversed.
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const_cast<ParseNode*>(*i)->comments_mutable()->ReverseSuffix();
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
626