public RegionSequence(CFGraph cfg) { regions = new List <Region>(); // Get all nodes of cfg List <CFGNode> allNodes = cfg.GetVertices().ToList(); // All edges in cfg List <Edge <CFGNode> > edges = cfg.EdgeTypes.Select(e => e.Key).ToList(); // Each node in cfg is leaf region foreach (var node in cfg.GetVertices()) { var edgesFromNode = edges.FindAll(e => e.Target == node); regions.Add(new LeafRegion(node, edges, NextName())); } var nc = cfg.getNaturalCyclesForBackwardEdges(); // Nodes which are headers of natural cycles HashSet <CFGNode> cyclesHeaders = new HashSet <CFGNode>(nc.Select(c => c[0])); // Headers of cycles. These cycles are added to list of regions HashSet <CFGNode> addedCyclesHeaders = new HashSet <CFGNode>(); while (nc.Count > 0) { // List of cycles we can add into regions (there are no nonadded cycles inside) List <List <CFGNode> > cyclesToAdd = nc.FindAll(c => c.Skip(1).All(node => { // If node is header of cycle then it should be added in list of regions return(cyclesHeaders.Contains(node) ? addedCyclesHeaders.Contains(node) : true); })); foreach (var cycle in cyclesToAdd) { var nodes = new HashSet <CFGNode>(cycle); AddCycle(cycle, edges, nodes); addedCyclesHeaders.Add(cycle[0]); } nc.RemoveAll(c => addedCyclesHeaders.Contains(c[0])); } // cfg is natural cycle if there is cycle header equals first node of cfg bool cfgIsNaturalCycle = cyclesHeaders.Contains(allNodes[0]); // If cfg isn't natural cycle then add region contains all nodes and edges if (!cfgIsNaturalCycle) { regions.Add(new BodyRegion(allNodes[0], allNodes, edges, NextName())); } }
static void Main(string[] args) { var text = File.ReadAllText("a.txt"); //text = "n = 0;" + // "if n {" + // "custom_label1:" + // "goto custom_label2;" + // "}" + // "else {" + // "custom_label2:" + // "goto custom_label1;" + // "}"; var root = Parser.ParseString(text); if (root == null) { Console.WriteLine("Error"); return; } // Генерация и получение трёхзначного кода var linearCode = new LinearCodeVisitor(); root.AcceptVisit(linearCode); var code = linearCode.code; // Get blocks and print it var blocks = LinearToBaseBlock.Build(code); foreach (var block in blocks) { Console.WriteLine(block.ToString()); } // Get graph and made DepthSpanningTree var cfg = new CFGraph(blocks); Console.WriteLine(cfg.ToString()); var exprsAnalizer = new AvailableExprAnalyzer(cfg); exprsAnalizer.analyze(); var dst = new DepthSpanningTree(cfg); string dst_viz = dst.ToString(); Console.WriteLine(dst_viz); Console.WriteLine(""); Console.WriteLine(cfg.EdgeTypes.ToString()); var f = cfg.allRetreatingEdgesAreBackwards(); var r = cfg.getNaturalCyclesForBackwardEdges(); var rs = new RegionSequence(cfg); Console.ReadLine(); }