⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexer.cpp

📁 < Game Script Mastery>> source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    }

                    // If it's an escape sequence, switch to the escape state and don't add the
                    // backslash to the lexeme

                    else if ( cCurrChar == '\\' )
                    {
                        iAddCurrChar = FALSE;
                        iCurrLexState = LEX_STATE_STRING_ESCAPE;
                    }

                    // Anything else gets added to the string

                    break;

                // Escape sequence

                case LEX_STATE_STRING_ESCAPE:

                    // Immediately switch back to the string state, now that the character's
                    // been added

                    iCurrLexState = LEX_STATE_STRING;

                    break;

                // String closing quote

                case LEX_STATE_STRING_CLOSE_QUOTE:

                    // Finish the string lexeme

                    iAddCurrChar = FALSE;
                    iLexemeDone = TRUE;

                    break;
            }

            // Add the next character to the lexeme and increment the index

            if ( iAddCurrChar )
            {
                g_CurrLexerState.pstrCurrLexeme [ iNextLexemeCharIndex ] = cCurrChar;
                ++ iNextLexemeCharIndex;
            }

            // If the lexeme is complete, exit the loop

            if ( iLexemeDone )
                break;
        }

        // Complete the lexeme string

        g_CurrLexerState.pstrCurrLexeme [ iNextLexemeCharIndex ] = '\0';

        // Retract the lexeme end index by one

        -- g_CurrLexerState.iCurrLexemeEnd;

        // Determine the token type

        Token TokenType;
        switch ( iCurrLexState )
        {
            // Unknown

            case LEX_STATE_UNKNOWN:
                TokenType = TOKEN_TYPE_INVALID;
                break;

            // Integer

            case LEX_STATE_INT:
                TokenType = TOKEN_TYPE_INT;
                break;

            // Float

            case LEX_STATE_FLOAT:
                TokenType = TOKEN_TYPE_FLOAT;
                break;

            // Identifier/Reserved Word

            case LEX_STATE_IDENT:

                // Set the token type to identifier in case none of the reserved words match

                TokenType = TOKEN_TYPE_IDENT;

                // ---- Determine if the "identifier" is actually a reserved word

                // var/var []

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "var" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_VAR;

                // true

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "true" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_TRUE;

                // false

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "false" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_FALSE;

                // if

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "if" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_IF;

                // else

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "else" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_ELSE;

                // break

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "break" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_BREAK;

                // continue

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "continue" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_CONTINUE;

                // for

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "for" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_FOR;

                // while

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "while" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_WHILE;

                // func

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "func" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_FUNC;

                // return

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "return" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_RETURN;

                // host

                if ( stricmp ( g_CurrLexerState.pstrCurrLexeme, "host" ) == 0 )
                    TokenType = TOKEN_TYPE_RSRVD_HOST;

                break;

            // Delimiter

            case LEX_STATE_DELIM:

                // Determine which delimiter was found

                switch ( g_CurrLexerState.pstrCurrLexeme [ 0 ] )
                {
                    case ',':
                        TokenType = TOKEN_TYPE_DELIM_COMMA;
                        break;

                    case '(':
                        TokenType = TOKEN_TYPE_DELIM_OPEN_PAREN;
                        break;

                    case ')':
                        TokenType = TOKEN_TYPE_DELIM_CLOSE_PAREN;
                        break;

                    case '[':
                        TokenType = TOKEN_TYPE_DELIM_OPEN_BRACE;
                        break;

                    case ']':
                        TokenType = TOKEN_TYPE_DELIM_CLOSE_BRACE;
                        break;

                    case '{':
                        TokenType = TOKEN_TYPE_DELIM_OPEN_CURLY_BRACE;
                        break;

                    case '}':
                        TokenType = TOKEN_TYPE_DELIM_CLOSE_CURLY_BRACE;
                        break;

                    case ';':
                        TokenType = TOKEN_TYPE_DELIM_SEMICOLON;
                        break;
                }
                
                break;

            // Operators

            case LEX_STATE_OP:
                TokenType = TOKEN_TYPE_OP;
                break;

            // Strings

            case LEX_STATE_STRING_CLOSE_QUOTE:
                TokenType = TOKEN_TYPE_STRING;
                break;

            // All that's left is whitespace, which means the end of the stream

            default:
                TokenType = TOKEN_TYPE_END_OF_STREAM;
        }

        // Return the token type and set the global copy

        g_CurrLexerState.CurrToken = TokenType;
        return TokenType;
    }

    /******************************************************************************************
    *
    *   RewindTokenStream ()
    *
    *   Moves the lexer back one token.
    */

    void RewindTokenStream ()
    {
        CopyLexerState ( g_CurrLexerState, g_PrevLexerState );
    }

    /******************************************************************************************
    *
    *   GetCurrToken ()
    *
    *   Returns the current token.
    */

    Token GetCurrToken ()
    {
        return g_CurrLexerState.CurrToken;
    }

    /******************************************************************************************
    *
    *   GetCurrLexeme ()
    *
    *   Returns a pointer to the current lexeme.
    */

    char * GetCurrLexeme ()
    {
        return g_CurrLexerState.pstrCurrLexeme;
    }

    /******************************************************************************************
    *
    *   CopyCurrLexeme ()
    *
    *   Makes a physical copy of the current lexeme into the specified string buffer.
    */

    void CopyCurrLexeme ( char * pstrBuffer )
    {
        strcpy ( pstrBuffer, g_CurrLexerState.pstrCurrLexeme );
    }

    /******************************************************************************************
    *
    *   GetCurrOp ()
    *
    *   Returns the current operator.
    */

    int GetCurrOp ()
    {
        return g_CurrLexerState.iCurrOp;
    }

    /******************************************************************************************
    *
    *   GetLookAheadChar ()
    *
    *   Returns the first character of the next token.
    */

    char GetLookAheadChar ()
    {
        // Save the current lexer state

        LexerState PrevLexerState;
        CopyLexerState ( PrevLexerState, g_CurrLexerState );

        // Skip any whitespace that may exist and return the first non-whitespace character

        char cCurrChar;
        while ( TRUE )
        {
            cCurrChar = GetNextChar ();
            if ( ! IsCharWhitespace ( cCurrChar ) )
                break;
        }

        // Restore the lexer state

        CopyLexerState ( g_CurrLexerState, PrevLexerState );

        // Return the look-ahead character

        return cCurrChar;
    }

    /******************************************************************************************
    *
    *   GetCurrSourceLine ()
    *
    *   Returns a pointer to the current source line string.
    */

    char * GetCurrSourceLine ()
    {
        if ( g_CurrLexerState.pCurrLine )
            return ( char * ) g_CurrLexerState.pCurrLine->pData;
        else
            return NULL;
    }

    /******************************************************************************************
    *
    *   GetCurrSourceLineIndex ()
    *
    *   Returns the current source line number.
    */

    int GetCurrSourceLineIndex ()
    {
        return g_CurrLexerState.iCurrLineIndex;
    }

    /******************************************************************************************
    *
    *   GetLexemeStartIndex ()
    *
    *   Returns the pointer to the start of the current lexeme
    */

    int GetLexemeStartIndex ()
    {
        return g_CurrLexerState.iCurrLexemeStart;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -