下方表格定义了 DOT 语言的抽象语法。终端以粗体显示,而非终端以斜体显示。字符字面量使用单引号包裹。圆括号 ( and ) 用来标识分组。方括号 [ and ] 包含可选项。竖线 | 分割可选方案。
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 | _) |
关键字 node, edge, graph, digraph, subgraph 和 strict 是大小写无关的。另外请注意:compass point 不是关键字,因此这些字符串可以在其他地方用作普通标识符,相反,解析器实际将接受任意的标识符。
一个 ID 可以是以下之一:
- 任何不以数字开头的字母 (
[a-zA-Z\200-\377]
),下划线 ('_'
) 或数字 ([0-9]
); - 数字
[-]?(.[0-9]+ | [0-9]+(.[0-9]*)? )
; - 任意双引号字符串 (
"..."
) 都可能包含转义字符\"
[1]; - HTML 字符串 (
<...>
)。
ID 是个字符串,前两种形式缺少引号 "
字符仅仅是为了简单起见。abc_2 和 "abc_2" 或 2.34 和 "2.34" 之间没有语义上的差异。显然,使用关键字作为 ID 时,必须对其加双引号。值得注意的是:在 HTML 字符串中,尖括号 <>
必须成对出现,且允许使用换行符或其他格式的空白符。除此之外,内容必须是合法的 XML,为了将 <
, >
, &
, '
, "
这些 XML 特殊字符嵌入属性值或原始文本中,使用特殊的 XML 转义序列 (<
, >
, &
, '
, "
) 可能是必需的。作为 ID,HTML 字符串可以是任何合法的 XML 字符串。但是,如果用作标签属性,它要被特殊解释,且必须遵循 类似 HTML 的标签 的语法。
带引号的字符串和 HTML 字符串都当作一个单元被扫描,因此任何嵌入的注释都将视作字符串的一部分被处理。
一个边操作 edgeop 在有向图中是 ->
,在无向图是 --
。
该语言支持 C++ 风格的注释:/ * * /
和 //
。除此之外,以 #
字符开头的行被视作从 C 预处理器输出的行(e.g., # 34 表示行 34)并被丢弃。
分号和逗号有助于提高可读性,但不是必需的。另外,可以在终端之间插入任意数量的空格。
作为增强可读性的另一种手段,DOT 允许双引号字符串使用(换行符[2]前的)反斜杠 \
(标准 C 约定)来跨越多行物理行。除此之外,可以使用 +
运算符将多个双引号字符串连接在一起。由于 HTML 字符串可以包含仅用于格式设置的换行符 (
),因此 DOT 不允许在其中使用转义的换行符或串联运算符 (如 +
)。
子图 Subgraphs 和聚类 Clusters
子图在 Graphviz 中扮演三个角色。首先,子图可用于表示图结构,指示哪些节点和边应分组在一起。子图的通常角色是指定关于图组件的语义信息。它还可以为边提供方便的简写:边语句允许在边运算符的左侧和右侧都有子图,发生这种情况时,将左侧的每个节点到右侧的每个节点都创建一条边。例如:
A -> {B C}
相当于
A -> B
A -> C
在第二个角色中,子图可以提供用于设置属性的上下文。例如,子图可以指定蓝色是其中定义的所有节点的默认颜色。在图绘制的上下文中,一个更有趣的示例是:
subgraph {
rank = same; A; B; C;
}
该(匿名)子图指定如果使用点绘制,则节点 A, B 和 C 都应置于同一等级。
子图的第三个角色直接涉及某些布局引擎如何布置图。如果子图的名称以 cluster
开头,则 Graphviz 将该子图记为特殊的 cluster 子图。如果支持,布局引擎将进行布局,以便将属于 cluster 的节点绘制在一起,并将 cluster 的整个图包含在边界矩形内。值得注意的是,无论好坏,cluster 子图都不是 DOT 语言的一部分,而仅仅是某些布局引擎遵守的语法约定。
词法 Lexical 和语义注释 Semantic Notes
图必须指定为一个有向图或无向图。 从语义上讲,这表明从边的一个节点到另一个节点是否存在自然方向。从词法上讲,有向图必须使用 edge 运算符 ->
指定边,而无向图使用 --
。从操作上讲,该区别用于定义不同的默认渲染属性。例如,默认情况下,使用指向头节点的箭头来绘制有向图的边。对于普通图,默认情况下绘制的边没有任何箭头。
图也可以描述为 strict。这会禁止创建多边,i.e., 在定向情况下,一个边最多具有给定的尾节点和头节点。对于无向图,一个边最多可以连接到相同的两个节点。随后使用相同两个节点的 edge 语句将使用先前的定义标识该 edge,并应用 edge 语句中给定的任何属性。例如,下图:
strict graph {
a -- b
a -- b
b -- a [color=blue]
}
将具有连接节点 a
和 b
的单个边,其颜色为蓝色。
如果使用 node, edge 或 graph 语句或通过未附加到节点或边的属性分配,定义了默认属性,则以后定义的任何适当类型的对象都将继承此属性值。直到默认属性设置为新值为止,此属性一直有效。在设置默认属性定义后,设置默认属性之前定义的对象将具有一个空字符串值附加到该属性。
尤其值得注意的是,子图在定义时会接收其父图的属性设置,这可能很有用。例如,可以为根图分配一种字体,其所有子图也将使用该字体。但是,对于某些属性,此属性是不可取的。如果将标签附加到根图,则所有子图都使用标签可能不是理想的效果。与其在子图的顶部列出图属性,以及在子图中按需要重置属性,不如简单地将图中的属性定义推迟到定义了适当的子图之前。
如果边属于某个 cluster,则其端点属于该 cluster。因此,放置边的位置会影响布局,因为有时会以递归方式排列 clusters。
对子图和 clusters 有某些限制。首先,目前,图及其子图的名称共享相同的命名空间,因此,每个子图必须具有唯一的名称。其次,尽管节点可以属于任意数量的子图,但是当视为节点和边的子集时,可以认为 clusters 形成严格的层次结构。
字符编码
DOT 语言至少采用 ascii 字符集。带引号的字符串(普通字符串和类似 HTML 的字符串都)可能包含非 ascii 字符。在大多数情况下,这些字符串是无法解释的:它们只是用作唯一标识符或通过不变的方式传递值。但是,必须要显示标签,这要求软件能够计算文本的大小并确定适当的字形,为此,它需要知道使用什么字符编码。
默认情况下,DOT 假定使用 UTF-8 字符编码。它还接受 Latin1 (ISO-8859-1) 字符集,假设输入图使用 charset 属性指定字符集。对于使用其他字符集的图,可以使用一些程序,例如 iconv
:它将一个字符集转换为另一个字符集。
避免标签中使用非 ascii 字符的另一种方法是将 HTML 实体用于特殊字符。在标签 evaluation 期间,这些实体会转换为基础字符。该 表 显示了受支持的实体及其 Unicode 值,典型字形和 HTML 实体名称。因此,为了在字符串中包含小写的希腊语贝塔 beta,可以使用 ascii 序列 β
。通常,仅应使用输出字符集中允许的实体,并且其字体中包含字形。
See also
- 相关翻译
- 一篇 DOT 语言翻译
- 另一篇 DOT 语言翻译
- 较全的 DOT 相关翻译
- 使用教程
- 使用 DOT 语言和 Graphviz 绘图(翻译)
- 使用 graphviz 绘制流程图
- dot language 学习笔记
- GraphViz Pocket Reference
- 练习
- graphviz 在线编辑器
- 另一个 graphviz 在线编辑器
- 官方链接
- The DOT Language 原文
- Node, Edge and Graph Attributes
- graphviz 官网
- graphviz 仓库
在 DOT 带双引号的字符串 (
"..."
) 中,唯一的转义字符是双引号"
。即,在带引号的字符串中,双引号\"
转换为"
,其他所有字符保持不变。特别地,\\
仍为\\
。Layout engines 可以应用其他转义序列。 ↩︎在 2.30 之前的版本中,DOT 允许将转义后的换行符用于 HTML 字符串之外的任何位置。由于基于新的 lex 扫描器使这一点难以实现,且考虑到这种通用性的功能的有用性,我们将这个功能限制在了双引号字符串中,这实际上可以有所帮助。 ↩︎