1 | // Copyright 2011 Google Inc. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef NINJA_LEXER_H_ |
16 | #define NINJA_LEXER_H_ |
17 | |
18 | #include "string_piece.h" |
19 | |
20 | // Windows may #define ERROR. |
21 | #ifdef ERROR |
22 | #undef ERROR |
23 | #endif |
24 | |
25 | struct EvalString; |
26 | |
27 | struct Lexer { |
28 | Lexer() {} |
29 | /// Helper ctor useful for tests. |
30 | explicit Lexer(const char* input); |
31 | |
32 | enum Token { |
33 | ERROR, |
34 | BUILD, |
35 | COLON, |
36 | DEFAULT, |
37 | EQUALS, |
38 | IDENT, |
39 | INCLUDE, |
40 | INDENT, |
41 | NEWLINE, |
42 | PIPE, |
43 | PIPE2, |
44 | PIPEAT, |
45 | POOL, |
46 | RULE, |
47 | SUBNINJA, |
48 | TEOF, |
49 | }; |
50 | |
51 | /// Return a human-readable form of a token, used in error messages. |
52 | static const char* TokenName(Token t); |
53 | |
54 | /// Return a human-readable token hint, used in error messages. |
55 | static const char* TokenErrorHint(Token expected); |
56 | |
57 | /// If the last token read was an ERROR token, provide more info |
58 | /// or the empty string. |
59 | std::string DescribeLastError(); |
60 | |
61 | /// Start parsing some input. |
62 | void Start(StringPiece filename, StringPiece input); |
63 | |
64 | /// Read a Token from the Token enum. |
65 | Token ReadToken(); |
66 | |
67 | /// Rewind to the last read Token. |
68 | void UnreadToken(); |
69 | |
70 | /// If the next token is \a token, read it and return true. |
71 | bool PeekToken(Token token); |
72 | |
73 | /// Read a simple identifier (a rule or variable name). |
74 | /// Returns false if a name can't be read. |
75 | bool ReadIdent(std::string* out); |
76 | |
77 | /// Read a path (complete with $escapes). |
78 | /// Returns false only on error, returned path may be empty if a delimiter |
79 | /// (space, newline) is hit. |
80 | bool ReadPath(EvalString* path, std::string* err) { |
81 | return ReadEvalString(path, true, err); |
82 | } |
83 | |
84 | /// Read the value side of a var = value line (complete with $escapes). |
85 | /// Returns false only on error. |
86 | bool ReadVarValue(EvalString* value, std::string* err) { |
87 | return ReadEvalString(value, false, err); |
88 | } |
89 | |
90 | /// Construct an error message with context. |
91 | bool Error(const std::string& message, std::string* err); |
92 | |
93 | private: |
94 | /// Skip past whitespace (called after each read token/ident/etc.). |
95 | void EatWhitespace(); |
96 | |
97 | /// Read a $-escaped string. |
98 | bool ReadEvalString(EvalString* eval, bool path, std::string* err); |
99 | |
100 | StringPiece filename_; |
101 | StringPiece input_; |
102 | const char* ofs_; |
103 | const char* last_token_; |
104 | }; |
105 | |
106 | #endif // NINJA_LEXER_H_ |
107 | |