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 3 // found in the LICENSE file. 4 5 #ifndef TOOLS_GN_PARSER_H_ 6 #define TOOLS_GN_PARSER_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/gtest_prod_util.h" 13 #include "base/memory/scoped_ptr.h" 14 #include "tools/gn/err.h" 15 #include "tools/gn/parse_tree.h" 16 17 class Parser; 18 typedef scoped_ptr<ParseNode> (Parser::*PrefixFunc)(Token token); 19 typedef scoped_ptr<ParseNode> (Parser::*InfixFunc)(scoped_ptr<ParseNode> left, 20 Token token); 21 22 struct ParserHelper { 23 PrefixFunc prefix; 24 InfixFunc infix; 25 int precedence; 26 }; 27 28 // Parses a series of tokens. The resulting AST will refer to the tokens passed 29 // to the input, so the tokens an the file data they refer to must outlive your 30 // use of the ParseNode. 31 class Parser { 32 public: 33 // Will return a null pointer and set the err on error. 34 static scoped_ptr<ParseNode> Parse(const std::vector<Token>& tokens, 35 Err* err); 36 37 // Alternative to parsing that assumes the input is an expression. 38 static scoped_ptr<ParseNode> ParseExpression(const std::vector<Token>& tokens, 39 Err* err); 40 41 scoped_ptr<ParseNode> ParseExpression(); 42 43 private: 44 // Vector must be valid for lifetime of call. 45 Parser(const std::vector<Token>& tokens, Err* err); 46 ~Parser(); 47 48 // Parses an expression with the given precedence or higher. 49 scoped_ptr<ParseNode> ParseExpression(int precedence); 50 51 // |PrefixFunc|s used in parsing expressions. 52 scoped_ptr<ParseNode> Literal(Token token); 53 scoped_ptr<ParseNode> Name(Token token); 54 scoped_ptr<ParseNode> Group(Token token); 55 scoped_ptr<ParseNode> Not(Token token); 56 scoped_ptr<ParseNode> List(Token token); 57 58 // |InfixFunc|s used in parsing expressions. 59 scoped_ptr<ParseNode> BinaryOperator(scoped_ptr<ParseNode> left, Token token); 60 scoped_ptr<ParseNode> IdentifierOrCall(scoped_ptr<ParseNode> left, 61 Token token); 62 scoped_ptr<ParseNode> Assignment(scoped_ptr<ParseNode> left, Token token); 63 scoped_ptr<ParseNode> Subscript(scoped_ptr<ParseNode> left, Token token); 64 65 // Helper to parse a comma separated list, optionally allowing trailing 66 // commas (allowed in [] lists, not in function calls). 67 scoped_ptr<ListNode> ParseList(Token::Type stop_before, 68 bool allow_trailing_comma); 69 70 scoped_ptr<ParseNode> ParseFile(); 71 scoped_ptr<ParseNode> ParseStatement(); 72 scoped_ptr<BlockNode> ParseBlock(); 73 scoped_ptr<ParseNode> ParseCondition(); 74 75 bool IsAssignment(const ParseNode* node) const; 76 bool IsStatementBreak(Token::Type token_type) const; 77 78 bool LookAhead(Token::Type type); 79 bool Match(Token::Type type); 80 Token Consume(Token::Type type, const char* error_message); 81 Token Consume(Token::Type* types, 82 size_t num_types, 83 const char* error_message); 84 Token Consume(); 85 cur_token()86 const Token& cur_token() const { return tokens_[cur_]; } 87 done()88 bool done() const { return at_end() || has_error(); } at_end()89 bool at_end() const { return cur_ >= tokens_.size(); } has_error()90 bool has_error() const { return err_->has_error(); } 91 92 const std::vector<Token>& tokens_; 93 94 static ParserHelper expressions_[Token::NUM_TYPES]; 95 96 Err* err_; 97 98 // Current index into the tokens. 99 size_t cur_; 100 101 FRIEND_TEST_ALL_PREFIXES(Parser, BinaryOp); 102 FRIEND_TEST_ALL_PREFIXES(Parser, Block); 103 FRIEND_TEST_ALL_PREFIXES(Parser, Condition); 104 FRIEND_TEST_ALL_PREFIXES(Parser, Expression); 105 FRIEND_TEST_ALL_PREFIXES(Parser, FunctionCall); 106 FRIEND_TEST_ALL_PREFIXES(Parser, List); 107 FRIEND_TEST_ALL_PREFIXES(Parser, ParenExpression); 108 FRIEND_TEST_ALL_PREFIXES(Parser, UnaryOp); 109 110 DISALLOW_COPY_AND_ASSIGN(Parser); 111 }; 112 113 #endif // TOOLS_GN_PARSER_H_ 114