• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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