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]; * } * } * } */ } }
public QuadrupleNode(QuadrupleType type, Object arg1 = null, Object arg2 = null) { Type = type; Arg1 = arg1; Arg2 = arg2; Active = false; CurrentValue = null; Result = null;//表示未初始化 }
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; }
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)); }
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 }); } }
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)); }
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 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; } }