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);
            }
        }
Exemple #2
0
        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);
        }