Python Graphviz: DOT 语言
接下来是定义 DOT 语言特征的抽象理论语法。终结符以醒目的文本风格显示,非终结符以斜体显示。严格字符以单个语句给出。括号(和)表示必要时的组合。方括号 [ 和 ] 包含可选项。竖线 | 分隔选项。
graph : [ strict ] (graph | digraph) [ ID ] '{' stmt_list '}'
stmt_list : [ stmt [ ';' ] stmt_list ]
stmt : node_stmt
| edge_stmt
| attr_stmt
| ID '=' ID
| subgraph
attr_stmt : (graph | node | edge) attr_list
attr_list : '[' [ a_list ] ']' [ attr_list ]
a_list : ID '=' ID [ (';' | ',') ] [ a_list ]
edge_stmt : (node_id | subgraph) edgeRHS [ attr_list ]
edgeRHS : edgeop (node_id | subgraph) [ edgeRHS ]
node_stmt : node_id [ attr_list ]
node_id : ID [ port ]
port : ':' ID [ ':' compass_pt ]
| ':' compass_pt
subgraph : [ subgraph [ ID ] ] '{' stmt_list '}'
compass_pt : (n | ne | e | se | s | sw | w | nw | c | _)
关键字 strict、subgraph、digraph、Graph、edge 和 node 不区分大小写。同样,允许的指南点值不是关键字,因此这些字符串可以在其他地方用作标准标识符,并且解析器也会接受任何标识符。
一个ID可以是以下之一:
- 由字母([a-zA-Z\200-\377])、下划线(’_’)或数字([0-9])组成,且不以数字开头的任何字符;
- 一个数字([-]?(.[0-9]? | [0-9]?(.[0-9]*)? ));
- 任何包含转义字符(\”)的双引号字符串(”…”);
- 一个HTML字符串(<…>)。
聚类和子图
在Graphviz中,子图在图形中有三个作用。首先,子图可以用来表示图的结构,指示应该将特定的节点和边组合在一起。这是子图的标准作用,并且通常指定了有关图形部分的语义信息。它还可以提供对边的简写表示。例如,选择。边语句允许在边运算符的左右两侧使用子图。当发生这种情况时,将从左侧的每个节点到右侧的每个节点创建一条边。
A - > {B C}
is identical to
A - > B
A - > C
在随后的工作中,子图可以提供一个设置来设置积分。例如,子图可以确定蓝色是其中定义的所有中心的默认颜色。在绘制图表方面,一个有趣的模型是:
subgraph {
rank = same; A; B; C;
}
这个(神秘的)子图表明,假设使用点绘制,节点A、B和C应该放置在相似的位置。
子图的第三个任务直接涉及特定布局引擎如何展开图表。如果子图的名称以cluster开头,Graphviz将子图视为特殊的群组子图。如果支持,布局引擎将进行布局,使得属于该群组的节点一起绘制,整个群组的绘制结果将被限制在一个方形内。请注意,无论好坏,群组子图都不是DOT语言的一部分,而仅仅是与某些布局引擎相关的语法展示方式。
语义和词汇说明
图表必须指定为有向图(digraph)或无向图(graph)。从语义上讲,这表示边上的一个节点是否有自然的方向指向另一个节点。
从功能上讲,这种区别被用来定义默认的绘制属性。在词法上,有向图应使用边操作符- >来指定边,而无向图应使用- -。例如,有向图中的边,默认情况下会用一个尖锐的钻石形状标示头部节点。对于通常的图表,边是没有尖锐钻石标记的。
图表也可以被描述为严格的。这会禁止生成多边,即在有向图的情况下,具有给定尾部节点和头部节点的一条边只能是唯一的。对于无向图,同样的两个节点之间可以存在一条边。之后使用相同的两个节点的边语句将会识别出先前定义过的边,并应用在边语句中给出的任何属性。例如,图表中的边
severe diagram {
a1 - - > b1
a1 - - > b1
b1 - - >a1 [color=blue]
}
它将具有一个连接边界的接口,它们的音色是蓝色的。
如果使用节点、边界或图声明或通过未连接到节点或边界的属性分配定义默认值,则后续定义的适当类型的任何对象都将继承此属性值。这一点在将默认值设置为另一个值后仍然有效,新值将被使用。在设置默认属性之前定义的对象将在默认值定义创建后将空字符串值连接到属性上。
特别要注意的是,子图在其定义时获取其父图的属性设置。这可能很有用;例如,可以将字体分配给根图,并且所有子图也将使用该字体。然而,对于某些属性来说,这种特性是不受欢迎的。如果将标签链接到根图中,可能不希望所有子图都使用该名称。与在子图中逐个案例地列出图属性并重置属性不同,可以将属性定义推迟到在适当的子图被定义之前。
假设边属于某个组,那么它的端点也属于该组。因此,放置边的位置可以影响布局,因为群组有时会递归展开。
子图和群组有一些限制。首先,图和其子图的名称共享相同的命名空间。因此,每个子图必须有一个独特的名称。其次,尽管节点可以属于任意多个子图,但假设群组在作为节点和边的子集时形成一个严格的区别。
字符编码
DOT语言主要使用ASCII字符集。引用字符串(常规和类似HTML的)可以包含非ASCII字符。总的来说,这些字符串是未解释的:它们充当了经过纯净处理的特殊标识符或值。然而,名称旨在被显示,这意味着软件能够计算文本的大小并确定适当的字形。为此,它必须知道使用了哪个字符编码。
默认情况下,DOT使用UTF-8字符编码。还接受Latin1(ISO-8859-1)字符集,假设输入图使用charset属性指定了该字符集。通常会有使用其他字符集的图形程序,例如图标,它们将从一个字符集转换为另一个字符集。
在名称中避免非ASCII字符的另一种方法是使用HTML元素替代特殊字符。因此,要将小写希腊字母β包含在字符串中,可以使用ASCII序列β。通常情况下,应使用在结果字符集中允许的实体,并且在字体中存在对应字形的实体。在名称计算期间,这些实体将转换为相应的字符。此表显示了支持的实体,以及其Unicode值、常见字形和HTML实体名称。
- 在DOT中,引用字符串中最重要的是双引号 “。也就是说,在引用字符串中,双引号 \” 被完全替换为 “;其他字符保持不变。具体而言,\\ 保留为 \\\\。格式引擎可能会应用额外的转义序列。
- 在2.30版本之前,该语言允许在HTML字符串之外的任何地方使用换行符。基于新的基于词法分析器的扫描程序,这变得很难实现。鉴于这种简化的可用性明显缺乏,我们将此功能限制在双引号字符串中,这将非常有用。