Parser.h (11354B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #ifndef __PARSER_H__ 30 #define __PARSER_H__ 31 32 /* 33 =============================================================================== 34 35 C/C++ compatible pre-compiler 36 37 =============================================================================== 38 */ 39 40 #define DEFINE_FIXED 0x0001 41 42 #define BUILTIN_LINE 1 43 #define BUILTIN_FILE 2 44 #define BUILTIN_DATE 3 45 #define BUILTIN_TIME 4 46 #define BUILTIN_STDC 5 47 48 #define INDENT_IF 0x0001 49 #define INDENT_ELSE 0x0002 50 #define INDENT_ELIF 0x0004 51 #define INDENT_IFDEF 0x0008 52 #define INDENT_IFNDEF 0x0010 53 54 // macro definitions 55 typedef struct define_s { 56 char * name; // define name 57 int flags; // define flags 58 int builtin; // > 0 if builtin define 59 int numparms; // number of define parameters 60 idToken * parms; // define parameters 61 idToken * tokens; // macro tokens (possibly containing parm tokens) 62 struct define_s *next; // next defined macro in a list 63 struct define_s *hashnext; // next define in the hash chain 64 } define_t; 65 66 // indents used for conditional compilation directives: 67 // #if, #else, #elif, #ifdef, #ifndef 68 typedef struct indent_s { 69 int type; // indent type 70 int skip; // true if skipping current indent 71 idLexer * script; // script the indent was in 72 struct indent_s *next; // next indent on the indent stack 73 } indent_t; 74 75 76 class idParser { 77 78 public: 79 // constructor 80 idParser(); 81 idParser( int flags ); 82 idParser( const char *filename, int flags = 0, bool OSPath = false ); 83 idParser( const char *ptr, int length, const char *name, int flags = 0 ); 84 // destructor 85 ~idParser(); 86 // load a source file 87 int LoadFile( const char *filename, bool OSPath = false ); 88 // load a source from the given memory with the given length 89 // NOTE: the ptr is expected to point at a valid C string: ptr[length] == '\0' 90 int LoadMemory( const char *ptr, int length, const char *name ); 91 // free the current source 92 void FreeSource( bool keepDefines = false ); 93 // returns true if a source is loaded 94 int IsLoaded() const { return idParser::loaded; } 95 // read a token from the source 96 int ReadToken( idToken *token ); 97 // expect a certain token, reads the token when available 98 int ExpectTokenString( const char *string ); 99 // expect a certain token type 100 int ExpectTokenType( int type, int subtype, idToken *token ); 101 // expect a token 102 int ExpectAnyToken( idToken *token ); 103 // returns true if the next token equals the given string and removes the token from the source 104 int CheckTokenString( const char *string ); 105 // returns true if the next token equals the given type and removes the token from the source 106 int CheckTokenType( int type, int subtype, idToken *token ); 107 // returns true if the next token equals the given string but does not remove the token from the source 108 int PeekTokenString( const char *string ); 109 // returns true if the next token equals the given type but does not remove the token from the source 110 int PeekTokenType( int type, int subtype, idToken *token ); 111 // skip tokens until the given token string is read 112 int SkipUntilString( const char *string ); 113 // skip the rest of the current line 114 int SkipRestOfLine(); 115 // skip the braced section 116 int SkipBracedSection( bool parseFirstBrace = true ); 117 // parse a braced section into a string 118 const char* ParseBracedSection( idStr& out, int tabs, bool parseFirstBrace, char intro, char outro ); 119 // parse a braced section into a string, maintaining indents and newlines 120 const char * ParseBracedSectionExact( idStr &out, int tabs = -1 ); 121 // parse the rest of the line 122 const char * ParseRestOfLine( idStr &out ); 123 // unread the given token 124 void UnreadToken( idToken *token ); 125 // read a token only if on the current line 126 int ReadTokenOnLine( idToken *token ); 127 // read a signed integer 128 int ParseInt(); 129 // read a boolean 130 bool ParseBool(); 131 // read a floating point number 132 float ParseFloat(); 133 // parse matrices with floats 134 int Parse1DMatrix( int x, float *m ); 135 int Parse2DMatrix( int y, int x, float *m ); 136 int Parse3DMatrix( int z, int y, int x, float *m ); 137 // get the white space before the last read token 138 int GetLastWhiteSpace( idStr &whiteSpace ) const; 139 // Set a marker in the source file (there is only one marker) 140 void SetMarker(); 141 // Get the string from the marker to the current position 142 void GetStringFromMarker( idStr& out, bool clean = false ); 143 // add a define to the source 144 int AddDefine( const char *string ); 145 // add builtin defines 146 void AddBuiltinDefines(); 147 // set the source include path 148 void SetIncludePath( const char *path ); 149 // set the punctuation set 150 void SetPunctuations( const punctuation_t *p ); 151 // returns a pointer to the punctuation with the given id 152 const char * GetPunctuationFromId( int id ); 153 // get the id for the given punctuation 154 int GetPunctuationId( const char *p ); 155 // set lexer flags 156 void SetFlags( int flags ); 157 // get lexer flags 158 int GetFlags() const; 159 // returns the current filename 160 const char * GetFileName() const; 161 // get current offset in current script 162 const int GetFileOffset() const; 163 // get file time for current script 164 const ID_TIME_T GetFileTime() const; 165 // returns the current line number 166 const int GetLineNum() const; 167 // print an error message 168 void Error( VERIFY_FORMAT_STRING const char *str, ... ) const; 169 // print a warning message 170 void Warning( VERIFY_FORMAT_STRING const char *str, ... ) const; 171 // returns true if at the end of the file 172 bool EndOfFile(); 173 // add a global define that will be added to all opened sources 174 static int AddGlobalDefine( const char *string ); 175 // remove the given global define 176 static int RemoveGlobalDefine( const char *name ); 177 // remove all global defines 178 static void RemoveAllGlobalDefines(); 179 // set the base folder to load files from 180 static void SetBaseFolder( const char *path ); 181 182 private: 183 int loaded; // set when a source file is loaded from file or memory 184 idStr filename; // file name of the script 185 idStr includepath; // path to include files 186 bool OSPath; // true if the file was loaded from an OS path 187 const punctuation_t *punctuations; // punctuations to use 188 int flags; // flags used for script parsing 189 idLexer * scriptstack; // stack with scripts of the source 190 idToken * tokens; // tokens to read first 191 define_t * defines; // list with macro definitions 192 define_t ** definehash; // hash chain with defines 193 indent_t * indentstack; // stack with indents 194 int skip; // > 0 if skipping conditional code 195 const char* marker_p; 196 197 static define_t *globaldefines; // list with global defines added to every source loaded 198 199 private: 200 void PushIndent( int type, int skip ); 201 void PopIndent( int *type, int *skip ); 202 void PushScript( idLexer *script ); 203 int ReadSourceToken( idToken *token ); 204 int ReadLine( idToken *token ); 205 int UnreadSourceToken( idToken *token ); 206 int ReadDefineParms( define_t *define, idToken **parms, int maxparms ); 207 int StringizeTokens( idToken *tokens, idToken *token ); 208 int MergeTokens( idToken *t1, idToken *t2 ); 209 int ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ); 210 int ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken ); 211 int ExpandDefineIntoSource( idToken *deftoken, define_t *define ); 212 void AddGlobalDefinesToSource(); 213 define_t * CopyDefine( define_t *define ); 214 define_t * FindHashedDefine(define_t **definehash, const char *name); 215 int FindDefineParm( define_t *define, const char *name ); 216 void AddDefineToHash(define_t *define, define_t **definehash); 217 static void PrintDefine( define_t *define ); 218 static void FreeDefine( define_t *define ); 219 static define_t *FindDefine( define_t *defines, const char *name ); 220 static define_t *DefineFromString( const char *string); 221 define_t * CopyFirstDefine(); 222 int Directive_include(); 223 int Directive_undef(); 224 int Directive_if_def( int type ); 225 int Directive_ifdef(); 226 int Directive_ifndef(); 227 int Directive_else(); 228 int Directive_endif(); 229 int EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer ); 230 int Evaluate( signed long int *intvalue, double *floatvalue, int integer ); 231 int DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer); 232 int Directive_define(); 233 int Directive_elif(); 234 int Directive_if(); 235 int Directive_line(); 236 int Directive_error(); 237 int Directive_warning(); 238 int Directive_pragma(); 239 void UnreadSignToken(); 240 int Directive_eval(); 241 int Directive_evalfloat(); 242 int ReadDirective(); 243 int DollarDirective_evalint(); 244 int DollarDirective_evalfloat(); 245 int ReadDollarDirective(); 246 }; 247 248 ID_INLINE const char *idParser::GetFileName() const { 249 if ( idParser::scriptstack ) { 250 return idParser::scriptstack->GetFileName(); 251 } 252 else { 253 return ""; 254 } 255 } 256 257 ID_INLINE const int idParser::GetFileOffset() const { 258 if ( idParser::scriptstack ) { 259 return idParser::scriptstack->GetFileOffset(); 260 } 261 else { 262 return 0; 263 } 264 } 265 266 ID_INLINE const ID_TIME_T idParser::GetFileTime() const { 267 if ( idParser::scriptstack ) { 268 return idParser::scriptstack->GetFileTime(); 269 } 270 else { 271 return 0; 272 } 273 } 274 275 ID_INLINE const int idParser::GetLineNum() const { 276 if ( idParser::scriptstack ) { 277 return idParser::scriptstack->GetLineNum(); 278 } 279 else { 280 return 0; 281 } 282 } 283 284 #endif /* !__PARSER_H__ */