// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef TOOLS_GN_PARSER_H_ #define TOOLS_GN_PARSER_H_ #include #include #include "base/basictypes.h" #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "tools/gn/err.h" #include "tools/gn/parse_tree.h" class Parser; typedef scoped_ptr (Parser::*PrefixFunc)(Token token); typedef scoped_ptr (Parser::*InfixFunc)(scoped_ptr left, Token token); struct ParserHelper { PrefixFunc prefix; InfixFunc infix; int precedence; }; // Parses a series of tokens. The resulting AST will refer to the tokens passed // to the input, so the tokens an the file data they refer to must outlive your // use of the ParseNode. class Parser { public: // Will return a null pointer and set the err on error. static scoped_ptr Parse(const std::vector& tokens, Err* err); // Alternative to parsing that assumes the input is an expression. static scoped_ptr ParseExpression(const std::vector& tokens, Err* err); scoped_ptr ParseExpression(); private: // Vector must be valid for lifetime of call. Parser(const std::vector& tokens, Err* err); ~Parser(); // Parses an expression with the given precedence or higher. scoped_ptr ParseExpression(int precedence); // |PrefixFunc|s used in parsing expressions. scoped_ptr Literal(Token token); scoped_ptr Name(Token token); scoped_ptr Group(Token token); scoped_ptr Not(Token token); scoped_ptr List(Token token); // |InfixFunc|s used in parsing expressions. scoped_ptr BinaryOperator(scoped_ptr left, Token token); scoped_ptr IdentifierOrCall(scoped_ptr left, Token token); scoped_ptr Assignment(scoped_ptr left, Token token); scoped_ptr Subscript(scoped_ptr left, Token token); // Helper to parse a comma separated list, optionally allowing trailing // commas (allowed in [] lists, not in function calls). scoped_ptr ParseList(Token::Type stop_before, bool allow_trailing_comma); scoped_ptr ParseFile(); scoped_ptr ParseStatement(); scoped_ptr ParseBlock(); scoped_ptr ParseCondition(); bool IsAssignment(const ParseNode* node) const; bool IsStatementBreak(Token::Type token_type) const; bool LookAhead(Token::Type type); bool Match(Token::Type type); Token Consume(Token::Type type, const char* error_message); Token Consume(Token::Type* types, size_t num_types, const char* error_message); Token Consume(); const Token& cur_token() const { return tokens_[cur_]; } bool done() const { return at_end() || has_error(); } bool at_end() const { return cur_ >= tokens_.size(); } bool has_error() const { return err_->has_error(); } const std::vector& tokens_; static ParserHelper expressions_[Token::NUM_TYPES]; Err* err_; // Current index into the tokens. size_t cur_; FRIEND_TEST_ALL_PREFIXES(Parser, BinaryOp); FRIEND_TEST_ALL_PREFIXES(Parser, Block); FRIEND_TEST_ALL_PREFIXES(Parser, Condition); FRIEND_TEST_ALL_PREFIXES(Parser, Expression); FRIEND_TEST_ALL_PREFIXES(Parser, FunctionCall); FRIEND_TEST_ALL_PREFIXES(Parser, List); FRIEND_TEST_ALL_PREFIXES(Parser, ParenExpression); FRIEND_TEST_ALL_PREFIXES(Parser, UnaryOp); DISALLOW_COPY_AND_ASSIGN(Parser); }; #endif // TOOLS_GN_PARSER_H_