强制 Graphviz 抱怨重复节点

Force Graphviz to complain for duplicate nodes

我刚刚注意到 Graphviz 没有投诉地处理了重复的节点名称(即使标记为唯一)。例如,考虑下图中呈现的以下简单图形(使用 circo):

graph { 
      a [label="a1"]
      a [label="a2"]
      b
      c
      d
      e
      a -- b; 
      b -- c; 
      a -- c; 
      d -- c; 
      e -- c; 
      e -- a; 
}

我希望上图有两个节点:a1 和 a2。所以我知道我应该用唯一的名称实例化它们(不同于我上面所做的)。但是在大图中,我可能没有注意到我错误地实例化了两个具有相同名称的不同节点。所以如果我做这样的事情,我想强迫 Graphviz 抱怨它或以某种方式引起我的注意,可能带有警告或错误消息。

我该如何完成?

所有 graphviz 程序都默默地合并具有重复名称的节点,我找不到任何方法让它们在这样做时发出警告。然而,由于我们只需要找到节点自己声明的情况,而不是在声明边时隐式声明的节点(在这种情况下重复是正常的和预期的),我们只需要找到所有节点名称和识别重复项。

如果在一行中声明的节点不超过一个,可以使用以下脚本完成:

#!/bin/sh
sed -n 's/^[\t ][\t ]*\([_a-zA-Z][_a-zA-Z0-9]*\) *\(\[.*\)*;*$// p' | \
sort | uniq -c | awk '$>1'

如果我们调用此脚本 findDupNodes,我们可以 运行 如下所示:

$ findDupNodes <duplicates.gv
      2 a

脚本查找由它们自己声明的或具有以 [ 开头的属性列表的节点名称,对它们进行排序,计算每个节点声明的次数(使用 uniq -c)和过滤掉只声明一次的。

可以在一行中声明多个节点(例如 a; b; c; d;)但是这个脚本不处理这种情况,或者(可能)一些其他情况——其中大部分可能需要一个完整的xdot 语言解析器。

不过,此脚本应该会找到许多重复的节点名称,这些名称可能会进入手写 graphviz 脚本。