1695b41eeSopenharmony_ci// Copyright 2011 Google Inc. All Rights Reserved.
2695b41eeSopenharmony_ci//
3695b41eeSopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4695b41eeSopenharmony_ci// you may not use this file except in compliance with the License.
5695b41eeSopenharmony_ci// You may obtain a copy of the License at
6695b41eeSopenharmony_ci//
7695b41eeSopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8695b41eeSopenharmony_ci//
9695b41eeSopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10695b41eeSopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS,
11695b41eeSopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12695b41eeSopenharmony_ci// See the License for the specific language governing permissions and
13695b41eeSopenharmony_ci// limitations under the License.
14695b41eeSopenharmony_ci
15695b41eeSopenharmony_ci#ifndef NINJA_LEXER_H_
16695b41eeSopenharmony_ci#define NINJA_LEXER_H_
17695b41eeSopenharmony_ci
18695b41eeSopenharmony_ci#include "string_piece.h"
19695b41eeSopenharmony_ci
20695b41eeSopenharmony_ci// Windows may #define ERROR.
21695b41eeSopenharmony_ci#ifdef ERROR
22695b41eeSopenharmony_ci#undef ERROR
23695b41eeSopenharmony_ci#endif
24695b41eeSopenharmony_ci
25695b41eeSopenharmony_cistruct EvalString;
26695b41eeSopenharmony_ci
27695b41eeSopenharmony_cistruct Lexer {
28695b41eeSopenharmony_ci  Lexer() {}
29695b41eeSopenharmony_ci  /// Helper ctor useful for tests.
30695b41eeSopenharmony_ci  explicit Lexer(const char* input);
31695b41eeSopenharmony_ci
32695b41eeSopenharmony_ci  enum Token {
33695b41eeSopenharmony_ci    ERROR,
34695b41eeSopenharmony_ci    BUILD,
35695b41eeSopenharmony_ci    COLON,
36695b41eeSopenharmony_ci    DEFAULT,
37695b41eeSopenharmony_ci    EQUALS,
38695b41eeSopenharmony_ci    IDENT,
39695b41eeSopenharmony_ci    INCLUDE,
40695b41eeSopenharmony_ci    INDENT,
41695b41eeSopenharmony_ci    NEWLINE,
42695b41eeSopenharmony_ci    PIPE,
43695b41eeSopenharmony_ci    PIPE2,
44695b41eeSopenharmony_ci    PIPEAT,
45695b41eeSopenharmony_ci    POOL,
46695b41eeSopenharmony_ci    RULE,
47695b41eeSopenharmony_ci    SUBNINJA,
48695b41eeSopenharmony_ci    TEOF,
49695b41eeSopenharmony_ci  };
50695b41eeSopenharmony_ci
51695b41eeSopenharmony_ci  /// Return a human-readable form of a token, used in error messages.
52695b41eeSopenharmony_ci  static const char* TokenName(Token t);
53695b41eeSopenharmony_ci
54695b41eeSopenharmony_ci  /// Return a human-readable token hint, used in error messages.
55695b41eeSopenharmony_ci  static const char* TokenErrorHint(Token expected);
56695b41eeSopenharmony_ci
57695b41eeSopenharmony_ci  /// If the last token read was an ERROR token, provide more info
58695b41eeSopenharmony_ci  /// or the empty string.
59695b41eeSopenharmony_ci  std::string DescribeLastError();
60695b41eeSopenharmony_ci
61695b41eeSopenharmony_ci  /// Start parsing some input.
62695b41eeSopenharmony_ci  void Start(StringPiece filename, StringPiece input);
63695b41eeSopenharmony_ci
64695b41eeSopenharmony_ci  /// Read a Token from the Token enum.
65695b41eeSopenharmony_ci  Token ReadToken();
66695b41eeSopenharmony_ci
67695b41eeSopenharmony_ci  /// Rewind to the last read Token.
68695b41eeSopenharmony_ci  void UnreadToken();
69695b41eeSopenharmony_ci
70695b41eeSopenharmony_ci  /// If the next token is \a token, read it and return true.
71695b41eeSopenharmony_ci  bool PeekToken(Token token);
72695b41eeSopenharmony_ci
73695b41eeSopenharmony_ci  /// Read a simple identifier (a rule or variable name).
74695b41eeSopenharmony_ci  /// Returns false if a name can't be read.
75695b41eeSopenharmony_ci  bool ReadIdent(std::string* out);
76695b41eeSopenharmony_ci
77695b41eeSopenharmony_ci  /// Read a path (complete with $escapes).
78695b41eeSopenharmony_ci  /// Returns false only on error, returned path may be empty if a delimiter
79695b41eeSopenharmony_ci  /// (space, newline) is hit.
80695b41eeSopenharmony_ci  bool ReadPath(EvalString* path, std::string* err) {
81695b41eeSopenharmony_ci    return ReadEvalString(path, true, err);
82695b41eeSopenharmony_ci  }
83695b41eeSopenharmony_ci
84695b41eeSopenharmony_ci  /// Read the value side of a var = value line (complete with $escapes).
85695b41eeSopenharmony_ci  /// Returns false only on error.
86695b41eeSopenharmony_ci  bool ReadVarValue(EvalString* value, std::string* err) {
87695b41eeSopenharmony_ci    return ReadEvalString(value, false, err);
88695b41eeSopenharmony_ci  }
89695b41eeSopenharmony_ci
90695b41eeSopenharmony_ci  /// Construct an error message with context.
91695b41eeSopenharmony_ci  bool Error(const std::string& message, std::string* err);
92695b41eeSopenharmony_ci
93695b41eeSopenharmony_ciprivate:
94695b41eeSopenharmony_ci  /// Skip past whitespace (called after each read token/ident/etc.).
95695b41eeSopenharmony_ci  void EatWhitespace();
96695b41eeSopenharmony_ci
97695b41eeSopenharmony_ci  /// Read a $-escaped string.
98695b41eeSopenharmony_ci  bool ReadEvalString(EvalString* eval, bool path, std::string* err);
99695b41eeSopenharmony_ci
100695b41eeSopenharmony_ci  StringPiece filename_;
101695b41eeSopenharmony_ci  StringPiece input_;
102695b41eeSopenharmony_ci  const char* ofs_;
103695b41eeSopenharmony_ci  const char* last_token_;
104695b41eeSopenharmony_ci};
105695b41eeSopenharmony_ci
106695b41eeSopenharmony_ci#endif // NINJA_LEXER_H_
107