/* Copyright (c) 1993 by Sanjay Ghemawat */ #ifndef _LEXERH #define _LEXERH #include #include /* * Help in lexing. */ class charArray; class Lexer { public: Lexer(char const* file); Lexer(charArray*); ~Lexer(); /* * Status. */ enum StatusType { Valid, Eof, Error }; StatusType Status(); /* Get current status */ void SetError(char const*); /* Set error and corresponding msg */ static char const* LastError(); /* Return text of last error */ /* * Input operations. * Return true iff operation succeeded. * May have skipped undetermined amount of input in case of error. */ /* * Character operations. */ int Peek(char&); /* Return next char without advancing */ int Next(char&); /* Return next char and advance over it */ int Advance(char&); /* Advance and then Peek() */ /* * Skip past expected text. */ int Skip(char); int Skip(char const*); /* * Skip all whitespace. */ int SkipWS(); /* * Read an identifier. * An identifier is a non-empty sequence of alphanumeric characters * (including underscores), where the first character is not a digit. * * X is set to point to a temporary buffer managed by the Lexer. * The temporary buffer contains the null-terminated identifier. * The next GetId operation on the lexer will invalidate this * temporary buffer. */ int GetId(char const*& x); /* * Read text until the specified character is hit. * X is set as by GetId(char const*&). */ int GetUntil(char, char const*& x); /* * Read number. */ int GetNumber(int& num); /* * Read specified number of characters into supplied buffer. */ int GetText(char*, int len); /* * Read a string. The string read by this method terminates * at the first "]". However, backslashes can be used to * quote characters. Therefore if the input contains "\]", * that will be read as "]". If the input contains "\\", * that will be read as a single backslash. The closing "]" * is not included in the returned string and is not consumed * from the input. * * X is set as by GetId(char const*&). */ int GetString(char const*& x); /* * Write "string" to out so that it can be later read back with * a call to GetString. No terminating "]" is output. */ static void PutString(charArray*, char const* x); /* * Return current position in file. */ int Index(); /* * Reset to a position returned by an earlier call to "Index". * Also clears any error condition. */ void Reset(int pos); protected: char* buf; /* Contents of entire file */ int length; /* File length */ int index; /* Index of next char in file */ charArray* tmp; /* Temporary buffer */ /* Last error message */ static char const* lastError; }; inline Lexer::StatusType Lexer::Status() { if (index == length) {return Eof;} else if (index > length) {return Error;} else {return Valid;} } inline void Lexer::SetError(char const* msg) { lastError = msg; index = length+1; } inline char const* Lexer::LastError() { return lastError; } inline int Lexer::Index() { return index; } inline void Lexer::Reset(int i) { index = i; } inline int Lexer::Peek(char& c) { if (index < length) { c = buf[index]; return 1; } else return 0; } inline int Lexer::Next(char& c) { if (index < length) { c = buf[index]; index++; return 1; } else return 0; } inline int Lexer::Advance(char& c) { index++; if (index < length) { c = buf[index]; return 1; } else { /* Undo advance */ index = length; return 0; } } inline int Lexer::Skip(char c) { if ((index < length) && (buf[index] == c)) { index++; return 1; } else { SetError("unexpected character"); return 0; } } #endif /* _LEXERH */