The DOT Language Graphviz中的“DOT”語(yǔ)言

如下是DOT語(yǔ)言的簡(jiǎn)明語(yǔ)法定義。

終端以粗體顯示,非終端以斜體顯示。文本字符使用單引號(hào)包含。括號(hào)(和)指明一些必要的組合。方括號(hào)[和]表示一些可選項(xiàng)。豎線|把一些備選方法分割開。

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

需要注意的是,關(guān)鍵字node, edge, graph, digraph, subgraph和strict是忽略大小寫的。另外,那些給出的指示符值并不是關(guān)鍵字,因此這些字符串在別處可以作為普通標(biāo)識(shí)符來(lái)使用。反過(guò)來(lái)說(shuō),解析器會(huì)接受任何標(biāo)識(shí)符。

ID可以是如下任何一種類型:

  • 任意字符類型的字母 ([a-zA-Z\200-\377]) , 下劃線 ('_') 數(shù)字 ([0-9]), 不能以數(shù)字開頭;
  • 一個(gè)數(shù)字 [-]?(.[0-9]+ | [0-9]+(.[0-9]*)? );
  • 雙引號(hào) ("...")包裹的字符串可能包含獨(dú)立的轉(zhuǎn)義引號(hào) (")1;
  • HTML 字符串 (<...>).

ID就是一個(gè)字符串。前面的兩個(gè)例子上沒有加引號(hào)只是為了簡(jiǎn)單起見。事實(shí)上, abc_2 和 "abc_2", 或者 2.34 和 "2.34"這兩種表達(dá)方式并沒有什么區(qū)別。

顯而易見,如果我們要把一個(gè)關(guān)鍵詞作為ID,那么就要加上引號(hào)。需要注意的是,在HTML語(yǔ)言中,尖括號(hào)必須成對(duì)的出現(xiàn),并且換行符和其他標(biāo)準(zhǔn)空字符是可以使用呢的。另外,HTML語(yǔ)言的內(nèi)容必須符合標(biāo)準(zhǔn)的XML, 因此在原文中使用XML中的特殊字符時(shí)需要進(jìn)行轉(zhuǎn)義,比如 ", &, <, 和 > 。

帶引號(hào)的內(nèi)容和HTML代碼都會(huì)被作為一個(gè)單元識(shí)別出來(lái)。所以被識(shí)別在這個(gè)單元內(nèi)部的任何內(nèi)容都會(huì)被認(rèn)為是他們的一部分。

edgeop(邊操作)使用 -> 表明有向圖邊 , -- 表明無(wú)向圖邊。
我們支持C++的注釋風(fēng)格:使用 /* */ 和 //. 同時(shí),一行以#號(hào)開頭的句子也會(huì)被認(rèn)為是C預(yù)處理器的輸出內(nèi)容而不被識(shí)別。 (我理解是#也是注釋)

分號(hào)和逗號(hào)有助于提高可讀性,但不是必需的。此外,可以在終端之間插入任何的空白字符。

另一個(gè)為了可讀性方便的案例是,DOT允許在雙引號(hào)包裹的字符串內(nèi)跨越多個(gè)物理行,只要你緊接在換行符前面使用標(biāo)準(zhǔn)C約定的反斜杠作為識(shí)別。
另外,雙引號(hào)包裹的字符串可以使用‘+’來(lái)進(jìn)行連接。由于HTML字符串允許內(nèi)部有換行符,因此該語(yǔ)言不允許使用轉(zhuǎn)移換行符和連接運(yùn)算符。

子圖和集合

在Graphviz中,子圖有三個(gè)作用。子圖可以用來(lái)表示圖結(jié)構(gòu),標(biāo)示某些點(diǎn)和邊可以組合在一起。這是子圖常用的方法,指明圖組件的語(yǔ)義信息。其次,它還可以為邊提供一個(gè)簡(jiǎn)便的縮寫。在邊的狀態(tài)中,子圖可以同時(shí)在邊操作符的左邊和右邊。當(dāng)這種狀態(tài)的時(shí)候,會(huì)為左邊的每個(gè)節(jié)點(diǎn)和右邊的每個(gè)節(jié)點(diǎn)之間都創(chuàng)建一條表。例如:

A -> {B C}

相當(dāng)于

  A -> B
  A -> C

第二點(diǎn),子圖可以為設(shè)置屬性提供一些上下文。比如說(shuō),子圖可以設(shè)定藍(lán)色作為所有節(jié)點(diǎn)產(chǎn)生時(shí)的默認(rèn)顏色。這里有一個(gè)更有意思的栗子:

subgraph { 
rank = same; A; B; C; 
}

這個(gè)子圖定義了ABC三個(gè)節(jié)點(diǎn)置于同一個(gè)等級(jí)。
子圖的第三個(gè)作用是在使用布局引擎對(duì)圖像進(jìn)行布局時(shí)進(jìn)行干預(yù)。如果子圖的名字被定義為cluster,那么Graphviz會(huì)識(shí)別到這是一個(gè)特殊的cluster子圖。在使用這個(gè)方法時(shí),布局引擎會(huì)把這個(gè)cluster下面的所有節(jié)點(diǎn)畫在一起,并用一個(gè)矩形框把它們括在一起。不過(guò)需要注意的是,cluster子圖并不是一個(gè)標(biāo)準(zhǔn)的DOT語(yǔ)句,它只是為了適配部分布局引擎的特殊需求而單獨(dú)約定的。

語(yǔ)法和語(yǔ)義要點(diǎn)

在該語(yǔ)言中,一個(gè)圖要么被指定為一個(gè)有向圖,要么被指定為一個(gè)無(wú)向圖。在語(yǔ)義上來(lái)說(shuō),有向圖需要在每一條邊上都設(shè)定一個(gè)方向或者兩個(gè)方向,而無(wú)向圖的邊則設(shè)定為沒有方向。在語(yǔ)法上來(lái)說(shuō),一個(gè)有向圖的邊要用->,一個(gè)無(wú)向圖的邊要用--來(lái)表述。有向圖和無(wú)向圖需要在定義圖形的時(shí)候就指定,作為一個(gè)默認(rèn)屬性。在有向圖中,一條線默認(rèn)會(huì)有一個(gè)箭頭指向頭部節(jié)點(diǎn),在無(wú)向圖中則不會(huì)有任何箭頭。

圖也可以被定義為嚴(yán)謹(jǐn)圖,禁止創(chuàng)建多邊對(duì)象,這意味著在任何兩點(diǎn)之間只能有一條邊。對(duì)于無(wú)向圖,兩個(gè)節(jié)點(diǎn)之間只能有一條線連接。在緊接著的邊聲明中,可以使用這兩個(gè)事先聲明的點(diǎn)來(lái)唯一標(biāo)識(shí)這一條邊,并且可以使用邊定義中的任何屬性。例如下面這樣

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

通過(guò)上述定義,我們就可以在點(diǎn)a和b之間創(chuàng)建一條藍(lán)色的邊。
如果使用節(jié)點(diǎn),邊或圖形語(yǔ)句或未附加到節(jié)點(diǎn)或邊的屬性賦值定義默認(rèn)屬性,則之后定義的任何相應(yīng)類型的對(duì)象將繼承此屬性值。
這種狀態(tài)將一直維持下去,除非這個(gè)值被賦予了一個(gè)新的值,那么從這個(gè)新的節(jié)點(diǎn)開始,后面都會(huì)使用新的值。已經(jīng)定義但沒有賦值的對(duì)象會(huì)有一個(gè)空字符串值。
值得注意的是,一個(gè)子圖在被定義的時(shí)候就會(huì)繼承父節(jié)點(diǎn)的屬性。這個(gè)功能很有用,比如你在根圖就制定了一個(gè)字體,在整個(gè)圖上的子圖都會(huì)使用這個(gè)字體。但是對(duì)于某些屬性,是不適用這個(gè)功能的。比如在根圖上加了一個(gè)標(biāo)簽,大概率上來(lái)說(shuō)這個(gè)標(biāo)簽都不需要加在所有的子圖上。所以不必在圖的頂點(diǎn)就列出所有屬性,然后在子圖上加以修改??梢院?jiǎn)單的進(jìn)行處理,那就是當(dāng)你需要的時(shí)候再加上這個(gè)屬性。
如果一條邊屬于一個(gè)集合,那么它的端點(diǎn)也屬于這個(gè)集合。因此,邊的放置會(huì)影響布局,因?yàn)榧嫌袝r(shí)候是遞歸布局的。
子圖和集合需要一些限制。首先,一個(gè)圖和所有子圖共享一個(gè)命名空間,所以所有的子圖都需要有一個(gè)唯一的命名。其次,盡管節(jié)點(diǎn)可以屬于任何子圖,但是當(dāng)節(jié)點(diǎn)是某個(gè)集合的邊或節(jié)點(diǎn)的子集的時(shí)候,該集合應(yīng)該是有嚴(yán)格的等級(jí)的。

