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 | _ |
關鍵字 node、edge、graph、digraph、subgraph 和 strict 不區分大小寫。另請注意,允許的羅盤點值不是關鍵字,因此這些字串可以在其他地方用作普通識別符號,反之,解析器實際上會接受任何識別符號。
IDs
ID 是以下其中一種
- 任何由字母 (
[a-zA-Z\200-\377]
) 字元、底線 ('_'
) 或數字 ([0-9]
) 組成的字串,但不以數字開頭; - 數字 [
-
]?(.
[0
-9
]⁺|
[0
-9
]⁺(.
[0
-9
]*)? ); - 任何雙引號括住的字串 (
"..."
) 可能包含跳脫引號 (\"
)¹; - HTML 字串 (
<...>
)。
ID 僅僅是一個字串;前兩種形式缺少引號字元僅僅是為了簡化。abc_2
和 "abc_2"
之間,或 2.34
和 "2.34"
之間沒有語義差異。顯然,要使用關鍵字作為 ID,必須將其括起來。
HTML 字串
請注意,在 HTML 字串中,角括號必須成對出現,並且允許換行符和其他格式化空白字元。此外,內容必須是合法的 XML,因此可能需要使用 ", &, < 和 > 的特殊 XML 跳脫序列,以便將這些字元嵌入到屬性值或原始文字中。作為 ID,HTML 字串可以是任何合法的 XML 字串。但是,如果用作 label 屬性,它會被特殊解釋,並且必須遵循 類似 HTML 的標籤 的語法。
雙引號字串和 HTML 字串都作為一個單元掃描,因此任何嵌入的註解都將被視為字串的一部分。
邊緣操作 (edgeops)
edgeop 在有向圖中是 ->
,在無向圖中是 --
。
註解和可選格式
該語言支援 C++ 風格的註解:/* */
和 //
。此外,以 '#' 字元開頭的行被視為來自 C 前處理器的行輸出(例如,# 34 表示第 34 行),並將被丟棄。
分號和逗號有助於提高可讀性,但並非必需。此外,任何數量的空白字元都可以在終端符號之間插入。
作為另一個提高可讀性的輔助手段,dot 允許使用反斜線緊接換行符的標準 C 約定,使雙引號字串跨越多個實體行²。此外,可以使用 '+' 運算符將雙引號字串連接起來。由於 HTML 字串可以包含僅用於格式化的換行字元,因此該語言不允許在其中使用跳脫換行符或串聯運算符。
子圖和叢集
子圖在 Graphviz 中扮演三個角色。首先,子圖可用於表示圖形結構,表示某些節點和邊緣應分組在一起。這是子圖的通常角色,並且通常指定有關圖形組件的語義資訊。它還可以為邊緣提供便捷的簡寫。邊緣語句允許在邊緣運算符的左側和右側都使用子圖。當這種情況發生時,將從左側的每個節點到右側的每個節點建立邊緣。例如,規範
A -> {B C}
等效於
A -> B
A -> C
在第二個角色中,子圖可以為設定屬性提供上下文。例如,子圖可以指定藍色是其中定義的所有節點的預設顏色。在圖形繪製的上下文中,一個更有趣的範例是
subgraph {
rank = same; A; B; C;
}
如果使用 dot 繪製,則此(匿名)子圖指定節點 A、B 和 C 都應放置在同一級別。
子圖的第三個作用直接關係到某些版面配置引擎如何佈局圖形。如果子圖的名稱以 cluster
開頭,Graphviz 會將該子圖視為特殊的叢集子圖。如果支援,版面配置引擎會進行佈局,使屬於叢集的節點被繪製在一起,並且整個叢集的繪圖都包含在一個邊界矩形內。請注意,無論好壞,叢集子圖都不是 DOT 語言的一部分,而僅是某些版面配置引擎所遵守的語法慣例。
詞法和語義註記
圖形必須指定為 digraph 或 graph。從語義上來說,這表示邊緣的其中一個節點到另一個節點是否有自然的方向。從詞法上來說,有向圖必須使用邊緣運算符 ->
指定邊緣,而無向圖必須使用 --
。從操作上來說,此區別用於定義不同的預設渲染屬性。例如,有向圖中的邊緣預設會繪製一個指向頭部節點的箭頭。對於普通圖形,邊緣預設會繪製成沒有任何箭頭。
圖形也可以被描述為 strict。這會禁止建立多重邊緣,也就是說,在有向的情況下,對於給定的尾部節點和頭部節點,最多只能有一條邊緣。對於無向圖,最多只能有一條邊緣連接到相同的兩個節點。後續使用相同兩個節點的邊緣語句將識別先前定義的邊緣,並應用邊緣語句中給定的任何屬性。例如,圖形
strict graph {
a -- b
a -- b
b -- a [color=blue]
}
將會有一條單一邊緣連接節點 a
和 b
,其顏色為藍色。
如果使用 node、edge 或 graph 語句,或者透過未附加到節點或邊緣的屬性分配來定義預設屬性,則之後定義的任何適當類型的物件都將繼承此屬性值。這將持續到預設屬性設定為新值為止,之後會使用新值。在設定預設屬性之前定義的物件,一旦定義預設屬性,其屬性將附加一個空字串值。
請特別注意,子圖在定義時會接收其父圖的屬性設定。這很有用;例如,可以將字型指定給根圖,所有子圖也會使用該字型。然而,對於某些屬性,此屬性是不可取的。如果將標籤附加到根圖,則讓所有子圖都使用該標籤可能不是預期的效果。與其在圖形頂部列出圖形屬性,並在子圖中根據需要重置屬性,不如直接在圖形中延遲屬性定義,直到定義了適當的子圖。
如果邊緣屬於叢集,則其端點也屬於該叢集。因此,放置邊緣的位置可能會影響佈局,因為叢集有時會以遞迴方式佈局。
子圖和叢集有一些限制。首先,目前圖形及其子圖的名稱共享相同的命名空間。因此,每個子圖都必須具有唯一的名稱。其次,儘管節點可以屬於任意數量的子圖,但假設叢集在視為節點和邊緣的子集時會形成嚴格的層次結構。
字元編碼
DOT 語言至少假設使用 ASCII 字元集。帶引號的字串(包括普通字串和類似 HTML 的字串)可以包含非 ASCII 字元。在大多數情況下,這些字串不會被解釋:它們僅作為唯一的識別碼或直接傳遞的數值。但是,標籤旨在顯示,這需要軟體能夠計算文字的大小並確定適當的字形。為此,它需要知道使用哪種字元編碼。
預設情況下,DOT 假設使用 UTF-8 字元編碼。它也接受 Latin1 (ISO-8859-1) 字元集,前提是輸入圖形使用 charset 屬性來指定此字元集。對於使用其他字元集的圖形,通常會有程式(例如 iconv
)可以從一種字元集轉換為另一種字元集。
避免在標籤中使用非 ASCII 字元的另一種方法是為特殊字元使用 HTML 實體。在標籤評估期間,這些實體會轉換為底層字元。此表格顯示支援的實體,包括其 Unicode 值、典型的字形和 HTML 實體名稱。因此,若要將小寫希臘字母 beta 包含在字串中,可以使用 ASCII 序列 β
。一般來說,應該只使用輸出字元集中允許的實體,以及字型中存在字形的實體。
- 在 DOT 中帶引號的字串中,唯一經過跳脫處理的字元是雙引號
"
。也就是說,在帶引號的字串中,二元組\"
會轉換為"
;所有其他字元保持不變。特別是,\\
仍然是\\
。版面配置引擎可能會應用其他跳脫序列。 - 在 2.30 之前的版本中,語言允許在 HTML 字串以外的任何地方使用跳脫換行符。新的基於 lex 的掃描器很難實現此功能。鑑於人們認為這種通用性沒有用處,我們已將此功能限制為雙引號字串,在雙引號字串中它實際上很有幫助。