public void ThisIsAwfulTestDontMakeItWorse() { string FileName = @"../../../a.txt"; try { string text = File.ReadAllText(FileName); SyntaxNode root = ParserWrap.Parse(text); Trace.WriteLine(root == null ? "Ошибка" : "Программа распознана"); if (root != null) { var prettyPrintedProgram = PrettyPrinter.CreateAndVisit(root).FormattedCode; Trace.WriteLine(prettyPrintedProgram); var threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program; Trace.WriteLine(threeAddressCode); Trace.WriteLine("\nУправляющий граф программы"); Graph g = new Graph(BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode)); Trace.WriteLine(g); Trace.WriteLine("Дерево доминаторов"); var dTree = new DominatorsTree(g); Trace.WriteLine(dTree); Trace.WriteLine("Классификация рёбер"); var classEdge = EdgeClassification.ClassifyEdge(g); foreach (var p in classEdge) { Trace.WriteLine(p.Key.Source.BlockId + "->" + p.Key.Target.BlockId + "; type = " + p.Value); } Trace.WriteLine("\nНахождение естественных циклов"); var findNL = SearchNaturalLoops.FindAllNaturalLoops(g); foreach (var nl in findNL) { Trace.Write(nl.Key.Source.BlockId + "->" + nl.Key.Target.BlockId + ": "); foreach (var node in nl.Value) { Trace.Write(node.ToString() + " "); } Trace.WriteLine(""); } Trace.WriteLine(("\nПостроение глубинного остовного дерева")); var DFN = g.GetDFN(); foreach (var node in DFN) { Trace.WriteLine("key: " + node.Key + " " + "value: " + node.Value); } List <Region> regions = new List <Region>(); foreach (BasicBlock v in g) { regions.Add(new LeafRegion(v)); } foreach (var l in findNL) { List <Region> regs = l.Value.Select(x => new LeafRegion(g.getBlockById(x)) as Region).ToList(); regions.Add(new LoopRegion(new BodyRegion(l.Key.Target, l.Key.Source.OutputBlocks, regs))); } } } catch (FileNotFoundException) { Trace.WriteLine("Файл {0} не найден", FileName); } catch (LexException e) { Trace.WriteLine("Лексическая ошибка. " + e.Message); } catch (SyntaxException e) { Trace.WriteLine("Синтаксическая ошибка. " + e.Message); } }
public void NaturalLoopsTest() { string programText_1 = @" b = 1; if 1 b = 3; else b = 2; "; string programText_2 = @" b = 1; if 1 b = 3; else for i = 1..5 b = 6; "; string programText_3 = @" i = 10; 1: i = i - 1; if i > 0 goto 1; "; string programText_4 = @" i = 1; j = 4; a = 2; while i < 20 { i = i + 1; j = j + 1; if i > a a = a + 5; i = i + 1; } "; Trace.WriteLine("==============="); Trace.WriteLine("Тест 1"); Trace.WriteLine("==============="); SyntaxNode root = ParserWrap.Parse(programText_1); var threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program; Trace.WriteLine(threeAddressCode); var basicBlocks = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode); Trace.WriteLine(Environment.NewLine + "Базовые блоки"); Trace.WriteLine(basicBlocks); Trace.WriteLine(Environment.NewLine + "Управляющий граф программы"); Graph g = new Graph(basicBlocks); Trace.WriteLine(g); var allNaturalLoops = SearchNaturalLoops.FindAllNaturalLoops(g); var tuples = new List <Tuple <int, int, SortedSet <int> > >(); foreach (var v in allNaturalLoops) { Trace.Write(v.Key.Source.BlockId + " -> " + v.Key.Target.BlockId + " : "); foreach (int k in v.Value) { Trace.Write(k.ToString() + " "); } Trace.WriteLine(""); tuples.Add(new Tuple <int, int, SortedSet <int> >(v.Key.Source.BlockId, v.Key.Target.BlockId, new SortedSet <int>(v.Value))); } int start = g.GetMinBlockId(); Assert.IsTrue(tuples.SequenceEqual(new List <Tuple <int, int, SortedSet <int> > >())); Trace.WriteLine("==============="); Trace.WriteLine("Тест 2"); Trace.WriteLine("==============="); root = ParserWrap.Parse(programText_2); threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program; Trace.WriteLine(threeAddressCode); basicBlocks = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode); Trace.WriteLine(Environment.NewLine + "Базовые блоки"); Trace.WriteLine(basicBlocks); Trace.WriteLine(Environment.NewLine + "Управляющий граф программы"); g = new Graph(basicBlocks); Trace.WriteLine(g); allNaturalLoops = SearchNaturalLoops.FindAllNaturalLoops(g); tuples = new List <Tuple <int, int, SortedSet <int> > >(); foreach (var v in allNaturalLoops) { Trace.Write(v.Key.Source.BlockId + " -> " + v.Key.Target.BlockId + " : "); foreach (int k in v.Value) { Trace.Write(k.ToString() + " "); } Trace.WriteLine(""); tuples.Add(new Tuple <int, int, SortedSet <int> >(v.Key.Source.BlockId, v.Key.Target.BlockId, new SortedSet <int>(v.Value))); } start = g.GetMinBlockId(); var check = new List <Tuple <int, int, SortedSet <int> > >() { new Tuple <int, int, SortedSet <int> >(start + 4, start + 3, new SortedSet <int>() { start + 3, start + 4 }) }; Assert.IsTrue(tuples.Count == 1); Assert.IsTrue(tuples[0].Item1 == check[0].Item1); Assert.IsTrue(tuples[0].Item2 == check[0].Item2); Assert.IsTrue(tuples[0].Item3.SequenceEqual(check[0].Item3)); Trace.WriteLine("==============="); Trace.WriteLine("Тест 3"); Trace.WriteLine("==============="); root = ParserWrap.Parse(programText_3); threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program; Trace.WriteLine(threeAddressCode); basicBlocks = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode); Trace.WriteLine(Environment.NewLine + "Базовые блоки"); Trace.WriteLine(basicBlocks); Trace.WriteLine(Environment.NewLine + "Управляющий граф программы"); g = new Graph(basicBlocks); Trace.WriteLine(g); allNaturalLoops = SearchNaturalLoops.FindAllNaturalLoops(g); tuples = new List <Tuple <int, int, SortedSet <int> > >(); foreach (var v in allNaturalLoops) { Trace.Write(v.Key.Source.BlockId + " -> " + v.Key.Target.BlockId + " : "); foreach (int k in v.Value) { Trace.Write(k.ToString() + " "); } Trace.WriteLine(""); tuples.Add(new Tuple <int, int, SortedSet <int> >(v.Key.Source.BlockId, v.Key.Target.BlockId, new SortedSet <int>(v.Value))); } start = g.GetMinBlockId(); check = new List <Tuple <int, int, SortedSet <int> > >() { new Tuple <int, int, SortedSet <int> >(start + 2, start + 1, new SortedSet <int>() { start + 1, start + 2 }) }; Assert.IsTrue(tuples.Count == 1); Assert.IsTrue(tuples[0].Item1 == check[0].Item1); Assert.IsTrue(tuples[0].Item2 == check[0].Item2); Assert.IsTrue(tuples[0].Item3.SequenceEqual(check[0].Item3)); Trace.WriteLine("==============="); Trace.WriteLine("Тест 4"); Trace.WriteLine("==============="); root = ParserWrap.Parse(programText_4); threeAddressCode = ThreeAddressCodeGenerator.CreateAndVisit(root).Program; Trace.WriteLine(threeAddressCode); basicBlocks = BasicBlocksGenerator.CreateBasicBlocks(threeAddressCode); Trace.WriteLine(Environment.NewLine + "Базовые блоки"); Trace.WriteLine(basicBlocks); Trace.WriteLine(Environment.NewLine + "Управляющий граф программы"); g = new Graph(basicBlocks); Trace.WriteLine(g); allNaturalLoops = SearchNaturalLoops.FindAllNaturalLoops(g); tuples = new List <Tuple <int, int, SortedSet <int> > >(); foreach (var v in allNaturalLoops) { Trace.Write(v.Key.Source.BlockId + " -> " + v.Key.Target.BlockId + " : "); foreach (int k in v.Value) { Trace.Write(k.ToString() + " "); } Trace.WriteLine(""); tuples.Add(new Tuple <int, int, SortedSet <int> >(v.Key.Source.BlockId, v.Key.Target.BlockId, new SortedSet <int>(v.Value))); } start = g.GetMinBlockId(); check = new List <Tuple <int, int, SortedSet <int> > >() { new Tuple <int, int, SortedSet <int> >(start + 4, start + 1, new SortedSet <int>() { start + 1, start + 2, start + 3, start + 4 }) }; Assert.IsTrue(tuples.Count == 1); Assert.IsTrue(tuples[0].Item1 == check[0].Item1); Assert.IsTrue(tuples[0].Item2 == check[0].Item2); Assert.IsTrue(tuples[0].Item3.SequenceEqual(check[0].Item3)); }
public List <Region> CreateSequence(Graph g) { if (!CheckRetreatingIsReverse.CheckRetreatingIsReverse.CheckReverseEdges(g)) { Console.WriteLine("there are some retreating edges which aren't reverse"); Environment.Exit(0); } var basicBlockLastRegion = new Dictionary <BasicBlock, Region>(); foreach (var v in g.GetVertices()) { var newReg = new LeafRegion(v); regionList.Add(newReg); basicBlockLastRegion[v] = newReg; } var loops = SearchNaturalLoops.FindAllNaturalLoops(g); var regionMade = new Dictionary <Edge <BasicBlock>, bool>(); foreach (var loop in loops) { regionMade[loop.Key] = false; } while (regionMade.ContainsValue(false)) { foreach (var loop in loops) { bool anyInsideLoops = false; foreach (var loopOther in loops) { anyInsideLoops = anyInsideLoops || checkLoopInclusion(loop, loopOther, regionMade[loopOther.Key]); } if (!anyInsideLoops) { continue; } regionMade[loop.Key] = true; var header = loop.Key.Target; var curRegions = new List <Region>(); var outputBlocks = new List <int>(); foreach (var blockId in loop.Value) { var block = g.getBlockById(blockId); if (!curRegions.Contains(basicBlockLastRegion[block])) { curRegions.Add(basicBlockLastRegion[block]); } foreach (var outputBlock in block.OutputBlocks) { if (!loop.Value.Contains(outputBlock)) { outputBlocks.Add(block.BlockId); break; } } } var bodyReg = new BodyRegion(header, outputBlocks, curRegions); regionList.Add(bodyReg); var loopReg = new LoopRegion(bodyReg); regionList.Add(loopReg); foreach (var blockId in loop.Value) { var block = g.getBlockById(blockId); basicBlockLastRegion[block] = loopReg; } } } // check if program has become one region foreach (var block in basicBlockLastRegion) { // if there are leaves not included in loops if (block.Value.GetType() == typeof(LeafRegion)) { var header = g.getRoot(); var outputBlocks = new List <int>(); var curRegions = new List <Region>(); foreach (var curblock in basicBlockLastRegion) { if (!curRegions.Contains(curblock.Value)) { curRegions.Add(curblock.Value); } } var newReg = new BodyRegion(header, outputBlocks, curRegions); regionList.Add(newReg); break; } } foreach (var reg in regionList) { if (reg.GetType() == typeof(LoopRegion)) { (reg as LoopRegion).Body.RegionParent = reg; } if (reg.GetType() == typeof(BodyRegion)) { foreach (var children in (reg as BodyRegion).Regions) { children.RegionParent = reg; } } } return(regionList); }