etqw-sdk/source/idlib/text/Parser.h

286 lines
11 KiB
C
Raw Permalink Normal View History

2008-05-29 00:00:00 +00:00
// Copyright (C) 2007 Id Software, Inc.
//
#ifndef __PARSER_H__
#define __PARSER_H__
/*
===============================================================================
C/C++ compatible pre-compiler
===============================================================================
*/
#define DEFINE_FIXED 0x0001
#define BUILTIN_LINE 1
#define BUILTIN_FILE 2
#define BUILTIN_DATE 3
#define BUILTIN_TIME 4
#define BUILTIN_STDC 5
#define INDENT_IF 0x0001
#define INDENT_ELSE 0x0002
#define INDENT_ELIF 0x0004
#define INDENT_IFDEF 0x0008
#define INDENT_IFNDEF 0x0010
// macro definitions
struct define_t {
char * name; // define name
int flags; // define flags
int builtin; // > 0 if builtin define
int numparms; // number of define parameters
idToken * parms; // define parameters
idToken * tokens; // macro tokens (possibly containing parm tokens)
define_t * next; // next defined macro in a list
define_t * hashnext; // next define in the hash chain
};
// indents used for conditional compilation directives:
// #if, #else, #elif, #ifdef, #ifndef
struct indent_t {
int type; // indent type
int skip; // true if skipping current indent
int skipElse; // true if any following else sections should be skipped
idLexer * script; // script the indent was in
indent_t * next; // next indent on the indent stack
};
typedef void (*pragmaFunc_t)( void *data, const char *pragma );
class idParser {
public:
// constructor
idParser();
idParser( int flags );
idParser( const char *filename, int flags = 0, bool OSPath = false );
idParser( const char *ptr, int length, const char *name, int flags = 0 );
// destructor
~idParser();
// load a source file
int LoadFile( const char *filename, bool OSPath = false, int startLine = 1 );
// load a source from the given memory with the given length
// NOTE: the ptr is expected to point at a valid C string: ptr[length] == '\0'
int LoadMemory( const char *ptr, int length, const char *name, int startLine = 1 );
int LoadMemoryBinary( const byte *ptr, int length, const char *name, idTokenCache* globals );
void WriteBinary( idFile* f, idTokenCache* tokenCache = NULL );
void ResetBinaryParsing();
// free the current source
void FreeSource( bool keepDefines = false );
// returns true if a source is loaded
int IsLoaded( void ) const { return idParser::loaded; }
// read a token from the source
int ReadToken( idToken *token );
// expect a certain token, reads the token when available
bool ExpectTokenString( const char *string, idToken* other = NULL );
// expect a certain token type
int ExpectTokenType( int type, int subtype, idToken *token );
// expect a token
int ExpectAnyToken( idToken *token );
// returns true if the next token equals the given string and removes the token from the source
int CheckTokenString( const char *string );
// returns true if the next token equals the given type and removes the token from the source
int CheckTokenType( int type, int subtype, idToken *token );
// returns true if the next token equals the given string but does not remove the token from the source
int PeekTokenString( const char *string );
// returns true if the next token equals the given type but does not remove the token from the source
int PeekTokenType( int type, int subtype, idToken *token );
// skip tokens until the given token string is read
int SkipUntilString( const char *string, idToken *token );
// skip the rest of the current line
int SkipRestOfLine( void );
// skip the braced section
int SkipBracedSection( bool parseFirstBrace = true );
// parse a braced section into a string
const char * ParseBracedSection( idStr &out, int tabs = -1, bool parseFirstBrace = true, char intro = '{', char outro = '}' );
// parse the rest of the line
const char * ParseRestOfLine( idStr &out );
// unread the given token
void UnreadToken( const idToken& token );
// read a token only if on the current line
int ReadTokenOnLine( idToken *token );
// read a signed integer
int ParseInt( void );
// read a boolean
bool ParseBool( void );
// read a floating point number
float ParseFloat( bool* hadError = NULL );
// parse matrices with floats
int Parse1DMatrix( int x, float *m );
int Parse2DMatrix( int y, int x, float *m );
int Parse3DMatrix( int z, int y, int x, float *m );
// retrieves the white space after the last read token
int GetNextWhiteSpace( idStr &whiteSpace, bool currentLine );
// retrieves the white space before the last read token
int GetLastWhiteSpace( idStr &whiteSpace ) const;
// add a define to the source
int AddDefine( const char *string );
// add includes to the source
int AddIncludes( const idStrList& includes );
// add an include to the source
int AddInclude( const char *string );
// add builtin defines
void AddBuiltinDefines( void );
// set the source include path
void SetIncludePath( const char *path );
// set pragma callback
void SetPragmaCallback( void *data, pragmaFunc_t func );
// set the punctuation set
void SetPunctuations( const punctuation_t *p );
// returns a pointer to the punctuation with the given id
const char * GetPunctuationFromId( int id );
// get the id for the given punctuation
int GetPunctuationId( const char *p );
// set lexer flags
void SetFlags( int flags );
// get lexer flags
int GetFlags( void ) const;
// returns the current filename
const char * GetFileName( void ) const;
// get current offset in current script
const int GetFileOffset( void ) const;
// get file time for current script
const unsigned int GetFileTime( void ) const;
// returns the current line number
const int GetLineNum( void ) const;
// print an error message
void Error( const char *str, ... ) const;
// print a warning message
void Warning( const char *str, ... ) const;
// for enumerating only the current level
int GetCurrentDependency( void ) const;
// walk all included files, start from 0 to enumerate all
const char* GetNextDependency( int &index ) const;
// add a global define that will be added to all opened sources
static int AddGlobalDefine( const char *string );
// remove the given global define
static int RemoveGlobalDefine( const char *name );
// remove all global defines
static void RemoveAllGlobalDefines( void );
// set the base folder to load files from
static void SetBaseFolder( const char *path );
// save off the state of the dependencies list
void PushDependencies();
void PopDependencies();
private:
int loaded; // set when a source file is loaded from file or memory
idStr filename; // file name of the script
idStr includepath; // path to include files
bool OSPath; // true if the file was loaded from an OS path
const punctuation_t *punctuations; // punctuations to use
int flags; // flags used for script parsing
idLexer * scriptstack; // stack with scripts of the source
idToken * tokens; // tokens to read first
define_t * defines; // list with macro definitions
define_t ** definehash; // hash chain with defines
indent_t * indentstack; // stack with indents
int skip; // > 0 if skipping conditional code
pragmaFunc_t pragmaCallback; // called when a #pragma is parsed
void * pragmaData;
int startLine; // line offset
static define_t * globaldefines; // list with global defines added to every source loaded
idStrList dependencies; // list of filenames that have been included
sdStack< int > dependencyStateStack; // stack of the number of dependencies
private:
void PushIndent( int type, int skip, int skipElse );
void PopIndent( int &type, int &skip, int &skipElse );
bool PushScript( idLexer *script );
int ReadSourceToken( idToken *token );
int ReadLine( idToken *token, bool multiline );
bool UnreadSourceToken( const idToken& token );
int ReadDefineParms( define_t *define, idToken **parms, int maxparms );
int StringizeTokens( idToken *tokens, idToken *token );
int MergeTokens( idToken *t1, idToken *t2 );
int ExpandBuiltinDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken );
int ExpandDefine( idToken *deftoken, define_t *define, idToken **firsttoken, idToken **lasttoken );
int ExpandDefineIntoSource( idToken *deftoken, define_t *define );
void AddGlobalDefinesToSource( void );
define_t * CopyDefine( define_t *define );
define_t * FindHashedDefine(define_t **definehash, const char *name);
int FindDefineParm( define_t *define, const char *name );
void AddDefineToHash(define_t *define, define_t **definehash);
static void PrintDefine( define_t *define );
static void FreeDefine( define_t *define );
static define_t * FindDefine( define_t *defines, const char *name );
static define_t * DefineFromString( const char *string );
define_t * CopyFirstDefine( void );
void UnreadSignToken( void );
int EvaluateTokens( idToken *tokens, signed long int *intvalue, double *floatvalue, int integer );
int Evaluate( signed long int *intvalue, double *floatvalue, int integer );
int DollarEvaluate( signed long int *intvalue, double *floatvalue, int integer);
int Directive_include( void );
int Directive_define( bool isTemplate );
int Directive_undef( void );
int Directive_if_def( int type );
int Directive_ifdef( void );
int Directive_ifndef( void );
int Directive_else( void );
int Directive_endif( void );
int Directive_elif( void );
int Directive_if( void );
int Directive_line( void );
int Directive_error( void );
int Directive_warning( void );
int Directive_pragma( void );
int ReadDirective( void );
int DollarDirective_if_def( int type );
int DollarDirective_ifdef( void );
int DollarDirective_ifndef( void );
int DollarDirective_else( void );
int DollarDirective_endif( void );
int DollarDirective_elif( void );
int DollarDirective_if( void );
int DollarDirective_evalint( void );
int DollarDirective_evalfloat( void );
int ReadDollarDirective( void );
};
ID_INLINE const char *idParser::GetFileName( void ) const {
if ( scriptstack ) {
return scriptstack->GetFileName();
} else {
return "";
}
}
ID_INLINE const int idParser::GetFileOffset( void ) const {
if ( scriptstack ) {
return scriptstack->GetFileOffset();
} else {
return 0;
}
}
ID_INLINE const unsigned int idParser::GetFileTime( void ) const {
if ( scriptstack ) {
return scriptstack->GetFileTime();
} else {
return 0;
}
}
ID_INLINE const int idParser::GetLineNum( void ) const {
if ( scriptstack ) {
return scriptstack->GetLineNum();
} else {
return 0;
}
}
#endif /* !__PARSER_H__ */