示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
            }
        }
示例#7
0
        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)));
        }