home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2006 March / Gamestar_82_2006-03_dvd.iso / DVDStar / Editace / quake4_sdkv10.exe / source / idlib / Lexer.h < prev    next >
C/C++ Source or Header  |  2005-11-14  |  17KB  |  467 lines

  1.  
  2. #ifndef __LEXER_H__
  3. #define __LEXER_H__
  4.  
  5. /*
  6. ===============================================================================
  7.  
  8.     Lexicographical parser
  9.  
  10.     Does not use memory allocation during parsing. The lexer uses no
  11.     memory allocation if a source is loaded with LoadMemory().
  12.     However, idToken may still allocate memory for large strings.
  13.     
  14.     A number directly following the escape character '\' in a string is
  15.     assumed to be in decimal format instead of octal. Binary numbers of
  16.     the form 0b.. or 0B.. can also be used.
  17.  
  18. ===============================================================================
  19. */
  20.  
  21. // lexer flags
  22. typedef enum {
  23.     LEXFL_NOERRORS                        = BIT(0),    // don't print any errors
  24.     LEXFL_NOWARNINGS                    = BIT(1),    // don't print any warnings
  25.     LEXFL_NOFATALERRORS                    = BIT(2),    // errors aren't fatal
  26.     LEXFL_NOSTRINGCONCAT                = BIT(3),    // multiple strings seperated by whitespaces are not concatenated
  27.     LEXFL_NOSTRINGESCAPECHARS            = BIT(4),    // no escape characters inside strings
  28.     LEXFL_NODOLLARPRECOMPILE            = BIT(5),    // don't use the $ sign for precompilation
  29.     LEXFL_NOBASEINCLUDES                = BIT(6),    // don't include files embraced with < >
  30.     LEXFL_ALLOWPATHNAMES                = BIT(7),    // allow path seperators in names
  31.     LEXFL_ALLOWNUMBERNAMES                = BIT(8),    // allow names to start with a number
  32.     LEXFL_ALLOWIPADDRESSES                = BIT(9),    // allow ip addresses to be parsed as numbers
  33.     LEXFL_ALLOWFLOATEXCEPTIONS            = BIT(10),    // allow float exceptions like 1.#INF or 1.#IND to be parsed
  34.     LEXFL_ALLOWMULTICHARLITERALS        = BIT(11),    // allow multi character literals
  35.     LEXFL_ALLOWBACKSLASHSTRINGCONCAT    = BIT(12),    // allow multiple strings seperated by '\' to be concatenated
  36.     LEXFL_ONLYSTRINGS                    = BIT(13),    // parse as whitespace deliminated strings (quoted strings keep quotes)
  37. // RAVEN BEGIN
  38. // jsinger: added to support binary writing from the lexer in either byte swapped or non-byte swapped formats
  39.     LEXFL_READBINARY                    = BIT(29),    // read a byte code compiled version of the file
  40.     LEXFL_BYTESWAP                        = BIT(30),    // when writing the byte code compiled file, byte swap numbers
  41.     LEXFL_WRITEBINARY                    = BIT(31)    // write out a byte code compiled version of the file
  42. // RAVEN END
  43. } lexerFlags_t;
  44.  
  45. // punctuation ids
  46. #define P_RSHIFT_ASSIGN                1
  47. #define P_LSHIFT_ASSIGN                2
  48. #define P_PARMS                        3
  49. #define P_PRECOMPMERGE                4
  50.  
  51. #define P_LOGIC_AND                    5
  52. #define P_LOGIC_OR                    6
  53. #define P_LOGIC_GEQ                    7
  54. #define P_LOGIC_LEQ                    8
  55. #define P_LOGIC_EQ                    9
  56. #define P_LOGIC_UNEQ                10
  57.  
  58. #define P_MUL_ASSIGN                11
  59. #define P_DIV_ASSIGN                12
  60. #define P_MOD_ASSIGN                13
  61. #define P_ADD_ASSIGN                14
  62. #define P_SUB_ASSIGN                15
  63. #define P_INC                        16
  64. #define P_DEC                        17
  65.  
  66. #define P_BIN_AND_ASSIGN            18
  67. #define P_BIN_OR_ASSIGN                19
  68. #define P_BIN_XOR_ASSIGN            20
  69. #define P_RSHIFT                    21
  70. #define P_LSHIFT                    22
  71.  
  72. #define P_POINTERREF                23
  73. #define P_CPP1                        24
  74. #define P_CPP2                        25
  75. #define P_MUL                        26
  76. #define P_DIV                        27
  77. #define P_MOD                        28
  78. #define P_ADD                        29
  79. #define P_SUB                        30
  80. #define P_ASSIGN                    31
  81.  
  82. #define P_BIN_AND                    32
  83. #define P_BIN_OR                    33
  84. #define P_BIN_XOR                    34
  85. #define P_BIN_NOT                    35
  86.  
  87. #define P_LOGIC_NOT                    36
  88. #define P_LOGIC_GREATER                37
  89. #define P_LOGIC_LESS                38
  90.  
  91. #define P_REF                        39
  92. #define P_COMMA                        40
  93. #define P_SEMICOLON                    41
  94. #define P_COLON                        42
  95. #define P_QUESTIONMARK                43
  96.  
  97. #define P_PARENTHESESOPEN            44
  98. #define P_PARENTHESESCLOSE            45
  99. #define P_BRACEOPEN                    46
  100. #define P_BRACECLOSE                47
  101. #define P_SQBRACKETOPEN                48
  102. #define P_SQBRACKETCLOSE            49
  103. #define P_BACKSLASH                    50
  104.  
  105. #define P_PRECOMP                    51
  106. #define P_DOLLAR                    52
  107.  
  108. // RAVEN BEGIN
  109. #define P_INVERTED_PLING            53
  110. #define P_INVERTED_QUERY            54
  111. // RAVEN END
  112.  
  113. // punctuation
  114. typedef struct punctuation_s
  115. {
  116.     char *p;                        // punctuation character(s)
  117.     int n;                            // punctuation id
  118. } punctuation_t;
  119.  
  120. // RAVEN BEGIN
  121.  
  122. #ifdef LEXER_READ_AHEAD
  123. class LexerIOWrapper {
  124.     idFile *file;
  125.     
  126.     int offset;
  127.     int size;
  128.     char *memory;
  129.  
  130. public:    
  131.     LexerIOWrapper();    
  132.     void InitFromMemory(char const * const ptr, int length);
  133.     bool OpenFile(char const *filename, bool OSPath);
  134.     int Length();    
  135.     int Tell();    
  136.     void Seek( int loc, int mode );    
  137.     void Read( void *dest, int s );    
  138.     void Close();    
  139.     int IsLoaded();
  140. };
  141. #endif
  142.  
  143. class idLexer {
  144.     friend class idParser;
  145.  
  146. public:
  147. // RAVEN END                    
  148.                     // constructor
  149.                     idLexer();
  150.                     idLexer( int flags );
  151.                     idLexer( const char *filename, int flags = 0, bool OSPath = false );
  152.                     idLexer( const char *ptr, int length, const char *name, int flags = 0 );
  153.                     // destructor
  154.                     ~idLexer();
  155.                     // load a script from the given file at the given offset with the given length
  156.     int                LoadFile( const char *filename, bool OSPath = false );
  157.                     // load a script from the given memory with the given length and a specified line offset,
  158.                     // so source strings extracted from a file can still refer to proper line numbers in the file
  159.                     // NOTE: the buffer is expect to be a valid C string: ptr[length] == '\0'
  160.     int                LoadMemory( const char *ptr, int length, const char *name, int startLine = 1 );
  161.                     // free the script
  162.     void            FreeSource( void );
  163.                     // returns true if a script is loaded
  164.     int                IsLoaded( void ) { return idLexer::loaded; }
  165.                     // read a token
  166.     int                ReadToken( idToken *token );
  167.                     // expect a certain token, reads the token when available
  168.     int                ExpectTokenString( const char *string );
  169.                     // expect a certain token type
  170.     int                ExpectTokenType( int type, int subtype, idToken *token );
  171.                     // expect a token
  172.     int                ExpectAnyToken( idToken *token );
  173.                     // returns true when the token is available
  174.     int                CheckTokenString( const char *string );
  175.                     // returns true an reads the token when a token with the given type is available
  176.     int                CheckTokenType( int type, int subtype, idToken *token );
  177.                     // skip tokens until the given token string is read
  178.     int                SkipUntilString( const char *string );
  179.                     // skip the rest of the current line
  180.     int                SkipRestOfLine( void );
  181.                     // skip the braced section
  182.     int                SkipBracedSection( bool parseFirstBrace = true );
  183.                     // unread the given token
  184.     void            UnreadToken( const idToken *token );
  185.                     // read a token only if on the same line
  186.     int                ReadTokenOnLine( idToken *token );
  187.                     //Returns the rest of the current line
  188.     const char*        ReadRestOfLine(idStr& out);
  189.                     // read a signed integer
  190.     int                ParseInt( void );
  191.                     // read a boolean
  192.     bool            ParseBool( void );
  193.                     // read a floating point number.  If errorFlag is NULL, a non-numeric token will
  194.                     // issue an Error().  If it isn't NULL, it will issue a Warning() and set *errorFlag = true
  195.     float            ParseFloat( bool *errorFlag = NULL );
  196.                     // parse matrices with floats
  197.     int                Parse1DMatrix( int x, float *m );
  198. // RAVEN BEGIN
  199. // rjohnson: added vertex color support to proc files.  assume a default RGBA of 0x000000ff
  200.     int                Parse1DMatrixOpenEnded( int MaxCount, float *m );
  201. // RAVEN END
  202.     int                Parse2DMatrix( int y, int x, float *m );
  203.     int                Parse3DMatrix( int z, int y, int x, float *m );
  204.                     // parse a braced section into a string
  205.     const char *    ParseBracedSection( idStr &out );
  206.                     // parse a braced section into a string, maintaining indents and newlines
  207.     const char *    ParseBracedSectionExact ( idStr &out, int tabs = -1 );
  208.                     // parse the rest of the line
  209.     const char *    ParseRestOfLine( idStr &out );
  210.                     // retrieves the white space characters before the last read token
  211.     int                GetLastWhiteSpace( idStr &whiteSpace ) const;
  212.                     // returns start index into text buffer of last white space
  213.     int                GetLastWhiteSpaceStart( void ) const;
  214.                     // returns end index into text buffer of last white space
  215.     int                GetLastWhiteSpaceEnd( void ) const;
  216.                     // set an array with punctuations, NULL restores default C/C++ set, see default_punctuations for an example
  217.     void            SetPunctuations( const punctuation_t *p );
  218.                     // returns a pointer to the punctuation with the given id
  219.     const char *    GetPunctuationFromId( int id );
  220.                     // get the id for the given punctuation
  221.     int                GetPunctuationId( const char *p );
  222.                     // set lexer flags
  223.     void            SetFlags( int flags );
  224.                     // get lexer flags
  225.     int                GetFlags( void );
  226.                     // reset the lexer
  227.     void            Reset( void );
  228.                     // returns true if at the end of the file
  229.     int                EndOfFile( void );
  230.                     // returns the current filename
  231.     const char *    GetFileName( void );
  232.                     // get offset in script
  233.     const int        GetFileOffset( void );
  234.                     // get file time
  235.     const unsigned int GetFileTime( void );
  236.                     // returns the current line number
  237.     const int        GetLineNum( void );
  238.                     // print an error message
  239.     void            Error( const char *str, ... ) id_attribute((format(printf,2,3)));
  240.                     // print a warning message
  241.     void            Warning( const char *str, ... ) id_attribute((format(printf,2,3)));
  242.                     // returns true if Error() was called with LEXFL_NOFATALERRORS or LEXFL_NOERRORS set
  243.     bool            HadError( void ) const;
  244.  
  245.     static void        SetBaseFolder(char const * const);
  246.  
  247. // RAVEN BEGIN
  248.                     // write a binary representation of a token
  249.     void            WriteBinaryToken(idToken *tok);
  250.     static void        WriteBinaryFile(char const * const filename);
  251. // RAVEN END
  252.  
  253. // RAVEN BEGIN
  254. // dluetscher: added method to parse a structure array that is made up of numerics (floats, ints), and stores them in the given storage
  255.     void            ParseNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage );
  256. // RAVEN END
  257.  
  258. private:
  259.     int                loaded;                    // set when a script file is loaded from file or memory
  260.     idStr            filename;                // file name of the script
  261.     bool            allocated;                // true if buffer memory was allocated
  262.     const char *    buffer;                    // buffer containing the script
  263.     const char *    script_p;                // current pointer in the script
  264.     const char *    end_p;                    // pointer to the end of the script
  265.     const char *    lastScript_p;            // script pointer before reading token
  266.     const char *    whiteSpaceStart_p;        // start of last white space
  267.     const char *    whiteSpaceEnd_p;        // end of last white space
  268.     unsigned int    fileTime;                // file time
  269.     int                length;                    // length of the script in bytes
  270.     int                line;                    // current line in script
  271.     int                lastline;                // line before reading token
  272.     int                tokenavailable;            // set by unreadToken
  273.     int                flags;                    // several script flags
  274.     const punctuation_t *punctuations;        // the punctuations used in the script
  275.     int *            punctuationtable;        // ASCII table with punctuations
  276.     int *            nextpunctuation;        // next punctuation in chain
  277.     idToken            token;                    // available token
  278.     idLexer*        next;                    // next script in a chain
  279.     bool            hadError;                // set by idLexer::Error, even if the error is supressed
  280.  
  281. protected:
  282.     static char                baseFolder[256];
  283.  
  284.  
  285. private:
  286.     void            CreatePunctuationTable( const punctuation_t *punctuations );
  287.     int                ReadWhiteSpace( void );
  288.     int                ReadEscapeCharacter( char *ch );
  289.     int                ReadString( idToken *token, int quote );
  290.     int                ReadName( idToken *token );
  291.     int                ReadNumber( idToken *token );
  292.     int                ReadPunctuation( idToken *token );
  293.     int                ReadPrimitive( idToken *token );
  294.     int                CheckString( const char *str ) const;
  295.     int                NumLinesCrossed( void );
  296.  
  297. // RAVEN BEGIN
  298. // jsinger: This is the file that WriteBinaryToken will write to when the proper flags are set
  299.     idFile            *mBinaryFile;
  300. // RAVEN END
  301. };
  302.  
  303. // this class is only necessary to parse binary files
  304. class Lexer {
  305.     friend class idParser;
  306.  
  307. public:
  308.  
  309. #ifdef LEXER_READ_AHEAD    
  310.     static void                BeginLevelLoad();
  311.     static void                EndLevelLoad();
  312. #endif
  313.  
  314.                             // constructors
  315.                             Lexer( const char *filename, int flags = 0, bool OSPath = false );
  316.                             Lexer(int flags=0);
  317.                             Lexer( char const * const ptr, int length, char const * const name, int flags = 0);
  318.  
  319.                             //destructor
  320.                             ~Lexer();
  321.                             // load a script from the given file at the given offset with the given length
  322.     int                        LoadFile( const char *filename, bool OSPath = false );
  323.                             // load a script from the given memory with the given length and a specified line offset,
  324.                             // so source strings extracted from a file can still refer to proper line numbers in the file
  325.                             // NOTE: the buffer is expect to be a valid C string: ptr[length] == '\0'
  326.     int                        LoadMemory( const char *ptr, int length, const char *name, int startLine = 1 );
  327.                             // free the script
  328.     void                    FreeSource( void );
  329.                             // returns true if a script is loaded
  330.     int                        IsLoaded( void );
  331.                             // read a token
  332.     int                        ReadToken( idToken *token );
  333.                             // expect a certain token, reads the token when available
  334.     int                        ExpectTokenString( const char *string );
  335.                             // expect a certain token type
  336.     int                        ExpectTokenType( int type, int subtype, idToken *token );
  337.                             // expect a token
  338.     int                        ExpectAnyToken( idToken *token );
  339.                             // returns true when the token is available
  340.     int                        CheckTokenString( const char *string );
  341.                             // returns true an reads the token when a token with the given type is available
  342.     int                        CheckTokenType( int type, int subtype, idToken *token );
  343.                             // skip tokens until the given token string is read
  344.     int                        SkipUntilString( const char *string );
  345.                             // skip the rest of the current line
  346.     int                        SkipRestOfLine( void );
  347.                             // skip the braced section
  348.     int                        SkipBracedSection( bool parseFirstBrace = true );
  349.                             // unread the given token
  350.     void                    UnreadToken( const idToken *token );
  351.                             // read a token only if on the same line
  352.     int                        ReadTokenOnLine( idToken *token );
  353.                             // read a signed integer
  354.     int                        ParseInt( void );
  355.                             // read a boolean
  356.     bool                    ParseBool( void );
  357.                             // read a floating point number.  If errorFlag is NULL, a non-numeric token will
  358.                             // issue an Error().  If it isn't NULL, it will issue a Warning() and set *errorFlag = true
  359.     float                    ParseFloat( bool *errorFlag = NULL );
  360.                             // parse matrices with floats
  361.     int                        Parse1DMatrix( int x, float *m );
  362.     int                        Parse1DMatrixOpenEnded( int MaxCount, float *m );
  363.     int                        Parse2DMatrix( int y, int x, float *m );
  364.     int                        Parse3DMatrix( int z, int y, int x, float *m );
  365.                             // parse a braced section into a string
  366.     const char *            ParseBracedSection( idStr &out );
  367.                             // parse a braced section into a string, maintaining indents and newlines
  368.     const char *            ParseBracedSectionExact ( idStr &out, int tabs = -1 );
  369.                             // parse the rest of the line
  370.     const char *            ParseRestOfLine( idStr &out );
  371.                             // retrieves the white space characters before the last read token
  372.     int                        GetLastWhiteSpace( idStr &whiteSpace ) const;
  373.                             // returns start index into text buffer of last white space
  374.     int                        GetLastWhiteSpaceStart( void ) const;
  375.                             // returns end index into text buffer of last white space
  376.     int                        GetLastWhiteSpaceEnd( void ) const;
  377.                             // set an array with punctuations, NULL restores default C/C++ set, see default_punctuations for an example
  378.     void                    SetPunctuations( const punctuation_t *p );
  379.                             // returns a pointer to the punctuation with the given id
  380.     const char *            GetPunctuationFromId( int id );
  381.                             // get the id for the given punctuation
  382.     int                        GetPunctuationId( const char *p );
  383.                             // set lexer flags
  384.     void                    SetFlags( int flags );
  385.                             // get lexer flags
  386.     int                        GetFlags( void );
  387.                             // reset the lexer
  388.     void                    Reset( void );
  389.                             // returns true if at the end of the file
  390.     int                        EndOfFile( void );
  391.                             // returns the current filename
  392.     const char *            GetFileName( void );
  393.                             // get offset in script
  394.     const int                GetFileOffset( void );
  395.                             // get file time
  396.     const unsigned int        GetFileTime( void );
  397.                             // returns the current line number
  398.     const int                GetLineNum( void );
  399.                             // print an error message
  400.     void                    Error( const char *str, ... );
  401.                             // print a warning message
  402.     void                    Warning( const char *str, ... );
  403.                             // returns true if Error() was called with LEXFL_NOFATALERRORS or LEXFL_NOERRORS set
  404.     bool                    HadError( void ) const;
  405.  
  406.                             // write a binary representation of a token
  407.     void                    WriteBinaryToken(idToken *tok);
  408.  
  409.     static void                SetBaseFolder(char const * const);
  410.  
  411. // RAVEN BEGIN
  412. // dluetscher: added method to parse a structure array that is made up of numerics (floats, ints), and stores them in the given storage
  413.     void                    ParseNumericStructArray( int numStructElements, int tokenSubTypeStructElements[], int arrayCount, byte *arrayStorage );
  414. // RAVEN END
  415.  
  416.     // suffix that should be appended to the normal file extension to signify that the file is binary
  417.     static idStr const        sCompiledFileSuffix;
  418.  
  419. protected:
  420.     static char                baseFolder[256];
  421.  
  422. private:
  423.     bool                    OpenFile(char const *filename, bool OSPath);
  424.     
  425. #ifdef LEXER_READ_AHEAD
  426.     LexerIOWrapper            mLexerIOWrapper;
  427. #else
  428.     idFile                    *mFile;
  429. #endif
  430.     
  431.     unsigned int            offset;
  432.     idToken                    unreadToken;
  433.     unsigned int            unreadSize;
  434.     bool                    tokenAvailable;
  435.     idLexer                    *mDelegate;
  436.     int                        mFlags;
  437. };
  438.  
  439.  
  440.  
  441. ID_INLINE const char *idLexer::GetFileName( void ) {
  442.     return idLexer::filename;
  443. }
  444.  
  445. ID_INLINE const int idLexer::GetFileOffset( void ) {
  446.     return idLexer::script_p - idLexer::buffer;
  447. }
  448.  
  449. ID_INLINE const unsigned int idLexer::GetFileTime( void ) {
  450.     return idLexer::fileTime;
  451. }
  452.  
  453. ID_INLINE const int idLexer::GetLineNum( void ) {
  454.     return idLexer::line;
  455. }
  456.  
  457. ID_INLINE void idLexer::SetFlags( int flags ) {
  458.     idLexer::flags = flags;
  459. }
  460.  
  461. ID_INLINE int idLexer::GetFlags( void ) {
  462.     return idLexer::flags;
  463. }
  464.  
  465. #endif /* !__LEXER_H__ */
  466.  
  467.