Ninja
lexer.h
Go to the documentation of this file.
00001 // Copyright 2011 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #ifndef NINJA_LEXER_H_
00016 #define NINJA_LEXER_H_
00017 
00018 #include "string_piece.h"
00019 
00020 // Windows may #define ERROR.
00021 #ifdef ERROR
00022 #undef ERROR
00023 #endif
00024 
00025 struct EvalString;
00026 
00027 struct Lexer {
00028   Lexer() {}
00029   /// Helper ctor useful for tests.
00030   explicit Lexer(const char* input);
00031 
00032   enum Token {
00033     ERROR,
00034     BUILD,
00035     COLON,
00036     DEFAULT,
00037     EQUALS,
00038     IDENT,
00039     INCLUDE,
00040     INDENT,
00041     NEWLINE,
00042     PIPE,
00043     PIPE2,
00044     POOL,
00045     RULE,
00046     SUBNINJA,
00047     TEOF,
00048   };
00049 
00050   /// Return a human-readable form of a token, used in error messages.
00051   static const char* TokenName(Token t);
00052 
00053   /// Return a human-readable token hint, used in error messages.
00054   static const char* TokenErrorHint(Token expected);
00055 
00056   /// If the last token read was an ERROR token, provide more info
00057   /// or the empty string.
00058   string DescribeLastError();
00059 
00060   /// Start parsing some input.
00061   void Start(StringPiece filename, StringPiece input);
00062 
00063   /// Read a Token from the Token enum.
00064   Token ReadToken();
00065 
00066   /// Rewind to the last read Token.
00067   void UnreadToken();
00068 
00069   /// If the next token is \a token, read it and return true.
00070   bool PeekToken(Token token);
00071 
00072   /// Read a simple identifier (a rule or variable name).
00073   /// Returns false if a name can't be read.
00074   bool ReadIdent(string* out);
00075 
00076   /// Read a path (complete with $escapes).
00077   /// Returns false only on error, returned path may be empty if a delimiter
00078   /// (space, newline) is hit.
00079   bool ReadPath(EvalString* path, string* err) {
00080     return ReadEvalString(path, true, err);
00081   }
00082 
00083   /// Read the value side of a var = value line (complete with $escapes).
00084   /// Returns false only on error.
00085   bool ReadVarValue(EvalString* value, string* err) {
00086     return ReadEvalString(value, false, err);
00087   }
00088 
00089   /// Construct an error message with context.
00090   bool Error(const string& message, string* err);
00091 
00092 private:
00093   /// Skip past whitespace (called after each read token/ident/etc.).
00094   void EatWhitespace();
00095 
00096   /// Read a $-escaped string.
00097   bool ReadEvalString(EvalString* eval, bool path, string* err);
00098 
00099   StringPiece filename_;
00100   StringPiece input_;
00101   const char* ofs_;
00102   const char* last_token_;
00103 };
00104 
00105 #endif // NINJA_LEXER_H_