예제 #1
0
        private void LocateJumpNodeAndDetermineNodeOffset()
        {
            for (int i = 0; i < CodeSeg.Count; ++i)
            {
                QuadrupleNode node = CodeSeg[i] as QuadrupleNode;
                node.Offset = i;

                /*
                 * if (IsJumpInstruction(node.Type))
                 * {
                 *  if (node.Result is int)
                 *  {
                 *      int tar = (int)node.Result;
                 *      if (tar >= CodeSeg.Count)
                 *      {
                 *          node.Result = null;
                 *      }
                 *      else
                 *      {
                 *          node.Result = CodeSeg[tar];
                 *      }
                 *  }
                 * }
                 */
            }
        }
예제 #2
0
 public QuadrupleNode(QuadrupleType type, Object arg1 = null, Object arg2 = null)
 {
     Type         = type;
     Arg1         = arg1;
     Arg2         = arg2;
     Active       = false;
     CurrentValue = null;
     Result       = null;//表示未初始化
 }
예제 #3
0
 public QuadrupleNode(QuadrupleNode old, int level)
 {
     Type          = old.Type;
     Arg1          = old.Arg1;
     Arg2          = old.Arg2;
     Value         = old.Value;
     Offset        = old.Offset;
     Level         = level - old.Level;
     AddressOffset = old.AddressOffset;
 }
예제 #4
0
        private void TranslateJump(QuadrupleNode Node)
        {
            if (Node.Type == QuadrupleType.JMP)
            {
                Add(new PNode(PCode.JMP, (int)Node.Result, 4));
                return;
            }
            LoadArg(Node);
            switch (Node.Type)//根据条件选择相反的指令,因为是if False跳转
            {
            case QuadrupleType.JNO:
                Add(new PNode(PCode.OPR, 6, 5));
                break;

            case QuadrupleType.JO:
                Add(new PNode(PCode.OPR, 7, 5));
                break;

            case QuadrupleType.JNE:
                Add(new PNode(PCode.OPR, 8, 5));
                break;

            case QuadrupleType.JE:
                Add(new PNode(PCode.OPR, 9, 5));
                break;

            case QuadrupleType.JGE:
                Add(new PNode(PCode.OPR, 10, 5));
                break;

            case QuadrupleType.JL:
                Add(new PNode(PCode.OPR, 11, 5));
                break;

            case QuadrupleType.JLE:
                Add(new PNode(PCode.OPR, 12, 5));
                break;

            case QuadrupleType.JG:
                Add(new PNode(PCode.OPR, 13, 5));
                break;
            }
            Add(new PNode(PCode.JPC, (int)Node.Result, 4));
        }
예제 #5
0
 private void LoadArg(QuadrupleNode Node)
 {
     if (Node.Arg1 is int)
     {
         Add(new PNode(PCode.LOD, (int)Node.Arg1, 2));
     }
     else if (Node.Arg1 is string)
     {
         int arg = int.Parse(((string)Node.Arg1).Substring(1));
         Add(new PNode(PCode.LIT, arg, 1));
     }
     else
     {
         var t = Node.Arg1 as QuadrupleNode;
         Add(new PNode(PCode.LOD, t.Offset, 3)
         {
             Offset = t.AddressOffset, Level = t.Level
         });
     }
     if (Node.Arg2 == null)
     {
         return;
     }
     if (Node.Arg2 is int)
     {
         Add(new PNode(PCode.LOD, (int)Node.Arg2, 2));
     }
     else if (Node.Arg2 is string)
     {
         int arg = int.Parse(((string)Node.Arg2).Substring(1));
         Add(new PNode(PCode.LIT, arg, 1));
     }
     else
     {
         var t = Node.Arg2 as QuadrupleNode;
         Add(new PNode(PCode.LOD, t.Offset, 3)
         {
             Offset = t.AddressOffset, Level = t.Level
         });
     }
 }
예제 #6
0
        private void TranslateOpr(QuadrupleNode Node)
        {
            LoadArg(Node);
            switch (Node.Type)
            {
            case QuadrupleType.Add:
                Add(new PNode(PCode.OPR, 2, 5));
                break;

            case QuadrupleType.Sub:
                Add(new PNode(PCode.OPR, 3, 5));
                break;

            case QuadrupleType.Mul:
                Add(new PNode(PCode.OPR, 4, 5));
                break;

            case QuadrupleType.Div:
                Add(new PNode(PCode.OPR, 5, 5));
                break;
            }
            Add(new PNode(PCode.STO, (int)Node.Result, 2));
        }
예제 #7
0
        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}");
            }
        }
예제 #8
0
        private void Translate(QuadrupleNode Node, int Index)
        {
            Node.Start = Programs.Count;
            int typeV = Convert.ToInt32(Node.Type);

            if (typeV <= IsJump)
            {
                TranslateJump(Node);
                return;
            }
            switch (Node.Type)
            {
            case QuadrupleType.Return:
                Add(new PNode(PCode.EXP));
                Address.Add(Index + 1, Programs.Count);
                break;

            case QuadrupleType.Call:
                int a = 1;
                if (Address.ContainsKey((int)Node.Result))
                {
                    a = Address[(int)Node.Result];
                }
                Add(new PNode(PCode.CAL, a, 4));
                break;

            case QuadrupleType.Add:
            case QuadrupleType.Sub:
            case QuadrupleType.Mul:
            case QuadrupleType.Div:
                TranslateOpr(Node);
                break;

            case QuadrupleType.Assign:
                if (Node.Arg2 is int)
                {
                    var node = new PNode(PCode.LOD, (int)Node.Arg2, 2);
                    Add(node);
                }
                else if (Node.Arg2 is string)
                {
                    int arg = int.Parse(((string)Node.Arg2).Substring(1));
                    Add(new PNode(PCode.LIT, arg, 1));
                }
                else
                {
                    Add(new PNode(PCode.LOD, ((QuadrupleNode)(Node.Arg2)).Offset, 3)
                    {
                        Offset = ((QuadrupleNode)(Node.Arg2)).AddressOffset, Level = ((QuadrupleNode)(Node.Arg2)).Level
                    });
                }
                var qnode = (QuadrupleNode)(Node.Arg1);
                Add(new PNode(PCode.STO, qnode.Offset, 3)
                {
                    Offset = qnode.AddressOffset, Level = qnode.Level
                });
                break;

            case QuadrupleType.Write:
                var list = Node.Arg1 as ArrayList;
                foreach (var i in list)
                {
                    if (i is string)
                    {
                        Add(new PNode(PCode.LIT, Convert.ToInt32(((string)i).Substring(1)), 1));
                        Add(new PNode(PCode.WRT));
                        continue;
                    }
                    var param = i as QuadrupleNode;
                    Add(new PNode(PCode.LOD, param.Offset, 3)
                    {
                        Offset = param.AddressOffset, Level = param.Level
                    });
                    Add(new PNode(PCode.WRT));
                }
                break;

            case QuadrupleType.Read:
                list = Node.Arg1 as ArrayList;
                foreach (var i in list)
                {
                    var param = i as QuadrupleNode;
                    Add(new PNode(PCode.RED, param.Offset, 3)
                    {
                        Offset = param.AddressOffset, Level = param.Level
                    });
                }
                break;
            }
        }