parse_tree.h revision effb81e5f8246d0db0270817048dc992db66e9fb
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 17class AccessorNode; 18class BinaryOpNode; 19class BlockNode; 20class ConditionNode; 21class FunctionCallNode; 22class IdentifierNode; 23class ListNode; 24class LiteralNode; 25class Scope; 26class UnaryOpNode; 27 28// ParseNode ------------------------------------------------------------------- 29 30// A node in the AST. 31class 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 or scope element. 67// 68// Currently, such values are only read-only. In that you can do: 69// a = obj1.a 70// b = obj2[0] 71// But not 72// obj1.a = 5 73// obj2[0] = 6 74// 75// In the current design where the dot operator is used only for templates, we 76// explicitly don't want to allow you to do "invoker.foo = 5", so if we added 77// support for accessors to be lvalues, we would also need to add some concept 78// of a constant scope. Supporting this would also add a lot of complications 79// to the operator= implementation, since some accessors might return values 80// in the const root scope that shouldn't be modified. Without a strong 81// use-case for this, it seems simpler to just disallow it. 82// 83// Additionally, the left-hand-side of the accessor must currently be an 84// identifier. So you can't do things like: 85// function_call()[1] 86// a = b.c.d 87// These are easier to implement if we needed them but given the very limited 88// use cases for this, it hasn't seemed worth the bother. 89class AccessorNode : public ParseNode { 90 public: 91 AccessorNode(); 92 virtual ~AccessorNode(); 93 94 virtual const AccessorNode* AsAccessor() const OVERRIDE; 95 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 96 virtual LocationRange GetRange() const OVERRIDE; 97 virtual Err MakeErrorDescribing( 98 const std::string& msg, 99 const std::string& help = std::string()) const OVERRIDE; 100 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 101 102 // Base is the thing on the left of the [] or dot, currently always required 103 // to be an identifier token. 104 const Token& base() const { return base_; } 105 void set_base(const Token& b) { base_ = b; } 106 107 // Index is the expression inside the []. Will be null if member is set. 108 const ParseNode* index() const { return index_.get(); } 109 void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); } 110 111 // The member is the identifier on the right hand side of the dot. Will be 112 // null if the index is set. 113 const IdentifierNode* member() const { return member_.get(); } 114 void set_member(scoped_ptr<IdentifierNode> i) { member_ = i.Pass(); } 115 116 private: 117 Value ExecuteArrayAccess(Scope* scope, Err* err) const; 118 Value ExecuteScopeAccess(Scope* scope, Err* err) const; 119 120 Token base_; 121 122 // Either index or member will be set according to what type of access this 123 // is. 124 scoped_ptr<ParseNode> index_; 125 scoped_ptr<IdentifierNode> member_; 126 127 DISALLOW_COPY_AND_ASSIGN(AccessorNode); 128}; 129 130// BinaryOpNode ---------------------------------------------------------------- 131 132class BinaryOpNode : public ParseNode { 133 public: 134 BinaryOpNode(); 135 virtual ~BinaryOpNode(); 136 137 virtual const BinaryOpNode* AsBinaryOp() const OVERRIDE; 138 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 139 virtual LocationRange GetRange() const OVERRIDE; 140 virtual Err MakeErrorDescribing( 141 const std::string& msg, 142 const std::string& help = std::string()) const OVERRIDE; 143 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 144 145 const Token& op() const { return op_; } 146 void set_op(const Token& t) { op_ = t; } 147 148 const ParseNode* left() const { return left_.get(); } 149 void set_left(scoped_ptr<ParseNode> left) { 150 left_ = left.Pass(); 151 } 152 153 const ParseNode* right() const { return right_.get(); } 154 void set_right(scoped_ptr<ParseNode> right) { 155 right_ = right.Pass(); 156 } 157 158 private: 159 scoped_ptr<ParseNode> left_; 160 Token op_; 161 scoped_ptr<ParseNode> right_; 162 163 DISALLOW_COPY_AND_ASSIGN(BinaryOpNode); 164}; 165 166// BlockNode ------------------------------------------------------------------- 167 168class BlockNode : public ParseNode { 169 public: 170 // Set has_scope if this block introduces a nested scope. 171 explicit BlockNode(bool has_scope); 172 virtual ~BlockNode(); 173 174 virtual const BlockNode* AsBlock() const OVERRIDE; 175 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 176 virtual LocationRange GetRange() const OVERRIDE; 177 virtual Err MakeErrorDescribing( 178 const std::string& msg, 179 const std::string& help = std::string()) const OVERRIDE; 180 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 181 182 void set_begin_token(const Token& t) { begin_token_ = t; } 183 void set_end_token(const Token& t) { end_token_ = t; } 184 185 const std::vector<ParseNode*>& statements() const { return statements_; } 186 void append_statement(scoped_ptr<ParseNode> s) { 187 statements_.push_back(s.release()); 188 } 189 190 // Doesn't create a nested scope. 191 Value ExecuteBlockInScope(Scope* our_scope, Err* err) const; 192 193 private: 194 bool has_scope_; 195 196 // Tokens corresponding to { and }, if any (may be NULL). 197 Token begin_token_; 198 Token end_token_; 199 200 // Owning pointers, use unique_ptr when we can use C++11. 201 std::vector<ParseNode*> statements_; 202 203 DISALLOW_COPY_AND_ASSIGN(BlockNode); 204}; 205 206// ConditionNode --------------------------------------------------------------- 207 208class ConditionNode : public ParseNode { 209 public: 210 ConditionNode(); 211 virtual ~ConditionNode(); 212 213 virtual const ConditionNode* AsConditionNode() const OVERRIDE; 214 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 215 virtual LocationRange GetRange() const OVERRIDE; 216 virtual Err MakeErrorDescribing( 217 const std::string& msg, 218 const std::string& help = std::string()) const OVERRIDE; 219 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 220 221 void set_if_token(const Token& token) { if_token_ = token; } 222 223 const ParseNode* condition() const { return condition_.get(); } 224 void set_condition(scoped_ptr<ParseNode> c) { 225 condition_ = c.Pass(); 226 } 227 228 const BlockNode* if_true() const { return if_true_.get(); } 229 void set_if_true(scoped_ptr<BlockNode> t) { 230 if_true_ = t.Pass(); 231 } 232 233 // This is either empty, a block (for the else clause), or another 234 // condition. 235 const ParseNode* if_false() const { return if_false_.get(); } 236 void set_if_false(scoped_ptr<ParseNode> f) { 237 if_false_ = f.Pass(); 238 } 239 240 private: 241 // Token corresponding to the "if" string. 242 Token if_token_; 243 244 scoped_ptr<ParseNode> condition_; // Always non-null. 245 scoped_ptr<BlockNode> if_true_; // Always non-null. 246 scoped_ptr<ParseNode> if_false_; // May be null. 247 248 DISALLOW_COPY_AND_ASSIGN(ConditionNode); 249}; 250 251// FunctionCallNode ------------------------------------------------------------ 252 253class FunctionCallNode : public ParseNode { 254 public: 255 FunctionCallNode(); 256 virtual ~FunctionCallNode(); 257 258 virtual const FunctionCallNode* AsFunctionCall() const OVERRIDE; 259 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 260 virtual LocationRange GetRange() const OVERRIDE; 261 virtual Err MakeErrorDescribing( 262 const std::string& msg, 263 const std::string& help = std::string()) const OVERRIDE; 264 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 265 266 const Token& function() const { return function_; } 267 void set_function(Token t) { function_ = t; } 268 269 const ListNode* args() const { return args_.get(); } 270 void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); } 271 272 const BlockNode* block() const { return block_.get(); } 273 void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); } 274 275 private: 276 Token function_; 277 scoped_ptr<ListNode> args_; 278 scoped_ptr<BlockNode> block_; // May be null. 279 280 DISALLOW_COPY_AND_ASSIGN(FunctionCallNode); 281}; 282 283// IdentifierNode -------------------------------------------------------------- 284 285class IdentifierNode : public ParseNode { 286 public: 287 IdentifierNode(); 288 IdentifierNode(const Token& token); 289 virtual ~IdentifierNode(); 290 291 virtual const IdentifierNode* AsIdentifier() const OVERRIDE; 292 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 293 virtual LocationRange GetRange() const OVERRIDE; 294 virtual Err MakeErrorDescribing( 295 const std::string& msg, 296 const std::string& help = std::string()) const OVERRIDE; 297 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 298 299 const Token& value() const { return value_; } 300 void set_value(const Token& t) { value_ = t; } 301 302 private: 303 Token value_; 304 305 DISALLOW_COPY_AND_ASSIGN(IdentifierNode); 306}; 307 308// ListNode -------------------------------------------------------------------- 309 310class ListNode : public ParseNode { 311 public: 312 ListNode(); 313 virtual ~ListNode(); 314 315 virtual const ListNode* AsList() const OVERRIDE; 316 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 317 virtual LocationRange GetRange() const OVERRIDE; 318 virtual Err MakeErrorDescribing( 319 const std::string& msg, 320 const std::string& help = std::string()) const OVERRIDE; 321 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 322 323 void set_begin_token(const Token& t) { begin_token_ = t; } 324 void set_end_token(const Token& t) { end_token_ = t; } 325 326 void append_item(scoped_ptr<ParseNode> s) { 327 contents_.push_back(s.release()); 328 } 329 const std::vector<const ParseNode*>& contents() const { return contents_; } 330 331 private: 332 // Tokens corresponding to the [ and ]. 333 Token begin_token_; 334 Token end_token_; 335 336 // Owning pointers, use unique_ptr when we can use C++11. 337 std::vector<const ParseNode*> contents_; 338 339 DISALLOW_COPY_AND_ASSIGN(ListNode); 340}; 341 342// LiteralNode ----------------------------------------------------------------- 343 344class LiteralNode : public ParseNode { 345 public: 346 LiteralNode(); 347 LiteralNode(const Token& token); 348 virtual ~LiteralNode(); 349 350 virtual const LiteralNode* AsLiteral() const OVERRIDE; 351 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 352 virtual LocationRange GetRange() const OVERRIDE; 353 virtual Err MakeErrorDescribing( 354 const std::string& msg, 355 const std::string& help = std::string()) const OVERRIDE; 356 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 357 358 const Token& value() const { return value_; } 359 void set_value(const Token& t) { value_ = t; } 360 361 private: 362 Token value_; 363 364 DISALLOW_COPY_AND_ASSIGN(LiteralNode); 365}; 366 367// UnaryOpNode ----------------------------------------------------------------- 368 369class UnaryOpNode : public ParseNode { 370 public: 371 UnaryOpNode(); 372 virtual ~UnaryOpNode(); 373 374 virtual const UnaryOpNode* AsUnaryOp() const OVERRIDE; 375 virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; 376 virtual LocationRange GetRange() const OVERRIDE; 377 virtual Err MakeErrorDescribing( 378 const std::string& msg, 379 const std::string& help = std::string()) const OVERRIDE; 380 virtual void Print(std::ostream& out, int indent) const OVERRIDE; 381 382 const Token& op() const { return op_; } 383 void set_op(const Token& t) { op_ = t; } 384 385 const ParseNode* operand() const { return operand_.get(); } 386 void set_operand(scoped_ptr<ParseNode> operand) { 387 operand_ = operand.Pass(); 388 } 389 390 private: 391 Token op_; 392 scoped_ptr<ParseNode> operand_; 393 394 DISALLOW_COPY_AND_ASSIGN(UnaryOpNode); 395}; 396 397#endif // TOOLS_GN_PARSE_TREE_H_ 398