/*************************************************************************** * Token.h * * * * The Token class ecapsulates a lexical analyzer for C++-like syntax. * * A token instance is associated with one or more text files, and * * grabs C++ tokens from them sequentially. There are many member * * functions designed to make parsing easy, such as "==" operators for * * strings and characters, and automatic conversion of numeric tokens * * into numeric values. * * * * Files can be nested via #include directives, and both styles of C++ * * comments are supported. * * * * * * HISTORY * * Name Date Description * * * * arvo 10/05/99 Fixed bug in TokFrame string allocation. * * arvo 01/15/95 Added ifdef, ifndef, else, and endif. * * arvo 02/13/94 Added Debug() member function. * * arvo 01/22/94 Several sections rewritten. * * arvo 06/19/93 Converted to C++ * * arvo 07/15/89 Rewritten for scene description parser. * * arvo 01/22/89 Initial coding. * * * *--------------------------------------------------------------------------* * Copyright (C) 1999, James Arvo * * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation. See http://www.fsf.org/copyleft/gpl.html * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT EXPRESS OR IMPLIED WARRANTY of merchantability or fitness for * * any particular purpose. See the GNU General Public License for more * * details. * * * ***************************************************************************/ #ifndef __TOKEN_INCLUDED__ #define __TOKEN_INCLUDED__ #include #include namespace ArvoMath { const int MaxTokenLen = 128; typedef enum { T_null, T_char, // A string of length 1. T_string, T_integer, T_float, T_ident, T_other, T_numeric, // Either T_float or T_int (use with == operator). T_directive, // Directives like #include are not returned to the user. T_nullmacro } TokType; typedef enum { T_malformed_float, T_unterm_string, T_unterm_comment, T_file_not_found, T_unknown_directive, T_string_expected, T_putback_error, T_name_too_long, T_no_endif, T_extra_endif, T_extra_else } TokError; class TokFrame { public: TokFrame(); TokFrame( const TokFrame &frame ) { *this = frame; } ~TokFrame(); void operator=( const TokFrame & ); public: TokFrame *next; FILE *source; char *fname; int line; int column; }; struct TokPath { char *path; TokPath *next; }; struct TokMacro { char *macro; char *repl; TokType type; TokMacro *next; }; class Token { public: // Constructors and destructor. Token(); Token( const char *file_name ); Token( FILE *file_pointer ); ~Token(); // Const data members for querying token information. TokType Type() const { return type; } // The type of token found. int Len() const { return length; } // The length of the token. int Line() const { return frame.line; } // The line it was found on. int Column() const { return Tcolumn; } // The column it began in. long Ivalue() const { return ivalue; } // Token value if an integer. float Fvalue() const; // Token value if int or float. char Char() const; // The token (if a Len() == 1). // Operators. int operator == ( const char* ) const; // 1 if strings match. int operator != ( const char* ) const; // 0 if strings match. int operator == ( char ) const; // 1 if token is this char. int operator != ( char ) const; // 0 if token is this char. int operator == ( TokType ) const; // 1 if token is of this type. int operator != ( TokType ) const; // 0 if token is of this type. Token & operator ++ ( ); // (prefix) Get the next token. Token & operator -- ( ); // (prefix) Put back one token. Token & operator ++ ( int ); // (postfix) Undefined. Token & operator -- ( int ); // (postfix) Undefined. // State-setting member functions. void Open( FILE * ); // Read already opened file. void Open( const char * ); // Open the named file. void CaseSensitive( int on_off ); // Applies to == and != operators. void AddPath( const char * ); // Adds path for <...> includes. void ClearPaths(); // Remove all search paths. // Miscellaneous. const char* Spelling() const; // The token itself. const char* FileName() const; // Current file being lexed. static void Debug( FILE * ); // Write all token streams to a file. static void Args ( int argc, char *argv[] ); // Search args for macro settings. void AddMacro( const char*, const char*, TokType type ); void SearchArgs(); private: // Private member functions. void Init(); int Getc ( int & ); void Unget( int c ) { pushed = c; } void Error( TokError error, const char *name = NULL ); int NonWhite( int & ); int HandleDirective(); int NextRawTok(); // No macro substitutions. int NextTok(); void PushFrame( FILE *fp, char *fname = NULL ); int PopFrame(); void GetName( char *name, int max ); FILE *ResolveName( const char *name ); TokMacro *MacroLookup( const char *str ) const; int MacroReplace( char *str, int &length, TokType &type ) const; // Private data members. TokPath *first; TokPath *last; TokMacro **table; TokFrame frame; TokType type; long ivalue; float fvalue; int length; int Tcolumn; int put_back; int case_sensitive; int pushed; int if_nesting; char spelling[ MaxTokenLen ]; char tempbuff[ MaxTokenLen ]; // Static data members. static int argc; static char **argv; static FILE *debug; }; // Predicate-style functions for testing token types. inline int Null ( const Token &t ) { return t.Type() == T_null; } inline int Numeric( const Token &t ) { return t.Type() == T_numeric; } inline int StringP( const Token &t ) { return t.Type() == T_string; } }; #endif