private void GetQuadruples(AstNode now, int Level)//dfs
        {
            if (now == null)
            {
                return;
            }
            switch (now.Type)
            {
            case AstType.SubProgram:
                GetQuadruples(now.Left, Level);
                if (CodeEntrance == -1)    //为1尚未被赋值
                {
                    if (now.Right == null) //没有起始语句
                    {
                        CodeEntrance = -2;
                    }
                    else
                    {
                        CodeEntrance = CodeSeg.Count;
                    }
                }
                GetQuadruples(now.Right, Level);
                if (now.Right != null)
                {
                    CodeSeg.Add(new QuadrupleNode(QuadrupleType.Return));
                }
                break;

            case AstType.Define:
                GetQuadruples(now.Left, Level);
                GetQuadruples(now.Right, Level + 1);
                break;

            case AstType.IdDefine:
                GetQuadruples(now.Left, Level);
                GetQuadruples(now.Right, Level);
                break;

            case AstType.ConstDefine:
                List <AstNode> list = now.Info as List <AstNode>;
                if (list == null)
                {
                    return;
                }
                foreach (var i in list)
                {
                    i.Offset = ConstSeg.Count;
                    ConstSeg.Add(Convert.ToInt32(i.Right.Info));
                }
                break;

            case AstType.VarDefine:
                list = now.Info as List <AstNode>;
                if (list == null)
                {
                    return;
                }
                int cnt = 0;
                foreach (var i in list)
                {
                    i.Offset = VarSeg.Count;
                    QuadrupleNode var = new QuadrupleNode(QuadrupleType.Var)
                    {
                        Value         = i.Left.Info,
                        Offset        = i.Offset,
                        AddressOffset = cnt++,
                        Level         = Level
                    };
                    VarSeg.Add(var);
                }
                break;

            case AstType.ProcsDefine:
                list = now.Info as List <AstNode>;
                if (list == null)
                {
                    return;
                }
                foreach (var i in list)
                {
                    i.Offset = ProcedureSeg.Count;
                    var proc = new QuadrupleNode(QuadrupleType.Proc)
                    {
                        Value = i.Left.Info,
                        Level = Level
                    };
                    ProcedureSeg.Add(proc);
                    GetQuadruples(i.Right.Left, Level);
                    proc.Offset = CodeSeg.Count;    //调用直接跳转到当前行
                    GetQuadruples(i.Right.Right, Level);
                    CodeSeg.Add(new QuadrupleNode(QuadrupleType.Return));
                    FreeAllTempData();
                }
                break;

            case AstType.Statements:
                list = now.Info as List <AstNode>;
                foreach (var i in list)
                {
                    GetQuadruples(i, Level);
                }
                break;

            case AstType.Assign:
                QuadrupleNode assign = new QuadrupleNode(QuadrupleType.Assign, new QuadrupleNode(VarSeg[now.Left.Offset], Level))
                {
                    Arg2 = GetArg(now.Right, Level)
                };
                if (assign.Arg2 == null)
                {
                    GetQuadruples(now.Right, Level);
                    assign.Arg2 = ResultIndex;
                }
                CodeSeg.Add(assign);
                break;

            case AstType.Call:
                CodeSeg.Add(new QuadrupleNode(QuadrupleType.Call)
                {
                    Result = ProcedureSeg[now.Left.Offset].Offset    //跳转地址
                });
                break;

            case AstType.IfElse:
                QuadrupleNode node = new QuadrupleNode(GetOppositeJumpInstruction(now.Left.Left.Info))
                {
                    Arg1 = GetArg(now.Left.Left.Left, Level)
                };
                if (node.Arg1 == null)
                {
                    GetQuadruples(now.Left.Left.Left, Level);    //左边表达式
                    node.Arg1 = ResultIndex;
                }
                if (node.Type != QuadrupleType.JO && node.Type != QuadrupleType.JNO)
                {
                    node.Arg2 = GetArg(now.Left.Left.Right, Level);
                    if (node.Arg2 == null)
                    {
                        GetQuadruples(now.Left.Left.Right, Level);
                        node.Arg2 = ResultIndex;
                    }
                }

                CodeSeg.Add(node);
                FreeAllTempData();
                GetQuadruples(now.Left.Right, Level);
                node.Result = CodeSeg.Count;
                //不成立跳转到隶属then的语句的之后
                //跳转指令的result(即目标地址)需要指向一个节点
                //扫描一遍回填
                if (now.Right != null)    //有else
                {
                    //if x then y else z ; t
                    QuadrupleNode LeaveIf = new QuadrupleNode(QuadrupleType.JMP);    //goto t
                    CodeSeg.Add(LeaveIf);
                    node.Result = CodeSeg.Count;
                    GetQuadruples(now.Right, Level);
                    //goto t
                    LeaveIf.Result = CodeSeg.Count;
                    FreeAllTempData();
                }
                FreeAllTempData();
                break;

            case AstType.RepeatUntil:
                node = new QuadrupleNode(GetOppositeJumpInstruction(now.Left.Info))
                {
                    Result = CodeSeg.Count    //当前位置
                };
                GetQuadruples(now.Right, Level);
                node.Arg1 = GetArg(now.Left.Left, Level);
                if (node.Arg1 == null)
                {
                    GetQuadruples(now.Left.Left, Level);
                    node.Arg1 = ResultIndex;
                }

                if (node.Type != QuadrupleType.JNO && node.Type != QuadrupleType.JO)
                {
                    node.Arg2 = GetArg(now.Left.Right, Level);
                    if (node.Arg2 == null)
                    {
                        GetQuadruples(now.Left.Right, Level);
                        node.Arg2 = ResultIndex;
                    }
                }
                CodeSeg.Add(node);
                FreeAllTempData();
                break;

            case AstType.WhileDo:
                object op = now.Left.Info;
                node = new QuadrupleNode(GetOppositeJumpInstruction(op))
                {
                    Arg1 = GetArg(now.Left.Left, Level)
                };
                if (node.Arg1 == null)
                {
                    GetQuadruples(now.Left.Left, Level);
                    node.Arg1 = ResultIndex;
                }
                if (node.Type != QuadrupleType.JNO && node.Type != QuadrupleType.JO)
                {
                    node.Arg2 = GetArg(now.Left.Right, Level);
                    if (node.Arg2 == null)
                    {
                        GetQuadruples(now.Left.Right, Level);
                        node.Arg2 = ResultIndex;
                    }
                }
                CodeSeg.Add(node);
                int location = CodeSeg.Count;
                FreeAllTempData();

                GetQuadruples(now.Right, Level);
                node.Result = CodeSeg.Count;    //while 条件不成立跳转
                QuadrupleNode back = new QuadrupleNode(GetJumpInstruction(op))
                {
                    Result = location
                };
                back.Arg1 = GetArg(now.Left.Left, Level);
                if (back.Arg1 == null)
                {
                    GetQuadruples(now.Left.Left, Level);
                    back.Arg1 = ResultIndex;
                }
                if (back.Type != QuadrupleType.JNO && back.Type != QuadrupleType.JO)
                {
                    back.Arg2 = GetArg(now.Left.Right, Level);
                    if (back.Arg2 == null)
                    {
                        GetQuadruples(now.Left.Right, Level);
                        back.Arg2 = ResultIndex;
                    }
                }

                CodeSeg.Add(back);
                node.Result = CodeSeg.Count;
                FreeAllTempData();
                break;

            case AstType.Expr:
                var node1 = new QuadrupleNode(GetOperator(now.Info))
                {
                    Arg2 = GetArg(now.Right, Level)
                };
                if (node1.Arg2 == null)
                {
                    GetQuadruples(now.Right, Level);
                    node1.Arg2 = ResultIndex;
                }
                if (now.Left.Type == AstType.Minus)    // -x -> 0 - x
                {
                    node = new QuadrupleNode(QuadrupleType.Sub)
                    {
                        Arg1 = "#0",
                        Arg2 = GetArg(now.Left.Right, Level)
                    };
                    if (node.Arg2 == null)
                    {
                        GetQuadruples(now.Left.Right, Level);
                        node.Arg2 = ResultIndex;
                    }
                    node.Result = GetTemp();
                    CodeSeg.Add(node);
                    node1.Arg1 = node.Result;
                }
                else
                {
                    node1.Arg1 = GetArg(now.Left, Level);
                    if (node1.Arg1 == null)
                    {
                        GetQuadruples(now.Left, Level);
                        node1.Arg1 = ResultIndex;
                    }
                }
                CodeSeg.Add(node1);
                ResultIndex  = GetTemp();
                node1.Result = ResultIndex;
                break;

            case AstType.Term:
                node = new QuadrupleNode(GetOperator(now.Info))
                {
                    Arg2 = GetArg(now.Right, Level)
                };
                if (node.Arg2 == null)
                {
                    GetQuadruples(now.Right, Level);
                    node.Arg2 = ResultIndex;
                }
                node.Arg1 = GetArg(now.Left, Level);
                if (node.Arg1 == null)
                {
                    GetQuadruples(now.Left, Level);
                    node.Arg1 = ResultIndex;
                }
                node.Result = GetTemp();
                ResultIndex = (int)node.Result;
                CodeSeg.Add(node);
                break;

            case AstType.Read:     //需要自己平衡栈,Write & Read
                ArrayList param = new ArrayList();
                foreach (var i in (List <AstNode>)now.Info)
                {
                    var n = new QuadrupleNode(VarSeg[i.Offset], Level);
                    param.Add(n);
                }
                CodeSeg.Add(new QuadrupleNode(QuadrupleType.Read, param));
                break;

            case AstType.Write:
                param = new ArrayList();
                foreach (var i in (List <AstNode>)now.Info)
                {
                    if (i.Type == AstType.NUM)
                    {
                        param.Add(i.Info);
                    }
                    else if (i.Type == AstType.Var)
                    {
                        var n = new QuadrupleNode(VarSeg[i.Offset], Level);
                        param.Add(n);
                    }
                    else if (i.Type == AstType.Const)
                    {
                        param.Add("#" + ConstSeg[i.Offset]);
                    }
                }
                CodeSeg.Add(new QuadrupleNode(QuadrupleType.Write, param));
                break;

            default:
                throw new Exception($"{now.Type}");
            }
        }
 private void Clear()
 {
     VarSeg.Clear();
     ConstSeg.Clear();
     CodeSeg.Clear();
 }