private void SecondParse()
    {
        Token token = null;

        while ((token = lexer.NextToken()).type != TokenType.EOF)
        {
//            Console.WriteLine ( token );

            switch (token.type)
            {
            case TokenType.FUNC:

                isFuncActive      = true;
                currentFunc       = script.funcTable.GetFuncByName(lexer.NextToken().value);
                currentParamIndex = 0;
                break;

            case TokenType.CLOSE_BRACE:

                isFuncActive = false;
                if (currentFunc.name == XASMLexer.Keyworkd_Main)
                {
                    script.instrStream.instrs [instrStreamSize].opCode  = OpCode.Exit;
                    script.instrStream.instrs [instrStreamSize].opCount = 1;
                    script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                        type = OpType.INT, intLiteral = 0
                    });
                }
                else
                {
                    script.instrStream.instrs [instrStreamSize].opCode  = OpCode.Ret;
                    script.instrStream.instrs [instrStreamSize].opCount = 0;
                    script.instrStream.instrs [instrStreamSize].opList  = null;
                }

//					Console.WriteLine ( $"添加 {script.instrStream.instrs [ instrStreamSize ]} {instrStreamSize} {lexer.LexerPosition}" );

                instrStreamSize++;
                break;

            case TokenType.PARAM:

                var paramNameToken = lexer.NextToken();
                int stackIndex     = -(currentFunc.localDataSize + 2 + (currentParamIndex + 1));                       // +2 因为从-2 开始(-1保留) +1 因为参数在返回地址的下面

                if (script.symbolTable.AddSymbol(paramNameToken.value, 1, stackIndex, currentFunc.index) == -1)
                {
                    throw new SyntaxError(
                              string.Format(Messages.ERROR_MSG_FUNC_PARAM_DUPLICATE_DEFINITION,
                                            paramNameToken.value), token.span.Start.Line, token.span.Start.Column);
                }

                currentParamIndex++;
                break;

            case TokenType.INSTR:

                InstrLookup currentInstrLookup = null;
                if (!instrLookupTable.GetInstrByMnemonic(token.value, out currentInstrLookup))
                {
                    throw new SyntaxError(
                              string.Format(Messages.ERROR_MSG_INSTR_NOT_FOUND,
                                            token.value), token.span.Start.Line, token.span.Start.Column);
                }

                script.instrStream.instrs [instrStreamSize].opCode  = currentInstrLookup.opCode;
                script.instrStream.instrs [instrStreamSize].opCount = currentInstrLookup.opCount;

                for (int i = 0; i < currentInstrLookup.opCount; i++)
                {
                    OpFlagType currentOpFlagType = currentInstrLookup.opList [i];

                    Token instrParamToken = lexer.NextToken();
//						Console.WriteLine ( $"指令参数{i}: {instrParamToken}" );
                    switch (instrParamToken.type)
                    {
                    case TokenType.INT:

                        if ((currentOpFlagType & OpFlagType.INT) == OpFlagType.INT)
                        {
                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.INT, intLiteral = int.Parse(instrParamToken.value)
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.FLOAT:

                        if ((currentOpFlagType & OpFlagType.FLOAT) == OpFlagType.FLOAT)
                        {
                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.FLOAT, floatLiteral = float.Parse(instrParamToken.value)
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.STRING:

                        if ((currentOpFlagType & OpFlagType.STRING) == OpFlagType.STRING)
                        {
                            int stringTableIdx = script.stringTable.AddString(instrParamToken.value);

                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.STRING, stringTableIndex = stringTableIdx
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.REG_RETVAL:

                        if ((currentOpFlagType & OpFlagType.REG) == OpFlagType.REG)
                        {
                            script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                type = OpType.REG, reg = 0
                            });
                        }
                        else
                        {
                            throw new SyntaxError(
                                      string.Format(Messages.ERROR_MSG_INSTR_WRONG_PARAM,
                                                    token.value, i, instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        }
                        break;

                    case TokenType.IDENT:

                        if ((currentOpFlagType & OpFlagType.FUNC_NAME) == OpFlagType.FUNC_NAME)
                        {
                            FuncNode func = script.funcTable.GetFuncByName(instrParamToken.value);

                            if (func != null)
                            {
                                script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                    type = OpType.FUNC_INDEX, funcIndex = func.index
                                });
                            }
                            else
                            {
                                throw new SyntaxError(
                                          string.Format(Messages.ERROR_MSG_FUNC_NOT_FOUND,
                                                        instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                            }
                        }

                        if ((currentOpFlagType & OpFlagType.LINE_LABEL) == OpFlagType.LINE_LABEL)
                        {
                            LabelNode labelNode = script.labelTable.GetLabelByIdent(instrParamToken.value, currentFunc.index);

                            if (labelNode != null)
                            {
                                script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                    type = OpType.INSTR_INDEX, instrIndex = labelNode.targetIndex
                                });
                            }
                            else
                            {
                                throw new SyntaxError(
                                          string.Format(Messages.ERROR_MSG_LABEL_NOT_FOUND,
                                                        instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                            }
                        }

                        if ((currentOpFlagType & OpFlagType.MEM_REF) == OpFlagType.MEM_REF)
                        {
                            SymbolNode symbolNode = script.symbolTable.GetSymbolByIdent(instrParamToken.value, currentFunc.index);

                            // 如果该变量不是函数作用域内定义的,则查找全局变量
                            if (symbolNode == null)
                            {
                                symbolNode = script.symbolTable.GetSymbolByIdent(instrParamToken.value, -1);
                            }
                            if (symbolNode == null)
                            {
                                throw new SyntaxError(
                                          string.Format(Messages.ERROR_MSG_VAR_NOT_FOUND,
                                                        instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                            }

                            int  baseIndex      = symbolNode.stackIndex;
                            char symbolNextChar = lexer.PeekChar(1);

                            if (symbolNextChar != char.MinValue)
                            {
                                // 非数组成员
                                if (symbolNextChar != XASMLexer.Open_Bracket)
                                {
                                    // 验证非数组定义
                                    if (symbolNode.size > 1)
                                    {
                                        throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_START_ERROR, token.span.Start.Line,
                                                              token.span.Start.Column);
                                    }

                                    script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                        type = OpType.ABS_STACK_INDEX, stackIndex = baseIndex
                                    });
                                }
                                else
                                {
                                    // 验证数组定义
                                    if (symbolNode.size <= 1)
                                    {
                                        throw new SyntaxError(
                                                  string.Format(Messages.ERROR_MSG_VAR_TYPE_IS_NOT_A_ARRAY,
                                                                instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                    }

                                    // 左中括号
                                    lexer.NextToken();

                                    // 数组索引参数
                                    Token arrayIndexParamToken = lexer.NextToken();

                                    // 数组索引是常数
                                    if (arrayIndexParamToken.type == TokenType.INT)
                                    {
                                        int offset = int.Parse(arrayIndexParamToken.value);
                                        if (offset >= symbolNode.size)
                                        {
                                            throw new SyntaxError(
                                                      string.Format(Messages.ERROR_MSG_INDEX_OUT_OF_BOUNDS,
                                                                    arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                        }

                                        script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                            type = OpType.ABS_STACK_INDEX, stackIndex = baseIndex >= 0 ? baseIndex + offset : baseIndex - offset
                                        });
                                    }

                                    // 数组索引是变量
                                    else if (arrayIndexParamToken.type == TokenType.IDENT)
                                    {
                                        SymbolNode offsetSymbolNode = script.symbolTable.GetSymbolByIdent(arrayIndexParamToken.value, currentFunc.index);

                                        // 如果该变量不是函数作用域内定义的,则查找全局变量
                                        if (offsetSymbolNode == null)
                                        {
                                            symbolNode = script.symbolTable.GetSymbolByIdent(arrayIndexParamToken.value, -1);
                                        }
                                        if (offsetSymbolNode == null)
                                        {
                                            throw new SyntaxError(
                                                      string.Format(Messages.ERROR_MSG_VAR_NOT_FOUND,
                                                                    arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                        }

                                        // 不支持数组作为数组的索引
                                        if (offsetSymbolNode.size > 1)
                                        {
                                            throw new SyntaxError(
                                                      string.Format(Messages.ERROR_MSG_VAR_ARRAY_INDEX_TYPE_NOT_SUPPORT,
                                                                    arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                        }

                                        script.instrStream.instrs [instrStreamSize].opList.Add(new Op {
                                            type = OpType.REL_STACK_INDEX, stackIndex = offsetSymbolNode.stackIndex
                                        });

                                        // 右中括号
                                        if (lexer.NextToken().type != TokenType.CLOSE_BRACKET)
                                        {
                                            throw new SyntaxError(Messages.ERROR_MSG_VAR_ARRAY_END_ERROR, token.span.Start.Line,
                                                                  token.span.Start.Column);
                                        }
                                    }
                                    else
                                    {
                                        throw new SyntaxError(
                                                  string.Format(Messages.ERROR_MSG_VAR_ARRAY_INDEX_TYPE_NOT_SUPPORT,
                                                                arrayIndexParamToken.value), token.span.Start.Line, token.span.Start.Column);
                                    }
                                }
                            }
                            else
                            {
                                throw new SyntaxError(Messages.ERROR_MSG_INVALID_TOKEN, token.span.Start.Line,
                                                      token.span.Start.Column);
                            }
                        }

                        break;

                    default:

                        throw new SyntaxError(
                                  string.Format(Messages.ERROR_MSG_INVALID_PARAM_TYPE,
                                                instrParamToken.value), token.span.Start.Line, token.span.Start.Column);
                        break;
                    }

                    // 指令参数之间的逗号分隔符
                    if (i < currentInstrLookup.opCount - 1)
                    {
                        if (lexer.NextToken().type != TokenType.COMMA)
                        {
                            throw new SyntaxError(Messages.ERROR_MSG_INSTR_PARAM_MISS_COMMA, token.span.Start.Line, token.span.Start.Column);
                        }
                    }
                }

                // 每条指令以换行符结束
                if (lexer.NextToken().type != TokenType.NEWLINE)
                {
                    throw new SyntaxError(Messages.ERROR_MSG_INSTR_END_MISMATCH, token.span.Start.Line, token.span.Start.Column);
                }

//					Console.WriteLine ( $"添加 {script.instrStream.instrs [ instrStreamSize ]} {instrStreamSize} {lexer.LexerPosition}" );

                instrStreamSize++;
                break;    // End Of TokenType.INSTR
            }             // End Of switch ( token.Type )

            // SkipToNextLine???
        }               // End Of While
    }
 public static void SetOpType(int instrIndex, int opIndex, OpFlagType opFlagType)
 {
     instrTable [instrIndex].opList [opIndex] = opFlagType;
 }