我遇到的情况是,在访问节点之前必须访问节点的前驱。所以,这是代码:
nodeQ.Enqueue(rootNode);
while(!nodeQ.Empty())
{
node = nodeQ.Dequeue();
ForEach(var predecessor in node.Predecessors)
{
if(predecessor is not visited)
{
//put the node back into the queue
nodeQ.Enqueue(node);
skip = true;
break;
}
}
if(skip)continue;
Visit(node)
foreach(var successor in node.Successors)
{
if(successor is not already visited)
{
nodeQ.Enqueue(successor);
}
}
}
上述算法适用于没有循环的线性控制流程图(读取:循环) 正常的BFS遍历不能确保在节点本身之前访问节点的前驱。
示例CFG:
普通BFS遍历将是: 0,1,2,3,12,4,5,9,10,11,8,6,7
但是,我希望订单为0,1,2,3,4,5,6,7,8,9,10,11,12,这可以通过我的代码中的小修改来实现在开头显示。
但是,当涉及到循环时,这种修改将导致无限跳过块。
示例CFG,这可能会失败:
在这种情况下,我的代码将无休止地推迟访问节点1,2,3
所以,我正在寻找一种遍历方式,以确保遍历CFG节点(有或没有循环),以便在节点本身之前访问节点的前驱。
我正在考虑识别后沿,即检查节点N是否是其前任P的支配者,然后P-> N是后备,并且不需要将P视为节点N的前驱。然而,这似乎不起作用,因为节点N并不总是必须支配节点P。
答案 0 :(得分:2)
我通过首先找到Dominators,创建Dominator Tree然后遍历DFS预订中的树来解决这个问题。
答案 1 :(得分:0)
对于那些寻求CFG和支配者计算指导的人来说,查看IBM WALA tools可能会有用。我在这里找到了很多有用的信息,用于我的特殊任务。