Index: tools/gn/parse_tree.h |
diff --git a/tools/gn/parse_tree.h b/tools/gn/parse_tree.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..09646e51ac4c4b2366ef1b549f1f3ef304819d2c |
--- /dev/null |
+++ b/tools/gn/parse_tree.h |
@@ -0,0 +1,366 @@ |
+// 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_PARSE_TREE_H_ |
+#define TOOLS_GN_PARSE_TREE_H_ |
+ |
+#include <vector> |
+ |
+#include "base/basictypes.h" |
+#include "base/compiler_specific.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "tools/gn/err.h" |
+#include "tools/gn/token.h" |
+#include "tools/gn/value.h" |
+ |
+class AccessorNode; |
+class BinaryOpNode; |
+class BlockNode; |
+class ConditionNode; |
+class FunctionCallNode; |
+class IdentifierNode; |
+class ListNode; |
+class LiteralNode; |
+class Scope; |
+class UnaryOpNode; |
+ |
+// ParseNode ------------------------------------------------------------------- |
+ |
+// A node in the AST. |
+class ParseNode { |
+ public: |
+ ParseNode(); |
+ virtual ~ParseNode(); |
+ |
+ virtual const AccessorNode* AsAccessor() const; |
+ virtual const BinaryOpNode* AsBinaryOp() const; |
+ virtual const BlockNode* AsBlock() const; |
+ virtual const ConditionNode* AsConditionNode() const; |
+ virtual const FunctionCallNode* AsFunctionCall() const; |
+ virtual const IdentifierNode* AsIdentifier() const; |
+ virtual const ListNode* AsList() const; |
+ virtual const LiteralNode* AsLiteral() const; |
+ virtual const UnaryOpNode* AsUnaryOp() const; |
+ |
+ virtual Value Execute(Scope* scope, Err* err) const = 0; |
+ |
+ virtual LocationRange GetRange() const = 0; |
+ |
+ // Returns an error with the given messages and the range set to something |
+ // that indicates this node. |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const = 0; |
+ |
+ // Prints a representation of this node to the given string, indenting |
+ // by the given number of spaces. |
+ virtual void Print(std::ostream& out, int indent) const = 0; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ParseNode); |
+}; |
+ |
+// AccessorNode ---------------------------------------------------------------- |
+ |
+// Access an array element. |
+// |
+// If we need to add support for member variables like "variable.len" I was |
+// thinking this would also handle that case. |
+class AccessorNode : public ParseNode { |
+ public: |
+ AccessorNode(); |
+ virtual ~AccessorNode(); |
+ |
+ virtual const AccessorNode* AsAccessor() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ // Base is the thing on the left of the [], currently always required to be |
+ // an identifier token. |
+ const Token& base() const { return base_; } |
+ void set_base(const Token& b) { base_ = b; } |
+ |
+ // Index is the expression inside the []. |
+ const ParseNode* index() const { return index_.get(); } |
+ void set_index(scoped_ptr<ParseNode> i) { index_ = i.Pass(); } |
+ |
+ private: |
+ Token base_; |
+ scoped_ptr<ParseNode> index_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AccessorNode); |
+}; |
+ |
+// BinaryOpNode ---------------------------------------------------------------- |
+ |
+class BinaryOpNode : public ParseNode { |
+ public: |
+ BinaryOpNode(); |
+ virtual ~BinaryOpNode(); |
+ |
+ virtual const BinaryOpNode* AsBinaryOp() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ const Token& op() const { return op_; } |
+ void set_op(const Token& t) { op_ = t; } |
+ |
+ const ParseNode* left() const { return left_.get(); } |
+ void set_left(scoped_ptr<ParseNode> left) { |
+ left_ = left.Pass(); |
+ } |
+ |
+ const ParseNode* right() const { return right_.get(); } |
+ void set_right(scoped_ptr<ParseNode> right) { |
+ right_ = right.Pass(); |
+ } |
+ |
+ private: |
+ scoped_ptr<ParseNode> left_; |
+ Token op_; |
+ scoped_ptr<ParseNode> right_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BinaryOpNode); |
+}; |
+ |
+// BlockNode ------------------------------------------------------------------- |
+ |
+class BlockNode : public ParseNode { |
+ public: |
+ // Set has_scope if this block introduces a nested scope. |
+ BlockNode(bool has_scope); |
+ virtual ~BlockNode(); |
+ |
+ virtual const BlockNode* AsBlock() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ void set_begin_token(const Token* t) { begin_token_ = t; } |
+ void set_end_token(const Token* t) { end_token_ = t; } |
+ |
+ const std::vector<ParseNode*>& statements() const { return statements_; } |
+ void append_statement(scoped_ptr<ParseNode> s) { |
+ statements_.push_back(s.release()); |
+ } |
+ |
+ // Doesn't create a nested scope. |
+ Value ExecuteBlockInScope(Scope* our_scope, Err* err) const; |
+ |
+ private: |
+ bool has_scope_; |
+ |
+ // Tokens corresponding to { and }, if any (may be NULL). |
+ const Token* begin_token_; |
+ const Token* end_token_; |
+ |
+ // Owning pointers, use unique_ptr when we can use C++11. |
+ std::vector<ParseNode*> statements_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BlockNode); |
+}; |
+ |
+// ConditionNode --------------------------------------------------------------- |
+ |
+class ConditionNode : public ParseNode { |
+ public: |
+ ConditionNode(); |
+ virtual ~ConditionNode(); |
+ |
+ virtual const ConditionNode* AsConditionNode() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ void set_if_token(const Token& token) { if_token_ = token; } |
+ |
+ const ParseNode* condition() const { return condition_.get(); } |
+ void set_condition(scoped_ptr<ParseNode> c) { |
+ condition_ = c.Pass(); |
+ } |
+ |
+ const BlockNode* if_true() const { return if_true_.get(); } |
+ void set_if_true(scoped_ptr<BlockNode> t) { |
+ if_true_ = t.Pass(); |
+ } |
+ |
+ // This is either empty, a block (for the else clause), or another |
+ // condition. |
+ const ParseNode* if_false() const { return if_false_.get(); } |
+ void set_if_false(scoped_ptr<ParseNode> f) { |
+ if_false_ = f.Pass(); |
+ } |
+ |
+ private: |
+ // Token corresponding to the "if" string. |
+ Token if_token_; |
+ |
+ scoped_ptr<ParseNode> condition_; // Always non-null. |
+ scoped_ptr<BlockNode> if_true_; // Always non-null. |
+ scoped_ptr<ParseNode> if_false_; // May be null. |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ConditionNode); |
+}; |
+ |
+// FunctionCallNode ------------------------------------------------------------ |
+ |
+class FunctionCallNode : public ParseNode { |
+ public: |
+ FunctionCallNode(); |
+ virtual ~FunctionCallNode(); |
+ |
+ virtual const FunctionCallNode* AsFunctionCall() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ const Token& function() const { return function_; } |
+ void set_function(Token t) { function_ = t; } |
+ |
+ const ListNode* args() const { return args_.get(); } |
+ void set_args(scoped_ptr<ListNode> a) { args_ = a.Pass(); } |
+ |
+ const BlockNode* block() const { return block_.get(); } |
+ void set_block(scoped_ptr<BlockNode> b) { block_ = b.Pass(); } |
+ |
+ private: |
+ Token function_; |
+ scoped_ptr<ListNode> args_; |
+ scoped_ptr<BlockNode> block_; // May be null. |
+ |
+ DISALLOW_COPY_AND_ASSIGN(FunctionCallNode); |
+}; |
+ |
+// IdentifierNode -------------------------------------------------------------- |
+ |
+class IdentifierNode : public ParseNode { |
+ public: |
+ IdentifierNode(); |
+ IdentifierNode(const Token& token); |
+ virtual ~IdentifierNode(); |
+ |
+ virtual const IdentifierNode* AsIdentifier() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ const Token& value() const { return value_; } |
+ void set_value(const Token& t) { value_ = t; } |
+ |
+ private: |
+ Token value_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(IdentifierNode); |
+}; |
+ |
+// ListNode -------------------------------------------------------------------- |
+ |
+class ListNode : public ParseNode { |
+ public: |
+ ListNode(); |
+ virtual ~ListNode(); |
+ |
+ virtual const ListNode* AsList() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ void set_begin_token(const Token& t) { begin_token_ = t; } |
+ void set_end_token(const Token& t) { end_token_ = t; } |
+ |
+ void append_item(scoped_ptr<ParseNode> s) { |
+ contents_.push_back(s.release()); |
+ } |
+ const std::vector<ParseNode*>& contents() const { return contents_; } |
+ |
+ private: |
+ // Tokens corresponding to the [ and ]. |
+ Token begin_token_; |
+ Token end_token_; |
+ |
+ // Owning pointers, use unique_ptr when we can use C++11. |
+ std::vector<ParseNode*> contents_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ListNode); |
+}; |
+ |
+// LiteralNode ----------------------------------------------------------------- |
+ |
+class LiteralNode : public ParseNode { |
+ public: |
+ LiteralNode(); |
+ LiteralNode(const Token& token); |
+ virtual ~LiteralNode(); |
+ |
+ virtual const LiteralNode* AsLiteral() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ const Token& value() const { return value_; } |
+ void set_value(const Token& t) { value_ = t; } |
+ |
+ private: |
+ Token value_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(LiteralNode); |
+}; |
+ |
+// UnaryOpNode ----------------------------------------------------------------- |
+ |
+class UnaryOpNode : public ParseNode { |
+ public: |
+ UnaryOpNode(); |
+ virtual ~UnaryOpNode(); |
+ |
+ virtual const UnaryOpNode* AsUnaryOp() const OVERRIDE; |
+ virtual Value Execute(Scope* scope, Err* err) const OVERRIDE; |
+ virtual LocationRange GetRange() const OVERRIDE; |
+ virtual Err MakeErrorDescribing( |
+ const std::string& msg, |
+ const std::string& help = std::string()) const OVERRIDE; |
+ virtual void Print(std::ostream& out, int indent) const OVERRIDE; |
+ |
+ const Token& op() const { return op_; } |
+ void set_op(const Token& t) { op_ = t; } |
+ |
+ const ParseNode* operand() const { return operand_.get(); } |
+ void set_operand(scoped_ptr<ParseNode> operand) { |
+ operand_ = operand.Pass(); |
+ } |
+ |
+ private: |
+ Token op_; |
+ scoped_ptr<ParseNode> operand_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(UnaryOpNode); |
+}; |
+ |
+#endif // TOOLS_GN_PARSE_TREE_H_ |