#pragma once #include "base.h" // The current goal of this class is to read old .html file and parse java applets in them. // This is not expected to be of use to anyone in the world other than me. class Tokenizer { public: Tokenizer(); ~Tokenizer(); // initialize by opening a given file bool Init(const char* filename); // instead of giving it a filename, give it the contents of the file bool InitFromString(const char* spec); // whitespace preceding current token, valid until the tokenizer moves to the next token const char* Whitespace() { return _whitespace; } // text of current token, valid until the tokenizer moves to the next token const char* Text() { return _text; } // parse the next token, return false if there are no more tokens bool Next(); // return true if the current token matches the text (do not move to next token) bool Match(const char* text); // This is supposed to be 6-digit hexadecimal color. Either skip over it (and return the color) or throw an error. int Color(); // throw an error at the current token, using the text as explanation void Throw(const char* text, ...); // return true if the current token matches the text, and move to the next token bool Skip(const char* text); // Throw an error if this token does not matches the text (case insensitive), otherwise go to next token // Return false if there is no next token. bool Expect(const char* text); static void UnitTest(); private: // line containing current token, valid until tokenizer moves to the next token const char* Line() { return _line.c_str(); } // line number of current line in the overall file u8 LineNumber() { return _lineNumber; } // position of start of the current token in line (whitespace precedes position, text follows position) u8 Position() { return _position; } // close and delete any existing file and reset the tokenizer to nothing void Clear(); // some helper routine creates an istream which it passes to this routine to do the actual initialization bool InitFromIstream(std::istream* is); // copy the line so far into the whitespace and finish it off with a null terminator void FinishWhitespace(u4* len, u4 off); // If we are at the end of a line, skip until the next nonempty line. Record the whitespace so far. // Return false if we reach the end of the file. bool HandleNewLine(u4* len, u4* off); void AcceptSingleChar(u4 *off); void AcceptQuotedString(u4 *off); void AcceptSingleQuotedString(u4 *off); void AcceptNumber(u4 *off); void AcceptIdentifier(u4 *off); static const int c_maxTokenLength = 256; std::istream* _config; // configuration file to tokenize std::string _line; u4 _lineNumber; u4 _lineLength; u4 _position; u4 _nextPosition; bool _noMoreTokens; char _whitespace[c_maxTokenLength+1]; char _text[c_maxTokenLength+1]; };