public override void VisitIfNode(IfNode bl) { Console.WriteLine(Tag + " VisitIfNode"); bl.Cond.Visit(this); var ifThenLine = new ThreeAddrLine(); ifThenLine.Label = GenNewLabel(); ifThenLine.LeftOp = GetLastLine().Accum; ifThenLine.OpType = ThreeAddrOpType.IfGoto; Data.Add(ifThenLine); if (bl.ElseB != null) { bl.ElseB.Visit(this); } var outsideIfLine = new ThreeAddrLine(); outsideIfLine.Label = GenNewLabel(); outsideIfLine.OpType = ThreeAddrOpType.Goto; Data.Add(outsideIfLine); ifThenLine.RightOp = GenNewLabel(); bl.ThenB.Visit(this); InsertNop(); outsideIfLine.RightOp = GetLastLine().Label; }
public override void VisitCycleNode(CycleNode c) { Console.WriteLine(Tag + " VisitCycleNode"); var startLoopLabel = GenNewLabel(); c.Expr.Visit(this); var whileLine = new ThreeAddrLine(); whileLine.Label = GenNewLabel(); whileLine.LeftOp = GetLastLine().Accum; whileLine.OpType = ThreeAddrOpType.IfGoto; Data.Add(whileLine); var outsideWhileLine = new ThreeAddrLine(); outsideWhileLine.Label = GenNewLabel(); outsideWhileLine.OpType = ThreeAddrOpType.Goto; Data.Add(outsideWhileLine); whileLine.RightOp = GenNewLabel(); c.Stat.Visit(this); var gotoStartLine = new ThreeAddrLine(); gotoStartLine.Label = GenNewLabel(); gotoStartLine.OpType = ThreeAddrOpType.Goto; gotoStartLine.RightOp = startLoopLabel; Data.Add(gotoStartLine); InsertNop(); outsideWhileLine.RightOp = GetLastLine().Label; }
public override void VisitReadNode(ReadNode rd) { var readLine = new ThreeAddrLine(); readLine.Label = GenNewLabel(); readLine.Accum = rd.Id.Name; readLine.OpType = ThreeAddrOpType.Read; Data.Add(readLine); }
public override void VisitIntNumNode(IntNumNode num) { var line = new ThreeAddrLine(); line.Accum = num.Num.ToString(); line.Label = GenNewLabel(); line.OpType = ThreeAddrOpType.Nop; Data.Add(line); }
public override void VisitWriteNode(WriteNode w) { Console.WriteLine(Tag + " VisitWriteNode"); w.Expr.Visit(this); var printLine = new ThreeAddrLine(); printLine.Label = GenNewLabel(); printLine.RightOp = GetLastLine().Accum; printLine.OpType = ThreeAddrOpType.Write; Data.Add(printLine); }
public override void VisitIdNode(IdNode id) { Console.WriteLine(Tag + " VisitIdNode"); var line = new ThreeAddrLine(); line.Accum = GenNewTemporaryVariable(); line.Label = GenNewLabel(); line.OpType = ThreeAddrOpType.Assign; line.RightOp = id.Name; Data.Add(line); }
public override void VisitAssignNode(AssignNode a) { Console.WriteLine(Tag + " VisitAssingNode"); if (a == null) { return; } a.Expr.Visit(this); var line = new ThreeAddrLine(); line.Accum = a.Id.Name; line.RightOp = GetLastLine().Accum; line.Label = GenNewLabel(); line.OpType = ThreeAddrOpType.Assign; Data.Add(line); }
private bool Recognize(ThreeAddrLine line) // метод получает строку трехадресного кода, конвертирует операнты и записывает результат. { int a = 0, b = 0; bool isaconst = int.TryParse(line.LeftOp, out a); // Получаем левый оперант. bool isbconst = int.TryParse(line.RightOp, out b); if (line.LeftOp == null) { isaconst = true; a = 0; } string res = null; if (!isaconst && !isbconst && (line.LeftOp != line.RightOp)) { return(false); // обе переменны, которые не равны друг другу, то не наш случай } // Конвертируем операнды и считаем результат if (!isaconst && !isbconst) { res = ComputeBothVar(line.OpType); } if (isaconst && (a == 1 || a == 0)) { res = ComputeVarRigth(a, line.RightOp, line.OpType); } if (isbconst && (b == 1 || b == 0)) { res = ComputeVarLeft(line.LeftOp, b, line.OpType); } if (res != null) { line.LeftOp = null; // Просто зануляем. line.OpType = ThreeAddrOpType.Assign; // записываем в тип операции assign. line.RightOp = res; return(true); } return(false); }
public List <ThreeAddrLine> ReadTextFile(string FilePath) // Метод читает трёхадерсную программу из текстового файла. { BinaryFormatter Formater = new BinaryFormatter(); List <ThreeAddrLine> Code = new List <ThreeAddrLine>(); using (StreamReader FS = new StreamReader(FilePath)) { string line; while ((line = FS.ReadLine()) != null) { line = line.Replace("=", " "); line = line.Replace(":", " "); line = Regex.Replace(line, @"\s+", " "); string[] tokens = line.Split(' '); int size_tokens = tokens.Count(); ThreeAddrLine threeAddrLine = new ThreeAddrLine(); threeAddrLine.Label = tokens[0]; // 1 if (tokens[1] == "nop") // 35: = nop { threeAddrLine.OpType = "nop"; Code.Add(threeAddrLine); continue; } if (tokens[1] == "write" || tokens[1] == "goto" ) // 39: = write p11 { threeAddrLine.OpType = tokens[1]; threeAddrLine.RightOp = tokens[2]; Code.Add(threeAddrLine); continue; } // 2 if (tokens[2] == "nop" || tokens[2] == "read" ) // 40: 5 = nop { threeAddrLine.OpType = tokens[2]; threeAddrLine.Accum = tokens[1]; Code.Add(threeAddrLine); continue; } if (tokens[2] == "ifgoto") // 78: = p29 ifgoto 80 { threeAddrLine.OpType = "ifgoto"; threeAddrLine.LeftOp = tokens[1]; threeAddrLine.RightOp = tokens[3]; Code.Add(threeAddrLine); continue; } if (tokens[2] == "assign" || tokens[2] == "not" ) // 36: p10 = assign v2 { threeAddrLine.OpType = tokens[2]; threeAddrLine.Accum = tokens[1]; threeAddrLine.RightOp = tokens[3]; Code.Add(threeAddrLine); continue; } // 3 if (tokens[3] == "or" || tokens[3] == "and" || tokens[3] == "+" || tokens[3] == "-" || tokens[3] == "/" || tokens[3] == "*" || tokens[3] == "<" || tokens[3] == ">" || tokens[3] == "<=" || tokens[3] == ">=" || tokens[3] == "==" || tokens[3] == "!=" || tokens[3] == "assign" ) // 45: p12 = p13 or 0 { threeAddrLine.OpType = tokens[3]; threeAddrLine.Accum = tokens[1]; threeAddrLine.LeftOp = tokens[2]; threeAddrLine.RightOp = tokens[4]; Code.Add(threeAddrLine); continue; } } } return(Code); }