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 <vector>
9
10#include "base/basictypes.h"
11#include "base/gtest_prod_util.h"
12#include "base/memory/scoped_ptr.h"
13#include "tools/gn/err.h"
14#include "tools/gn/parse_tree.h"
15
16// Parses a series of tokens. The resulting AST will refer to the tokens passed
17// to the input, so the tokens an the file data they refer to must outlive your
18// use of the ParseNode.
19class Parser {
20 public:
21  // Will return a null pointer and set the err on error.
22  static scoped_ptr<ParseNode> Parse(const std::vector<Token>& tokens,
23                                     Err* err);
24
25  // Alternative to parsing that assumes the input is an expression.
26  static scoped_ptr<ParseNode> ParseExpression(const std::vector<Token>& tokens,
27                                               Err* err);
28
29 private:
30  // Vector must be valid for lifetime of call.
31  Parser(const std::vector<Token>& tokens, Err* err);
32  ~Parser();
33
34  scoped_ptr<AccessorNode> ParseAccessor();
35  scoped_ptr<BlockNode> ParseBlock(bool need_braces);
36  scoped_ptr<ConditionNode> ParseCondition();
37  scoped_ptr<ParseNode> ParseExpression();
38  scoped_ptr<ParseNode> ParseExpressionExceptBinaryOperators();
39  scoped_ptr<FunctionCallNode> ParseFunctionCall();
40  scoped_ptr<ListNode> ParseList(const Token& expected_begin,
41                                 const Token& expected_end);
42  scoped_ptr<ParseNode> ParseParenExpression();
43  scoped_ptr<UnaryOpNode> ParseUnaryOp();
44
45  bool IsToken(Token::Type type, char* str) const;
46
47  // Gets an error corresponding to the last token. When we hit an EOF
48  // usually we've already gone beyond the end (or maybe there are no tokens)
49  // so there is some tricky logic to report this.
50  Err MakeEOFError(const std::string& message,
51                   const std::string& help = std::string()) const;
52
53  const Token& cur_token() const { return tokens_[cur_]; }
54
55  bool done() const { return at_end() || has_error(); }
56  bool at_end() const { return cur_ >= tokens_.size(); }
57  bool has_error() const { return err_->has_error(); }
58
59  const Token& next_token() const { return tokens_[cur_ + 1]; }
60  bool has_next_token() const { return cur_ + 1 < tokens_.size(); }
61
62  const std::vector<Token>& tokens_;
63
64  Err* err_;
65
66  // Current index into the tokens.
67  size_t cur_;
68
69  FRIEND_TEST_ALL_PREFIXES(Parser, BinaryOp);
70  FRIEND_TEST_ALL_PREFIXES(Parser, Block);
71  FRIEND_TEST_ALL_PREFIXES(Parser, Condition);
72  FRIEND_TEST_ALL_PREFIXES(Parser, Expression);
73  FRIEND_TEST_ALL_PREFIXES(Parser, FunctionCall);
74  FRIEND_TEST_ALL_PREFIXES(Parser, List);
75  FRIEND_TEST_ALL_PREFIXES(Parser, ParenExpression);
76  FRIEND_TEST_ALL_PREFIXES(Parser, UnaryOp);
77
78  DISALLOW_COPY_AND_ASSIGN(Parser);
79};
80
81#endif  // TOOLS_GN_PARSER_H_
82