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
25struct EvalString;
26
27struct 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
93private:
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