字符編碼

DOT語(yǔ)言支持ASCII字符編碼字符集。在引用的字符中,普通引用和類HTML引用可能包含非ASCII編碼字符。在大多數(shù)情況下,這些字符都不會(huì)被解析。它們會(huì)被當(dāng)做標(biāo)識(shí)符或者字符值來(lái)進(jìn)行傳遞。其中有一類比較特殊的,即標(biāo)簽(Labels),需要用來(lái)在前端展示,需要在軟件需求的長(zhǎng)度范圍內(nèi),并使用合適的字體。因此,對(duì)于這部分需要知道使用了什么字符編碼格式。
DOT語(yǔ)言默認(rèn)是UTF-8編碼。也可以使用Latin1 (ISO-8859-1)編碼,但是需要使用 charset
來(lái)指明。對(duì)于其他的字符編碼比如iconv,需要轉(zhuǎn)換成上面的兩種。
在labels中避免非法字符的另外一種方法是在使用特殊字符時(shí)包進(jìn)HTML實(shí)體中。在識(shí)別標(biāo)簽的時(shí)候,這些實(shí)體被轉(zhuǎn)換成底層標(biāo)簽。table這個(gè)表里記錄了所有支持的實(shí)體,連帶它們的Unicode值,標(biāo)準(zhǔn)字形和HTML實(shí)體名。因此,要將小寫的希臘語(yǔ)beta包含在字符串中,可以使用ascii編碼&beta;。通常,應(yīng)該只使用輸出字符集中允許的實(shí)體,并且字體中只有一個(gè)字形。

  1. 在DOT中的引用字符串中,唯一的轉(zhuǎn)義字符是雙引號(hào)(")。也就是說(shuō),在引用的字符串中,dyad \“被轉(zhuǎn)換為”;所有其他字符保持不變。尤其是\仍然\。布局引擎可以應(yīng)用其他轉(zhuǎn)義序列。
  2. 在2.30版本之前,該語(yǔ)言允許在HTML字符串之外的任何地方使用轉(zhuǎn)義換行符。新的語(yǔ)義識(shí)別器很難實(shí)現(xiàn)這個(gè)功能,同時(shí)因?yàn)檫@個(gè)功能的用處也不是很大,我們將此功能限制為僅限于使用雙引號(hào)的字符串,這樣在需要的時(shí)候也可以發(fā)揮一點(diǎn)作用。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從匹配中返回值 Match 對(duì)象 成功的匹配總是返回一個(gè) Match 對(duì)象, 這個(gè)對(duì)象通常也被放進(jìn) $/ 中, (...
    焉知非魚閱讀 1,943評(píng)論 0 1
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,744評(píng)論 0 5
  • 這次開一個(gè)小腦洞。因?yàn)槭悄X洞,所以是有水分的,很多定義是模糊的,推理過(guò)程也并不要求嚴(yán)格。 話題先從標(biāo)題的最后一項(xiàng)開...
    LostAbaddon閱讀 1,941評(píng)論 8 11
  • JavaScript語(yǔ)言精粹 前言 約定:=> 表示參考相關(guān)文章或書籍; JS是JavaScript的縮寫。 本書...
    微笑的AK47閱讀 665評(píng)論 0 3
  • 字符串和字符 [TOC] 字符串是例如 "hello, world" , "albatross" 這樣的有序的 C...
    伍哥___閱讀 1,167評(píng)論 0 0

友情鏈接更多精彩內(nèi)容