The DOT Language

下方表格定义了 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, subgraphstrict 是大小写无关的。另外请注意: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]
}

将具有连接节点 ab 的单个边,其颜色为蓝色。

如果使用 node, edgegraph 语句或通过未附加到节点或边的属性分配,定义了默认属性,则以后定义的任何适当类型的对象都将继承此属性值。直到默认属性设置为新值为止,此属性一直有效。在设置默认属性定义后,设置默认属性之前定义的对象将具有一个空字符串值附加到该属性。

尤其值得注意的是,子图在定义时会接收其父图的属性设置,这可能很有用。例如,可以为根图分配一种字体,其所有子图也将使用该字体。但是,对于某些属性,此属性是不可取的。如果将标签附加到根图,则所有子图都使用标签可能不是理想的效果。与其在子图的顶部列出图属性,以及在子图中按需要重置属性,不如简单地将图中的属性定义推迟到定义了适当的子图之前。

如果边属于某个 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 仓库

  1. 在 DOT 带双引号的字符串 ("...") 中,唯一的转义字符是双引号 "。即,在带引号的字符串中,双引号 \" 转换为 ",其他所有字符保持不变。特别地,\\ 仍为 \\。Layout engines 可以应用其他转义序列。 ↩︎

  2. 在 2.30 之前的版本中,DOT 允许将转义后的换行符用于 HTML 字符串之外的任何位置。由于基于新的 lex 扫描器使这一点难以实现,且考虑到这种通用性的功能的有用性,我们将这个功能限制在了双引号字符串中,这实际上可以有所帮助。 ↩︎

你可能感兴趣的:(The DOT Language)