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 {
LexerLexer28   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     POOL,
45     RULE,
46     SUBNINJA,
47     TEOF,
48   };
49 
50   /// Return a human-readable form of a token, used in error messages.
51   static const char* TokenName(Token t);
52 
53   /// Return a human-readable token hint, used in error messages.
54   static const char* TokenErrorHint(Token expected);
55 
56   /// If the last token read was an ERROR token, provide more info
57   /// or the empty string.
58   std::string DescribeLastError();
59 
60   /// Start parsing some input.
61   void Start(StringPiece filename, StringPiece input);
62 
63   /// Read a Token from the Token enum.
64   Token ReadToken();
65 
66   /// Rewind to the last read Token.
67   void UnreadToken();
68 
69   /// If the next token is \a token, read it and return true.
70   bool PeekToken(Token token);
71 
72   /// Read a simple identifier (a rule or variable name).
73   /// Returns false if a name can't be read.
74   bool ReadIdent(std::string* out);
75 
76   /// Read a path (complete with $escapes).
77   /// Returns false only on error, returned path may be empty if a delimiter
78   /// (space, newline) is hit.
ReadPathLexer79   bool ReadPath(EvalString* path, std::string* err) {
80     return ReadEvalString(path, true, err);
81   }
82 
83   /// Read the value side of a var = value line (complete with $escapes).
84   /// Returns false only on error.
ReadVarValueLexer85   bool ReadVarValue(EvalString* value, std::string* err) {
86     return ReadEvalString(value, false, err);
87   }
88 
89   /// Construct an error message with context.
90   bool Error(const std::string& message, std::string* err);
91 
92 private:
93   /// Skip past whitespace (called after each read token/ident/etc.).
94   void EatWhitespace();
95 
96   /// Read a $-escaped string.
97   bool ReadEvalString(EvalString* eval, bool path, std::string* err);
98 
99   StringPiece filename_;
100   StringPiece input_;
101   const char* ofs_;
102   const char* last_token_;
103 };
104 
105 #endif // NINJA_LEXER_H_
106