//Алгоритм построения естественного цикла обратного ребра n → d. public CFGNaturalCycle(ControlFlowGraph cfg, Edge <ThreeAddressCode> loopEdge) { //loopSet ≔ {n, d} var visitedVertex = new HashSet <ThreeAddressCode>(); // Пометим d как посещённый visitedVertex.Add(loopEdge.Target); EntryBlock = loopEdge.Target; Graph.AddVertex(EntryBlock); var targetVertex = new Queue <ThreeAddressCode>(); targetVertex.Enqueue(loopEdge.Source); ExitBlocks.Add(loopEdge.Source); Graph.AddVertex(loopEdge.Source); Graph.AddEdge(new Edge <ThreeAddressCode>(loopEdge.Source, EntryBlock)); //Выполним поиск в глубину на обратном графе потока, начиная с n. Внесём все //посещённые узлы в loopSet. while (targetVertex.Count() > 0) { var curVertex = targetVertex.Dequeue(); var containVertex = cfg.ContainsVertex(curVertex); // Рассмотрим обратный граф потока управления (все стрелочки – в обратную сторону) var incomingEdges = containVertex ? cfg.InEdges(curVertex) : new List <Edge <ThreeAddressCode> >(); foreach (var edge in incomingEdges) { if (!visitedVertex.Contains(edge.Source)) { targetVertex.Enqueue(edge.Source); } if (!Graph.Vertices.Contains(edge.Source)) { Graph.AddVertex(edge.Source); } Graph.AddEdge(new Edge <ThreeAddressCode>(edge.Source, edge.Target)); } visitedVertex.Add(curVertex); } }