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.
5 #ifndef TOOLS_GN_PARSER_H_
6 #define TOOLS_GN_PARSER_H_
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"
18 typedef scoped_ptr
<ParseNode
> (Parser::*PrefixFunc
)(Token token
);
19 typedef scoped_ptr
<ParseNode
> (Parser::*InfixFunc
)(scoped_ptr
<ParseNode
> left
,
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.
33 // Will return a null pointer and set the err on error.
34 static scoped_ptr
<ParseNode
> Parse(const std::vector
<Token
>& tokens
,
37 // Alternative to parsing that assumes the input is an expression.
38 static scoped_ptr
<ParseNode
> ParseExpression(const std::vector
<Token
>& tokens
,
41 scoped_ptr
<ParseNode
> ParseExpression();
44 // Vector must be valid for lifetime of call.
45 Parser(const std::vector
<Token
>& tokens
, Err
* err
);
48 // Parses an expression with the given precedence or higher.
49 scoped_ptr
<ParseNode
> ParseExpression(int precedence
);
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 scoped_ptr
<ParseNode
> BlockComment(Token token
);
59 // |InfixFunc|s used in parsing expressions.
60 scoped_ptr
<ParseNode
> BinaryOperator(scoped_ptr
<ParseNode
> left
, Token token
);
61 scoped_ptr
<ParseNode
> IdentifierOrCall(scoped_ptr
<ParseNode
> left
,
63 scoped_ptr
<ParseNode
> Assignment(scoped_ptr
<ParseNode
> left
, Token token
);
64 scoped_ptr
<ParseNode
> Subscript(scoped_ptr
<ParseNode
> left
, Token token
);
65 scoped_ptr
<ParseNode
> DotOperator(scoped_ptr
<ParseNode
> left
, Token token
);
67 // Helper to parse a comma separated list, optionally allowing trailing
68 // commas (allowed in [] lists, not in function calls).
69 scoped_ptr
<ListNode
> ParseList(Token start_token
,
70 Token::Type stop_before
,
71 bool allow_trailing_comma
);
73 scoped_ptr
<ParseNode
> ParseFile();
74 scoped_ptr
<ParseNode
> ParseStatement();
75 scoped_ptr
<BlockNode
> ParseBlock();
76 scoped_ptr
<ParseNode
> ParseCondition();
78 // Generates a pre- and post-order traversal of the tree.
79 void TraverseOrder(const ParseNode
* root
,
80 std::vector
<const ParseNode
*>* pre
,
81 std::vector
<const ParseNode
*>* post
);
83 // Attach comments to nearby syntax.
84 void AssignComments(ParseNode
* file
);
86 bool IsAssignment(const ParseNode
* node
) const;
87 bool IsStatementBreak(Token::Type token_type
) const;
89 bool LookAhead(Token::Type type
);
90 bool Match(Token::Type type
);
91 Token
Consume(Token::Type type
, const char* error_message
);
92 Token
Consume(Token::Type
* types
,
94 const char* error_message
);
97 const Token
& cur_token() const { return tokens_
[cur_
]; }
99 bool done() const { return at_end() || has_error(); }
100 bool at_end() const { return cur_
>= tokens_
.size(); }
101 bool has_error() const { return err_
->has_error(); }
103 std::vector
<Token
> tokens_
;
104 std::vector
<Token
> line_comment_tokens_
;
105 std::vector
<Token
> suffix_comment_tokens_
;
107 static ParserHelper expressions_
[Token::NUM_TYPES
];
111 // Current index into the tokens.
114 FRIEND_TEST_ALL_PREFIXES(Parser
, BinaryOp
);
115 FRIEND_TEST_ALL_PREFIXES(Parser
, Block
);
116 FRIEND_TEST_ALL_PREFIXES(Parser
, Condition
);
117 FRIEND_TEST_ALL_PREFIXES(Parser
, Expression
);
118 FRIEND_TEST_ALL_PREFIXES(Parser
, FunctionCall
);
119 FRIEND_TEST_ALL_PREFIXES(Parser
, List
);
120 FRIEND_TEST_ALL_PREFIXES(Parser
, ParenExpression
);
121 FRIEND_TEST_ALL_PREFIXES(Parser
, UnaryOp
);
123 DISALLOW_COPY_AND_ASSIGN(Parser
);
126 #endif // TOOLS_GN_PARSER_H_