public void Test2() { var cfg = GenerateCFG( @"{ n = 4; c = n + 5; if a + 3 > 4 * 2 { a = a + 3; } else { b = 5; } s = 8; }"); /* * 4 блока * 0 {n = 4 #t0 = n + 5 * c = #t0 #t1 = a + 3 #t2 = 4 * 2 #t3 = #t1 > #t2 * if #t3 goto #L0} * 1 { b = 5 * goto #L1} * 2 { #t4 = a + 3 * a = #t4} * 3 {s = 8} */ var dominatorsTree = new DominatorsTree(cfg); dominatorsTree.GenDominatorsTree(); var Actual = dominatorsTree.dominators; var Expect = new Dictionary <BasicBlock, List <BasicBlock> >(); Expect.Add(cfg.blocks[0], new List <BasicBlock>() { cfg.blocks[0] }); Expect.Add(cfg.blocks[1], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[1] }); Expect.Add(cfg.blocks[2], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[2] }); Expect.Add(cfg.blocks[3], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[3] }); CollectionAssert.AreEqual(Actual, Expect); }
public List <NaturalLoop> GetLoops(string sourceCode) { var TAC = GenerateTAC(sourceCode); var TACBlocks = new TACBaseBlocks(TAC.Instructions); TACBlocks.GenBaseBlocks(); var cfg = new ControlFlowGraph(TACBlocks.blocks); var dt = new DominatorsTree(cfg); dt.GenDominatorsTree(); var loops = TACUtils.GetNaturalLoops(cfg, dt.dominators); return(loops); }
public void Test1() { var cfg = GenerateCFG( @"{ if (true) { a = 5; } else { b = 1; } }"); /* * 4 блока * 0 {if True goto #L0} * 1 {b = 1; goto #L1} * 2 {#L0 a = 5;} * 3 {#L1} */ var dominatorsTree = new DominatorsTree(cfg); dominatorsTree.GenDominatorsTree(); var Actual = dominatorsTree.dominators; var Expect = new Dictionary <BasicBlock, List <BasicBlock> >(); Expect.Add(cfg.blocks[0], new List <BasicBlock>() { cfg.blocks[0] }); Expect.Add(cfg.blocks[1], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[1] }); Expect.Add(cfg.blocks[2], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[2] }); Expect.Add(cfg.blocks[3], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[3] }); CollectionAssert.AreEqual(Actual, Expect); }
public void Test3() { var cfg = GenerateCFG( @"{ x = 14; goto 1; 1: y = 2; goto 2; 2: y = 3; }"); /* * 3 блока * 0 {x = 14 * goto 1} * 1 { y = 2 * goto 2} * 2 { y = 3} */ var dominatorsTree = new DominatorsTree(cfg); dominatorsTree.GenDominatorsTree(); var Actual = dominatorsTree.dominators; var Expect = new Dictionary <BasicBlock, List <BasicBlock> >(); Expect.Add(cfg.blocks[0], new List <BasicBlock>() { cfg.blocks[0] }); Expect.Add(cfg.blocks[1], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[1] }); Expect.Add(cfg.blocks[2], new List <BasicBlock>() { cfg.blocks[0], cfg.blocks[1], cfg.blocks[2] }); CollectionAssert.AreEqual(Actual, Expect); }
public static Dictionary <Edge <BasicBlock>, EdgeType> ClassifyEdge(ControlFlowGraph.Graph g) { Dictionary <Edge <BasicBlock>, EdgeType> edgeTypes = new Dictionary <Edge <BasicBlock>, EdgeType>(); Dictionary <int, int> dfn = g.GetDFN(); DominatorsTree tree = new DominatorsTree(g); foreach (Edge <BasicBlock> e in g.GetEdges()) { if (dfn[e.Source.BlockId] >= dfn[e.Target.BlockId]) { edgeTypes.Add(e, EdgeType.Retreating); } else if (g.IsAncestor(e.Target.BlockId, e.Source.BlockId) && tree.GetParent(e.Target.BlockId) == e.Source.BlockId) { edgeTypes.Add(e, EdgeType.Advancing); } else { edgeTypes.Add(e, EdgeType.Cross); } } return(edgeTypes); }
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 DominatorsTreesTest() { 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; "; 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 dominatorsTree = new DominatorsTree(g); foreach (var v in dominatorsTree.GetMap()) { Trace.WriteLine(v.Key + " " + v.Value); } int start = g.GetMinBlockId(); Assert.IsTrue(dominatorsTree.GetMap().OrderBy(x => x.Key).SequenceEqual( new Dictionary <int, int> { { start, start }, { start + 1, start }, { start + 2, start }, { start + 3, start } } .OrderBy(x => x.Key))); 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); dominatorsTree = new DominatorsTree(g); foreach (var v in dominatorsTree.GetMap()) { Trace.WriteLine(v.Key + " " + v.Value); } start = g.GetMinBlockId(); Assert.IsTrue(dominatorsTree.GetMap().OrderBy(x => x.Key).SequenceEqual( new Dictionary <int, int> { { start, start }, { start + 1, start }, { start + 2, start }, { start + 3, start + 2 }, { start + 4, start + 3 }, { start + 5, start + 3 }, { start + 6, start } } .OrderBy(x => x.Key))); 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); dominatorsTree = new DominatorsTree(g); foreach (var v in dominatorsTree.GetMap()) { Trace.WriteLine(v.Key + " " + v.Value); } start = g.GetMinBlockId(); Assert.IsTrue(dominatorsTree.GetMap().OrderBy(x => x.Key).SequenceEqual( new Dictionary <int, int> { { start, start }, { start + 1, start }, { start + 2, start + 1 }, { start + 3, start + 1 } } .OrderBy(x => x.Key))); }