• 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_PARSE_TREE_H_
6 #define TOOLS_GN_PARSE_TREE_H_
7 
8 #include <vector>
9 
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "tools/gn/err.h"
14 #include "tools/gn/token.h"
15 #include "tools/gn/value.h"
16 
17 class AccessorNode;
18 class BinaryOpNode;
19 class BlockNode;
20 class ConditionNode;
21 class FunctionCallNode;
22 class IdentifierNode;
23 class ListNode;
24 class LiteralNode;
25 class Scope;
26 class UnaryOpNode;
27 
28 // ParseNode -------------------------------------------------------------------
29 
30 // A node in the AST.
31 class ParseNode {
32  public:
33   ParseNode();
34   virtual ~ParseNode();
35 
36   virtual const AccessorNode* AsAccessor() const;
37   virtual const BinaryOpNode* AsBinaryOp() const;
38   virtual const BlockNode* AsBlock() const;
39   virtual const ConditionNode* AsConditionNode() const;
40   virtual const FunctionCallNode* AsFunctionCall() const;
41   virtual const IdentifierNode* AsIdentifier() const;
42   virtual const ListNode* AsList() const;
43   virtual const LiteralNode* AsLiteral() const;
44   virtual const UnaryOpNode* AsUnaryOp() const;
45 
46   virtual Value Execute(Scope* scope, Err* err) const = 0;
47 
48   virtual LocationRange GetRange() const = 0;
49 
50   // Returns an error with the given messages and the range set to something
51   // that indicates this node.
52   virtual Err MakeErrorDescribing(
53       const std::string& msg,
54       const std::string& help = std::string()) const = 0;
55 
56   // Prints a representation of this node to the given string, indenting
57   // by the given number of spaces.
58   virtual void Print(std::ostream& out, int indent) const = 0;
59 
60  private:
61   DISALLOW_COPY_AND_ASSIGN(ParseNode);
62 };
63 
64 // AccessorNode ----------------------------------------------------------------
65 
66 // Access an array element.
67 //
68 // If we need to add support for member variables like "variable.len" I was
69 // thinking this would also handle that case.
70 class AccessorNode : public ParseNode {
71  public:
72   AccessorNode();
73   virtual ~AccessorNode();
74 
75   virtual const AccessorNode* AsAccessor() const OVERRIDE;
76   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
77   virtual LocationRange GetRange() const OVERRIDE;
78   virtual Err MakeErrorDescribing(
79       const std::string& msg,
80       const std::string& help = std::string()) const OVERRIDE;
81   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
82 
83   // Base is the thing on the left of the [], currently always required to be
84   // an identifier token.
base()85   const Token& base() const { return base_; }
set_base(const Token & b)86   void set_base(const Token& b) { base_ = b; }
87 
88   // Index is the expression inside the [].
index()89   const ParseNode* index() const { return index_.get(); }
set_index(scoped_ptr<ParseNode> i)90   void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); }
91 
92  private:
93   Token base_;
94   scoped_ptr<ParseNode> index_;
95 
96   DISALLOW_COPY_AND_ASSIGN(AccessorNode);
97 };
98 
99 // BinaryOpNode ----------------------------------------------------------------
100 
101 class BinaryOpNode : public ParseNode {
102  public:
103   BinaryOpNode();
104   virtual ~BinaryOpNode();
105 
106   virtual const BinaryOpNode* AsBinaryOp() const OVERRIDE;
107   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
108   virtual LocationRange GetRange() const OVERRIDE;
109   virtual Err MakeErrorDescribing(
110       const std::string& msg,
111       const std::string& help = std::string()) const OVERRIDE;
112   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
113 
op()114   const Token& op() const { return op_; }
set_op(const Token & t)115   void set_op(const Token& t) { op_ = t; }
116 
left()117   const ParseNode* left() const { return left_.get(); }
set_left(scoped_ptr<ParseNode> left)118   void set_left(scoped_ptr<ParseNode> left) {
119     left_ = left.Pass();
120   }
121 
right()122   const ParseNode* right() const { return right_.get(); }
set_right(scoped_ptr<ParseNode> right)123   void set_right(scoped_ptr<ParseNode> right) {
124     right_ = right.Pass();
125   }
126 
127  private:
128   scoped_ptr<ParseNode> left_;
129   Token op_;
130   scoped_ptr<ParseNode> right_;
131 
132   DISALLOW_COPY_AND_ASSIGN(BinaryOpNode);
133 };
134 
135 // BlockNode -------------------------------------------------------------------
136 
137 class BlockNode : public ParseNode {
138  public:
139   // Set has_scope if this block introduces a nested scope.
140   explicit BlockNode(bool has_scope);
141   virtual ~BlockNode();
142 
143   virtual const BlockNode* AsBlock() const OVERRIDE;
144   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
145   virtual LocationRange GetRange() const OVERRIDE;
146   virtual Err MakeErrorDescribing(
147       const std::string& msg,
148       const std::string& help = std::string()) const OVERRIDE;
149   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
150 
set_begin_token(const Token & t)151   void set_begin_token(const Token& t) { begin_token_ = t; }
set_end_token(const Token & t)152   void set_end_token(const Token& t) { end_token_ = t; }
153 
statements()154   const std::vector<ParseNode*>& statements() const { return statements_; }
append_statement(scoped_ptr<ParseNode> s)155   void append_statement(scoped_ptr<ParseNode> s) {
156     statements_.push_back(s.release());
157   }
158 
159   // Doesn't create a nested scope.
160   Value ExecuteBlockInScope(Scope* our_scope, Err* err) const;
161 
162  private:
163   bool has_scope_;
164 
165   // Tokens corresponding to { and }, if any (may be NULL).
166   Token begin_token_;
167   Token end_token_;
168 
169   // Owning pointers, use unique_ptr when we can use C++11.
170   std::vector<ParseNode*> statements_;
171 
172   DISALLOW_COPY_AND_ASSIGN(BlockNode);
173 };
174 
175 // ConditionNode ---------------------------------------------------------------
176 
177 class ConditionNode : public ParseNode {
178  public:
179   ConditionNode();
180   virtual ~ConditionNode();
181 
182   virtual const ConditionNode* AsConditionNode() const OVERRIDE;
183   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
184   virtual LocationRange GetRange() const OVERRIDE;
185   virtual Err MakeErrorDescribing(
186       const std::string& msg,
187       const std::string& help = std::string()) const OVERRIDE;
188   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
189 
set_if_token(const Token & token)190   void set_if_token(const Token& token) { if_token_ = token; }
191 
condition()192   const ParseNode* condition() const { return condition_.get(); }
set_condition(scoped_ptr<ParseNode> c)193   void set_condition(scoped_ptr<ParseNode> c) {
194     condition_ = c.Pass();
195   }
196 
if_true()197   const BlockNode* if_true() const { return if_true_.get(); }
set_if_true(scoped_ptr<BlockNode> t)198   void set_if_true(scoped_ptr<BlockNode> t) {
199     if_true_ = t.Pass();
200   }
201 
202   // This is either empty, a block (for the else clause), or another
203   // condition.
if_false()204   const ParseNode* if_false() const { return if_false_.get(); }
set_if_false(scoped_ptr<ParseNode> f)205   void set_if_false(scoped_ptr<ParseNode> f) {
206     if_false_ = f.Pass();
207   }
208 
209  private:
210   // Token corresponding to the "if" string.
211   Token if_token_;
212 
213   scoped_ptr<ParseNode> condition_;  // Always non-null.
214   scoped_ptr<BlockNode> if_true_;  // Always non-null.
215   scoped_ptr<ParseNode> if_false_;  // May be null.
216 
217   DISALLOW_COPY_AND_ASSIGN(ConditionNode);
218 };
219 
220 // FunctionCallNode ------------------------------------------------------------
221 
222 class FunctionCallNode : public ParseNode {
223  public:
224   FunctionCallNode();
225   virtual ~FunctionCallNode();
226 
227   virtual const FunctionCallNode* AsFunctionCall() const OVERRIDE;
228   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
229   virtual LocationRange GetRange() const OVERRIDE;
230   virtual Err MakeErrorDescribing(
231       const std::string& msg,
232       const std::string& help = std::string()) const OVERRIDE;
233   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
234 
function()235   const Token& function() const { return function_; }
set_function(Token t)236   void set_function(Token t) { function_ = t; }
237 
args()238   const ListNode* args() const { return args_.get(); }
set_args(scoped_ptr<ListNode> a)239   void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); }
240 
block()241   const BlockNode* block() const { return block_.get(); }
set_block(scoped_ptr<BlockNode> b)242   void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); }
243 
244  private:
245   Token function_;
246   scoped_ptr<ListNode> args_;
247   scoped_ptr<BlockNode> block_;  // May be null.
248 
249   DISALLOW_COPY_AND_ASSIGN(FunctionCallNode);
250 };
251 
252 // IdentifierNode --------------------------------------------------------------
253 
254 class IdentifierNode : public ParseNode {
255  public:
256   IdentifierNode();
257   IdentifierNode(const Token& token);
258   virtual ~IdentifierNode();
259 
260   virtual const IdentifierNode* AsIdentifier() const OVERRIDE;
261   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
262   virtual LocationRange GetRange() const OVERRIDE;
263   virtual Err MakeErrorDescribing(
264       const std::string& msg,
265       const std::string& help = std::string()) const OVERRIDE;
266   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
267 
value()268   const Token& value() const { return value_; }
set_value(const Token & t)269   void set_value(const Token& t) { value_ = t; }
270 
271  private:
272   Token value_;
273 
274   DISALLOW_COPY_AND_ASSIGN(IdentifierNode);
275 };
276 
277 // ListNode --------------------------------------------------------------------
278 
279 class ListNode : public ParseNode {
280  public:
281   ListNode();
282   virtual ~ListNode();
283 
284   virtual const ListNode* AsList() const OVERRIDE;
285   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
286   virtual LocationRange GetRange() const OVERRIDE;
287   virtual Err MakeErrorDescribing(
288       const std::string& msg,
289       const std::string& help = std::string()) const OVERRIDE;
290   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
291 
set_begin_token(const Token & t)292   void set_begin_token(const Token& t) { begin_token_ = t; }
set_end_token(const Token & t)293   void set_end_token(const Token& t) { end_token_ = t; }
294 
append_item(scoped_ptr<ParseNode> s)295   void append_item(scoped_ptr<ParseNode> s) {
296     contents_.push_back(s.release());
297   }
contents()298   const std::vector<const ParseNode*>& contents() const { return contents_; }
299 
300  private:
301   // Tokens corresponding to the [ and ].
302   Token begin_token_;
303   Token end_token_;
304 
305   // Owning pointers, use unique_ptr when we can use C++11.
306   std::vector<const ParseNode*> contents_;
307 
308   DISALLOW_COPY_AND_ASSIGN(ListNode);
309 };
310 
311 // LiteralNode -----------------------------------------------------------------
312 
313 class LiteralNode : public ParseNode {
314  public:
315   LiteralNode();
316   LiteralNode(const Token& token);
317   virtual ~LiteralNode();
318 
319   virtual const LiteralNode* AsLiteral() const OVERRIDE;
320   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
321   virtual LocationRange GetRange() const OVERRIDE;
322   virtual Err MakeErrorDescribing(
323       const std::string& msg,
324       const std::string& help = std::string()) const OVERRIDE;
325   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
326 
value()327   const Token& value() const { return value_; }
set_value(const Token & t)328   void set_value(const Token& t) { value_ = t; }
329 
330  private:
331   Token value_;
332 
333   DISALLOW_COPY_AND_ASSIGN(LiteralNode);
334 };
335 
336 // UnaryOpNode -----------------------------------------------------------------
337 
338 class UnaryOpNode : public ParseNode {
339  public:
340   UnaryOpNode();
341   virtual ~UnaryOpNode();
342 
343   virtual const UnaryOpNode* AsUnaryOp() const OVERRIDE;
344   virtual Value Execute(Scope* scope, Err* err) const OVERRIDE;
345   virtual LocationRange GetRange() const OVERRIDE;
346   virtual Err MakeErrorDescribing(
347       const std::string& msg,
348       const std::string& help = std::string()) const OVERRIDE;
349   virtual void Print(std::ostream& out, int indent) const OVERRIDE;
350 
op()351   const Token& op() const { return op_; }
set_op(const Token & t)352   void set_op(const Token& t) { op_ = t; }
353 
operand()354   const ParseNode* operand() const { return operand_.get(); }
set_operand(scoped_ptr<ParseNode> operand)355   void set_operand(scoped_ptr<ParseNode> operand) {
356     operand_ = operand.Pass();
357   }
358 
359  private:
360   Token op_;
361   scoped_ptr<ParseNode> operand_;
362 
363   DISALLOW_COPY_AND_ASSIGN(UnaryOpNode);
364 };
365 
366 #endif  // TOOLS_GN_PARSE_TREE_H_
367