DOT 語言

用於定義 Graphviz 節點、邊緣、圖形、子圖和叢集的抽象語法。

終端符號以粗體字顯示,非終端符號以斜體字顯示。文字字元以單引號表示。括號 () 在需要時表示分組。方括號 [] 括住可選項目。垂直線 | 分隔選項。

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 | _

關鍵字 nodeedgegraphdigraphsubgraphstrict 不區分大小寫。另請注意,允許的羅盤點值不是關鍵字,因此這些字串可以在其他地方用作普通識別符號,反之,解析器實際上會接受任何識別符號。

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 語言的一部分,而僅是某些版面配置引擎所遵守的語法慣例。

詞法和語義註記

圖形必須指定為 digraphgraph。從語義上來說,這表示邊緣的其中一個節點到另一個節點是否有自然的方向。從詞法上來說,有向圖必須使用邊緣運算符 -> 指定邊緣,而無向圖必須使用 --。從操作上來說,此區別用於定義不同的預設渲染屬性。例如,有向圖中的邊緣預設會繪製一個指向頭部節點的箭頭。對於普通圖形,邊緣預設會繪製成沒有任何箭頭。

圖形也可以被描述為 strict。這會禁止建立多重邊緣,也就是說,在有向的情況下,對於給定的尾部節點和頭部節點,最多只能有一條邊緣。對於無向圖,最多只能有一條邊緣連接到相同的兩個節點。後續使用相同兩個節點的邊緣語句將識別先前定義的邊緣,並應用邊緣語句中給定的任何屬性。例如,圖形

strict graph { 
  a -- b
  a -- b
  b -- a [color=blue]
} 

將會有一條單一邊緣連接節點 ab,其顏色為藍色。

如果使用 nodeedgegraph 語句,或者透過未附加到節點或邊緣的屬性分配來定義預設屬性,則之後定義的任何適當類型的物件都將繼承此屬性值。這將持續到預設屬性設定為新值為止,之後會使用新值。在設定預設屬性之前定義的物件,一旦定義預設屬性,其屬性將附加一個空字串值。

請特別注意,子圖在定義時會接收其父圖的屬性設定。這很有用;例如,可以將字型指定給根圖,所有子圖也會使用該字型。然而,對於某些屬性,此屬性是不可取的。如果將標籤附加到根圖,則讓所有子圖都使用該標籤可能不是預期的效果。與其在圖形頂部列出圖形屬性,並在子圖中根據需要重置屬性,不如直接在圖形中延遲屬性定義,直到定義了適當的子圖。

如果邊緣屬於叢集,則其端點也屬於該叢集。因此,放置邊緣的位置可能會影響佈局,因為叢集有時會以遞迴方式佈局。

子圖和叢集有一些限制。首先,目前圖形及其子圖的名稱共享相同的命名空間。因此,每個子圖都必須具有唯一的名稱。其次,儘管節點可以屬於任意數量的子圖,但假設叢集在視為節點和邊緣的子集時會形成嚴格的層次結構。

字元編碼

DOT 語言至少假設使用 ASCII 字元集。帶引號的字串(包括普通字串和類似 HTML 的字串)可以包含非 ASCII 字元。在大多數情況下,這些字串不會被解釋:它們僅作為唯一的識別碼或直接傳遞的數值。但是,標籤旨在顯示,這需要軟體能夠計算文字的大小並確定適當的字形。為此,它需要知道使用哪種字元編碼。

預設情況下,DOT 假設使用 UTF-8 字元編碼。它也接受 Latin1 (ISO-8859-1) 字元集,前提是輸入圖形使用 charset 屬性來指定此字元集。對於使用其他字元集的圖形,通常會有程式(例如 iconv)可以從一種字元集轉換為另一種字元集。

避免在標籤中使用非 ASCII 字元的另一種方法是為特殊字元使用 HTML 實體。在標籤評估期間,這些實體會轉換為底層字元。此表格顯示支援的實體,包括其 Unicode 值、典型的字形和 HTML 實體名稱。因此,若要將小寫希臘字母 beta 包含在字串中,可以使用 ASCII 序列 &beta;。一般來說,應該只使用輸出字元集中允許的實體,以及字型中存在字形的實體。


  1. 在 DOT 中帶引號的字串中,唯一經過跳脫處理的字元是雙引號 "。也就是說,在帶引號的字串中,二元組 \" 會轉換為 ";所有其他字元保持不變。特別是,\\ 仍然是 \\。版面配置引擎可能會應用其他跳脫序列。
  2. 在 2.30 之前的版本中,語言允許在 HTML 字串以外的任何地方使用跳脫換行符。新的基於 lex 的掃描器很難實現此功能。鑑於人們認為這種通用性沒有用處,我們已將此功能限制為雙引號字串,在雙引號字串中它實際上很有幫助。
上次修改時間:2024 年 9 月 28 日:更新 lang.md 語法更正 (888a216)