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

📄 parser.cpp

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

            ReadToken ( TOKEN_TYPE_DELIM_CLOSE_BRACE );
        }

        // Add the identifier and size to the symbol table

        if ( AddSymbol ( pstrIdent, iSize, g_iCurrScope, SYMBOL_TYPE_VAR ) == -1 )
            ExitOnCodeError ( "Identifier redefinition" );

        // Read the semicolon

        ReadToken ( TOKEN_TYPE_DELIM_SEMICOLON );
    }

    /******************************************************************************************
    *
    *   ParseHostAPIFuncImport ()
    *
    *   Parses the importing of a host API function.
    *
    *       host <Identifier> ();
    */

    void ParseHost ()
    {
        // Read the host API function name

        ReadToken ( TOKEN_TYPE_IDENT );

        // Add the function to the function table with the host API flag set

        if ( AddFunc ( GetCurrLexeme (), TRUE ) == -1 )
            ExitOnCodeError ( "Function redefinition" );

        // Make sure the function name is followed with ()

        ReadToken ( TOKEN_TYPE_DELIM_OPEN_PAREN );
        ReadToken ( TOKEN_TYPE_DELIM_CLOSE_PAREN );

        // Read the semicolon

        ReadToken ( TOKEN_TYPE_DELIM_SEMICOLON );
    }

    /******************************************************************************************
    *
    *   ParseFunc ()
    *
    *   Parses a function.
    *
    *       func <Identifier> ( <Parameter-List> ) <Statement>
    */

    void ParseFunc ()
    {
        // Make sure we're not already in a function

        if ( g_iCurrScope != SCOPE_GLOBAL )
            ExitOnCodeError ( "Nested functions illegal" );

        // Read the function name

        ReadToken ( TOKEN_TYPE_IDENT );

        // Add the non-host API function to the function table and get its index

        int iFuncIndex = AddFunc ( GetCurrLexeme (), FALSE );

        // Check for a function redefinition

        if ( iFuncIndex == -1 )
            ExitOnCodeError ( "Function redefinition" );

        // Set the scope to the function

        g_iCurrScope = iFuncIndex;

        // Read the opening parenthesis

        ReadToken ( TOKEN_TYPE_DELIM_OPEN_PAREN );
       
        // Use the look-ahead character to determine if the function takes parameters

        if ( GetLookAheadChar () != ')' )
        {   
            // If the function being defined is _Main (), flag an error since _Main ()
            // cannot accept paraemters

            if ( g_ScriptHeader.iIsMainFuncPresent &&
                 g_ScriptHeader.iMainFuncIndex == iFuncIndex )
            {
                ExitOnCodeError ( "_Main () cannot accept parameters" );
            }

            // Start the parameter count at zero

            int iParamCount = 0;

            // Crete an array to store the parameter list locally

            char ppstrParamList [ MAX_FUNC_DECLARE_PARAM_COUNT ][ MAX_IDENT_SIZE ];

            // Read the parameters

            while ( TRUE )
            {
                // Read the identifier

                ReadToken ( TOKEN_TYPE_IDENT );

                // Copy the current lexeme to the parameter list array

                CopyCurrLexeme ( ppstrParamList [ iParamCount ] );

                // Increment the parameter count

                ++ iParamCount;

                // Check again for the closing parenthesis to see if the parameter list is done

                if ( GetLookAheadChar () == ')' )
                    break;

                // Otherwise read a comma and move to the next parameter

                ReadToken ( TOKEN_TYPE_DELIM_COMMA );           
            }

            // Set the final parameter count

            SetFuncParamCount ( g_iCurrScope, iParamCount );

            // Write the parameters to the function's symbol table in reverse order, so they'll
            // be emitted from right-to-left

            while ( iParamCount > 0 )
            {
                -- iParamCount;

                // Add the parameter to the symbol table

                AddSymbol ( ppstrParamList [ iParamCount ], 1, g_iCurrScope, SYMBOL_TYPE_PARAM );
            }
        }

        // Read the closing parenthesis

        ReadToken ( TOKEN_TYPE_DELIM_CLOSE_PAREN );

        // Read the opening curly brace

        ReadToken ( TOKEN_TYPE_DELIM_OPEN_CURLY_BRACE );

        // Parse the function's body

        ParseBlock ();

        // Return to the global scope

        g_iCurrScope = SCOPE_GLOBAL;
    }

    /******************************************************************************************
    *
    *   ParseExpr ()
    *
    *   Parses an expression.
    */

    void ParseExpr ()
    {
        int iInstrIndex;

        // The current operator type

        int iOpType;

        // Parse the subexpression

        ParseSubExpr ();

        // Parse any subsequent relational or logical operators

        while ( TRUE )
        {
            // Get the next token

            if ( GetNextToken () != TOKEN_TYPE_OP ||
                 ( ! IsOpRelational ( GetCurrOp () ) &&
                   ! IsOpLogical ( GetCurrOp () ) ) )
            {
                RewindTokenStream ();
                break;
            }

            // Save the operator

            iOpType = GetCurrOp ();

            // Parse the second term

            ParseSubExpr ();

            // Pop the first operand into _T1

            iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_POP );
            AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar1SymbolIndex );

            // Pop the second operand into _T0

            iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_POP );
            AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar0SymbolIndex );

            // ---- Perform the binary operation associated with the specified operator

            // Determine the operator type

            if ( IsOpRelational ( iOpType ) )
            {
                // Get a pair of free jump target indices

                int iTrueJumpTargetIndex = GetNextJumpTargetIndex (),
                    iExitJumpTargetIndex = GetNextJumpTargetIndex ();

                // It's a relational operator

                switch ( iOpType )
                {
                    // Equal

                    case OP_TYPE_EQUAL:
                    {
                        // Generate a JE instruction

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JE );
                        break;
                    }

                    // Not Equal

                    case OP_TYPE_NOT_EQUAL:
                    {
                        // Generate a JNE instruction

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JNE );
                        break;
                    }

                    // Greater

                    case OP_TYPE_GREATER:
                    {
                        // Generate a JG instruction

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JG );
                        break;
                    }

                    // Less

                    case OP_TYPE_LESS:
                    {
                        // Generate a JL instruction

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JL );
                        break;
                    }

                    // Greater or Equal

                    case OP_TYPE_GREATER_EQUAL:
                    {
                        // Generate a JGE instruction

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JGE );
                        break;
                    }

                    // Less Than or Equal

                    case OP_TYPE_LESS_EQUAL:
                    {
                        // Generate a JLE instruction

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JLE );
                        break;
                    }
                }

                // Add the jump instruction's operands (_T0 and _T1)

                AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar0SymbolIndex );
                AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar1SymbolIndex );
                AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iTrueJumpTargetIndex );

                // Generate the outcome for falsehood

                iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_PUSH );
                AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );

                // Generate a jump past the true outcome

                iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JMP );
                AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iExitJumpTargetIndex );

                // Set the jump target for the true outcome

                AddICodeJumpTarget ( g_iCurrScope, iTrueJumpTargetIndex );

                // Generate the outcome for truth

                iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_PUSH );
                AddIntICodeOp ( g_iCurrScope, iInstrIndex, 1 );

                // Set the jump target for exiting the operand evaluation

                AddICodeJumpTarget ( g_iCurrScope, iExitJumpTargetIndex );
            }
            else
            {
                // It must be a logical operator

                switch ( iOpType )
                {
                    // And

                    case OP_TYPE_LOGICAL_AND:
                    {
                        // Get a pair of free jump target indices

                        int iFalseJumpTargetIndex = GetNextJumpTargetIndex (),
                            iExitJumpTargetIndex = GetNextJumpTargetIndex ();

                        // JE _T0, 0, True

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JE );
                        AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar0SymbolIndex );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );
                        AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iFalseJumpTargetIndex );

                        // JE _T1, 0, True

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JE );
                        AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar1SymbolIndex );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );
                        AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iFalseJumpTargetIndex );

                        // Push 1

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_PUSH );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 1 );

                        // Jmp Exit

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JMP );
                        AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iExitJumpTargetIndex );

                        // L0: (False)

                        AddICodeJumpTarget ( g_iCurrScope, iFalseJumpTargetIndex );

                        // Push 0

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_PUSH );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );

                        // L1: (Exit)

                        AddICodeJumpTarget ( g_iCurrScope, iExitJumpTargetIndex );

                        break;
                    }

                    // Or

                    case OP_TYPE_LOGICAL_OR:
                    {
                        // Get a pair of free jump target indices

                        int iTrueJumpTargetIndex = GetNextJumpTargetIndex (),
                            iExitJumpTargetIndex = GetNextJumpTargetIndex ();

                        // JNE _T0, 0, True

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JNE );
                        AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar0SymbolIndex );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );
                        AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iTrueJumpTargetIndex );

                        // JNE _T1, 0, True

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JNE );
                        AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar1SymbolIndex );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );
                        AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iTrueJumpTargetIndex );

                        // Push 0

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_PUSH );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 0 );

                        // Jmp Exit

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_JMP );
                        AddJumpTargetICodeOp ( g_iCurrScope, iInstrIndex, iExitJumpTargetIndex );

                        // L0: (True)

                        AddICodeJumpTarget ( g_iCurrScope, iTrueJumpTargetIndex );

                        // Push 1

                        iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_PUSH );
                        AddIntICodeOp ( g_iCurrScope, iInstrIndex, 1 );

                        // L1: (Exit)

                        AddICodeJumpTarget ( g_iCurrScope, iExitJumpTargetIndex );

                        break;
                    }
                }
            }
        }
    }

    /******************************************************************************************
    *
    *   ParseSubExpr ()
    *
    *   Parses a sub expression.
    */

    void ParseSubExpr ()
    {
        int iInstrIndex;

        // The current operator type

        int iOpType;

        // Parse the first term

        ParseTerm (); 

        // Parse any subsequent +, - or $ operators

        while ( TRUE )
        {
            // Get the next token

            if ( GetNextToken () != TOKEN_TYPE_OP ||
                 ( GetCurrOp () != OP_TYPE_ADD &&
                   GetCurrOp () != OP_TYPE_SUB &&
                   GetCurrOp () != OP_TYPE_CONCAT ) )
            {
                RewindTokenStream ();
                break;
            }

            // Save the operator

            iOpType = GetCurrOp ();

            // Parse the second term

            ParseTerm ();

            // Pop the first operand into _T1

            iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_POP );
            AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar1SymbolIndex );

            // Pop the second operand into _T0

            iInstrIndex = AddICodeInstr ( g_iCurrScope, INSTR_POP );
            AddVarICodeOp ( g_iCurrScope, iInstrIndex, g_iTempVar0SymbolIndex );

            // Perform the binary operation associated with the specified operator

            int iOpInstr;
            switch ( iOpType )
            {
                // Binary addition

                case OP_TYPE_ADD:
                    iOpInstr = INSTR_ADD;
                    break;

                // Binary subtraction

                case OP_TYPE_SUB:
                    iOpInstr = INSTR_SUB;
                    break;

                // Binary string concatenation

                case OP_TYPE_CONCAT:
                    iOpInstr = INSTR_CONCAT;
                    break;
            }
            iInstrIndex = AddICodeInstr ( g_iCurrScope, iOpInstr );

⌨️ 快捷键说明

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