private string InterpretFactor(TreeNode node)
        {
            var temp = SymbolTable.GetTempSymbol().Name;

            switch (node.LeftNode.DataType)
            {
            case TokenType.PlusPlus:
                Codes.AddLast(isVar
                        ? new Quadruple(InstructionType.Plus, InterpretExp(node.MiddleNode), "1",
                                        InterpretExp(node.MiddleNode), Line)
                        : new Quadruple(InstructionType.Plus, InterpretExp(node.MiddleNode), "1", temp, Line));
                break;

            case TokenType.MinusMinus:
                Codes.AddLast(isVar
                        ? new Quadruple(InstructionType.Minus, InterpretExp(node.MiddleNode), "1",
                                        InterpretExp(node.MiddleNode), Line)
                        : new Quadruple(InstructionType.Minus, InterpretExp(node.MiddleNode), "1", temp, Line));
                break;

            case TokenType.Not:
                Codes.AddLast(new Quadruple(InstructionType.Not, InterpretExp(node.MiddleNode), null, temp, Line));
                break;

            case TokenType.Plus:
                Codes.AddLast(new Quadruple(InstructionType.Plus, "0", InterpretExp(node.MiddleNode), temp, Line));
                break;

            case TokenType.Minus:
                Codes.AddLast(new Quadruple(InstructionType.Minus, "0", InterpretExp(node.MiddleNode), temp, Line));
                break;

            default:
                if (node.MiddleNode.DataType == TokenType.PlusPlus)
                {
                    var targetNode = node.LeftNode;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, InterpretExp(targetNode), null, temp, Line));
                    Line++;
                    if (isVar)
                    {
                        Codes.AddLast(new Quadruple(InstructionType.Plus, InterpretExp(targetNode), "1", InterpretExp(targetNode), Line));
                    }
                    break;
                }
                else if (node.MiddleNode.DataType == TokenType.MinusMinus)
                {
                    var targetNode = node.LeftNode;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, InterpretExp(targetNode), null, temp, Line));
                    Line++;
                    if (isVar)
                    {
                        Codes.AddLast(new Quadruple(InstructionType.Minus, InterpretExp(targetNode), "1", InterpretExp(targetNode), Line));
                    }
                    break;
                }
                throw new InterpretException("ERROR : 因式表达式非法.\n");
            }
            Line++;
            return(temp);
        }
        private void InterpretPrintStmt(TreeNode node)
        {
            var instruction = new Quadruple(InstructionType.Print, null, null, InterpretExp(node.LeftNode), Line);

            Codes.AddLast(instruction);
            Line++;
        }
        private void InterpretScanStmt(TreeNode node)
        {
            var targetNode = node.LeftNode.LeftNode;
            var type       = SymbolTable.FindSymbol(targetNode.Value).Type;

            switch (type)
            {
            case SymbolType.IntValue:
            case SymbolType.RealValue:
            case SymbolType.CharValue:
                Codes.AddLast(new Quadruple(InstructionType.Scan, null, null, targetNode.Value, Line));
                Line++;
                break;

            case SymbolType.IntArray:
            case SymbolType.RealArray:
            case SymbolType.CharArray:
                Codes.AddLast(new Quadruple(InstructionType.Scan, null, null, $"{targetNode.Value}{InterpretArrayDim(node.LeftNode.MiddleNode, out var dim)}", Line));
                Line++;
                break;

            default:
                throw new InterpretException("Error : 输入语句有误.\n");
            }
        }
        private void InterpretELseStmt(TreeNode node, Quadruple jump, LinkedList <Quadruple> breakCode)
        {
            var elseJump = new Quadruple(InstructionType.Jump, null, null, null, Line);

            Codes.AddLast(elseJump);
            Line++;
            jump.Third = (Line + 1).ToString();
            if (node.LeftNode.Type != StmtType.StmtBlock)
            {
                Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line));
                Line++;
                var table = new SymbolTable();
                Level++;
                InterpretStmt(node.LeftNode, breakCode);
                Level--;
                SymbolTable.DeRegister();
                Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line));
                Line++;
            }
            else
            {
                InterpretStmt(node.LeftNode, breakCode);
            }
            elseJump.Third = (Line + 1).ToString();
        }
        private string InterpretAssignExp(TreeNode node)
        {
            var str = InterpretExp(node.LeftNode);

            if (!isVar)
            {
                throw new InterpretException("ERROR : 赋值表达式左值应该为变量.\n");
            }
            var temp = SymbolTable.GetTempSymbol().Name;

            if (node.MiddleNode != null)
            {
                switch (node.MiddleNode.LeftNode.DataType)
                {
                case TokenType.Assign:
                    Codes.AddLast(new Quadruple(InstructionType.Assign, InterpretExp(node.MiddleNode.MiddleNode), null, str, Line));
                    break;

                case TokenType.PlusAssign:
                    Codes.AddLast(new Quadruple(InstructionType.Plus, str, InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    Line++;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, temp, null, str, Line));
                    break;

                case TokenType.MinusAssign:
                    Codes.AddLast(new Quadruple(InstructionType.Minus, str, InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    Line++;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, temp, null, str, Line));
                    break;

                case TokenType.MulAssign:
                    Codes.AddLast(new Quadruple(InstructionType.Mul, str, InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    Line++;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, temp, null, str, Line));
                    break;

                case TokenType.DivAssign:
                    Codes.AddLast(new Quadruple(InstructionType.Div, str, InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    Line++;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, temp, null, str, Line));
                    break;

                case TokenType.ModAssign:
                    Codes.AddLast(new Quadruple(InstructionType.Mod, str, InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    Line++;
                    Codes.AddLast(new Quadruple(InstructionType.Assign, temp, null, str, Line));
                    break;

                default:
                    throw new InterpretException("ERROR : 赋值表达式非法.\n");
                }
                Line++;
            }
            return(str);
        }
        private string InterpretTerm(TreeNode node)
        {
            var temp = SymbolTable.GetTempSymbol().Name;

            if (node.MiddleNode != null)
            {
                switch (node.MiddleNode.LeftNode.DataType)
                {
                case TokenType.Mul:
                    Codes.AddLast(new Quadruple(InstructionType.Mul, InterpretExp(node.LeftNode), InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    break;

                case TokenType.Div:
                    Codes.AddLast(new Quadruple(InstructionType.Div, InterpretExp(node.LeftNode), InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    break;

                case TokenType.Mod:
                    Codes.AddLast(new Quadruple(InstructionType.Mod, InterpretExp(node.LeftNode), InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                    break;

                default:
                    throw new InterpretException("ERROR : 算术运算非法.\n");
                }
                Line++;
                node = node.MiddleNode;
            }

            while (node.RightNode != null)
            {
                var tempN = temp;
                temp = SymbolTable.GetTempSymbol().Name;
                switch (node.RightNode.LeftNode.DataType)
                {
                case TokenType.Mul:
                    Codes.AddLast(new Quadruple(InstructionType.Mul, tempN, InterpretExp(node.RightNode.MiddleNode), temp, Line));
                    break;

                case TokenType.Div:
                    Codes.AddLast(new Quadruple(InstructionType.Div, tempN, InterpretExp(node.RightNode.MiddleNode), temp, Line));
                    break;

                case TokenType.Mod:
                    Codes.AddLast(new Quadruple(InstructionType.Mod, tempN, InterpretExp(node.RightNode.MiddleNode), temp, Line));
                    break;

                default:
                    throw new InterpretException("ERROR : 算术运算非法.\n");
                }
                Line++;
                node = node.RightNode;
            }
            return(temp);
        }
        private string InterpretExp(TreeNode node)
        {
            isVar = false;
            if (node.Type == StmtType.Exp)
            {
                switch (node.DataType)
                {
                case TokenType.AdditiveExp:
                    return(InterpretAdditiveExp(node));

                case TokenType.AssignExp:
                    return(InterpretAssignExp(node));

                case TokenType.LogicOrExp:
                    return(InterpretLogicOrExp(node));

                case TokenType.LogicAndExp:
                    return(InterpretLogicAndExp(node));

                case TokenType.CompExp:
                    return(InterpretCompExp(node));

                case TokenType.CompEqExp:
                    return(InterpretCompEqExp(node));

                default:
                    throw new InterpretException("ERROR : 复合表达式非法.\n");
                }
            }
            if (node.Type == StmtType.Term)
            {
                return(InterpretTerm(node));
            }
            if (node.Type == StmtType.Factor)
            {
                return(InterpretFactor(node));
            }
            if (node.Type == StmtType.Var)
            {
                isVar = true;
                return(InterpretVariable(node));
            }

            if (node.Type == StmtType.Value || node.Type == StmtType.Null)
            {
                var temp = SymbolTable.GetTempSymbol().Name;
                Codes.AddLast(new Quadruple(InstructionType.Assign, $"{node.Value}", null, temp, Line));
                Line++;
                return(temp);
            }
            throw new InterpretException("ERROR : 表达式非法.\n");
        }
        private void InterpretWhileStmt(TreeNode node)
        {
            isRepeat = true;
            var jumpLine    = Line + 1;
            var instruction = new Quadruple(InstructionType.Jump, InterpretExp(node.LeftNode), null, null, Line);

            Codes.AddLast(instruction);
            Line++;
            inPos.AddLast(Line);
            var breakCode = new LinkedList <Quadruple>();

            if (node.MiddleNode != null)
            {
                if (node.MiddleNode.Type != StmtType.StmtBlock)
                {
                    Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line));
                    Line++;
                    var table = new SymbolTable();
                    Level++;
                    InterpretStmt(node.MiddleNode, breakCode);
                    Level--;
                    SymbolTable.DeRegister();
                    Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line));
                    Line++;
                }
                else
                {
                    InterpretStmt(node.MiddleNode, breakCode);
                }
            }
            Codes.AddLast(new Quadruple(InstructionType.Jump, null, null, jumpLine.ToString(), Line));
            Line++;
            outPos.AddLast(Line + 1);
            if (breakCode != null)
            {
                foreach (var c in breakCode)
                {
                    c.Third = (Line + 1).ToString();
                }
            }
            instruction.Third = (Line + 1).ToString();
            outPos.RemoveLast();
            inPos.RemoveLast();
            if (Level == 0)
            {
                isRepeat = false;
            }
        }
        private void InterpretStmtBlock(TreeNode node, LinkedList <Quadruple> breakCode)
        {
            Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line));
            Line++;
            Level++;
            var table = new SymbolTable();

            if (node.LeftNode != null)
            {
                InterpretStmtSeq(node.LeftNode, breakCode);
            }
            SymbolTable.DeRegister();
            Level--;
            Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line));
            Line++;
        }
        private void InterpretIfStmt(TreeNode node, LinkedList <Quadruple> breakCode)
        {
            var jump = new Quadruple(InstructionType.Jump, InterpretExp(node.LeftNode), null, null, Line);

            Codes.AddLast(jump);
            Line++;
            if (node.MiddleNode != null)
            {
                if (node.MiddleNode.Type == StmtType.ElseStmt)
                {
                    Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line));
                    Line++;
                    Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line));
                    Line++;
                    InterpretELseStmt(node, jump, breakCode);
                }
                else
                {
                    if (node.MiddleNode.LeftNode.Type != StmtType.StmtBlock)
                    {
                        Codes.AddLast(new Quadruple(InstructionType.In, null, null, null, Line));
                        Line++;
                        var table = new SymbolTable();
                        Level++;
                        InterpretStmt(node.MiddleNode.LeftNode, breakCode);
                        Level--;
                        SymbolTable.DeRegister();
                        Codes.AddLast(new Quadruple(InstructionType.Out, null, null, null, Line));
                        Line++;
                    }
                    else
                    {
                        InterpretStmt(node.MiddleNode.LeftNode, breakCode);
                    }
                    jump.Third = (Line + 1).ToString();
                    if (node.MiddleNode.MiddleNode != null)
                    {
                        InterpretELseStmt(node.MiddleNode.MiddleNode, jump, breakCode);
                    }
                }
            }
            else
            {
                jump.Third = (Line + 1).ToString();
            }
        }
 private void InterpretJumpStmt(TreeNode node, out Quadruple jump)
 {
     if (!isRepeat)
     {
         throw new InterpretException("ERROR : 跳转语句需要在循环体内.\n");
     }
     jump = new Quadruple(InstructionType.Jump, null, null, null, Line);
     if (node.DataType == TokenType.Break)
     {
         jump.Second = "break";
         jump.Third  = outPos.Last.Value.ToString();
     }
     else if (node.DataType == TokenType.Continue)
     {
         jump.Second = "continue";
         jump.Third  = inPos.Last.Value.ToString();
     }
     Codes.AddLast(jump);
     Line++;
 }
        private string InterpretLogicAndExp(TreeNode node)
        {
            var temp = SymbolTable.GetTempSymbol().Name;

            if (node.MiddleNode != null)
            {
                if (node.MiddleNode.LeftNode.DataType == TokenType.And)
                {
                    Codes.AddLast(new Quadruple(InstructionType.And, InterpretExp(node.LeftNode),
                                                InterpretExp(node.MiddleNode.MiddleNode), temp, Line));
                }
                else
                {
                    throw new InterpretException("ERROR : 逻辑运算非法.\n");
                }

                Line++;
                node = node.MiddleNode;
            }

            while (node.RightNode != null)
            {
                var tempN = temp;
                temp = SymbolTable.GetTempSymbol().Name;
                if (node.RightNode.LeftNode.DataType == TokenType.And)
                {
                    Codes.AddLast(new Quadruple(InstructionType.And, tempN, InterpretExp(node.RightNode.MiddleNode),
                                                temp, Line));
                }
                else
                {
                    throw new InterpretException("ERROR : 逻辑运算非法.\n");
                }

                Line++;
                node = node.RightNode;
            }
            return(temp);
        }
        private void InterpretDecVariable(TreeNode node, int type, SymbolList table)
        {
            var variable = node;

            if (variable.MiddleNode == null)
            {
                string value = null;
                if (variable.RightNode != null)
                {
                    value = InterpretExp(variable.RightNode.MiddleNode);
                }

                if (type == TokenType.Int)
                {
                    Codes.AddLast(new Quadruple(InstructionType.Int, value, null, variable.LeftNode.Value, Line));
                    Line++;
                    var symbol = new Symbol(variable.LeftNode.Value, SymbolType.IntValue, Level);
                    SymbolTable.Register(symbol);
                }
                else if (type == TokenType.Real)
                {
                    Codes.AddLast(new Quadruple(InstructionType.Real, value, null, variable.LeftNode.Value, Line));
                    Line++;
                    var symbol = new Symbol(variable.LeftNode.Value, SymbolType.RealValue, Level);
                    SymbolTable.Register(symbol);
                }
                else if (type == TokenType.Char)
                {
                    Codes.AddLast(new Quadruple(InstructionType.Char, value, null, variable.LeftNode.Value, Line));
                    Line++;
                    var symbol = new Symbol(variable.LeftNode.Value, SymbolType.CharValue, Level);
                    SymbolTable.Register(symbol);
                }
            }
            else if (variable.MiddleNode != null)       //数组暂时不能初始化
            {
                if (variable.RightNode != null)
                {
                    throw new InterpretException("ERROR : 初始化非法.\n");
                }
                var len = InterpretArrayDim(variable.MiddleNode, out var dim);
                if (type == TokenType.Int)
                {
                    Codes.AddLast(new Quadruple(InstructionType.Int, dim.ToString(), len, variable.LeftNode.Value, Line));
                    Line++;
                    var symbol = new Symbol(variable.LeftNode.Value, SymbolType.IntArray, Level);
                    SymbolTable.Register(symbol);
                }
                else if (type == TokenType.Real)
                {
                    Codes.AddLast(new Quadruple(InstructionType.Real, dim.ToString(), len, variable.LeftNode.Value, Line));
                    Line++;
                    var symbol = new Symbol(variable.LeftNode.Value, SymbolType.RealArray, Level);
                    SymbolTable.Register(symbol);
                }
                else if (type == TokenType.Char)
                {
                    Codes.AddLast(new Quadruple(InstructionType.Char, dim.ToString(), len, variable.LeftNode.Value, Line));
                    Line++;
                    var symbol = new Symbol(variable.LeftNode.Value, SymbolType.CharArray, Level);
                    SymbolTable.Register(symbol);
                }
            }
        }