Spec-Zone.ru › Graphviz

Язык 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 | _

Ключевые слова node, edge, graph, digraph, subgraph и strict не зависят от регистра. Обратите также внимание, что допустимые значения точек компаса не являются ключевыми словами, поэтому эти строки можно использовать в других местах как обычные идентификаторы; и, наоборот, парсер фактически принимает любой идентификатор.

Идентификаторы

ID — это один из следующих вариантов:

  • Любая строка, состоящая из буквенных ([a-zA-Z\200-\377]) символов, символов подчёркивания ('_') или цифр ([0-9]), не начинающаяся с цифры;
  • число [-]?(.[0-9]⁺ | [0-9]⁺(.[0-9]*)? );
  • любая строка в двойных кавычках ("..."), возможно содержащая экранированные кавычки (\")¹;
  • строка HTML (<...>).

Идентификатор — это просто строка; отсутствие кавычек в первых двух формах сделано лишь для простоты. Семантической разницы между abc_2 и "abc_2" или между 2.34 и "2.34" нет. Очевидно, чтобы использовать ключевое слово в качестве идентификатора, его необходимо заключить в кавычки.

Строки HTML

Обратите внимание, что в строках HTML угловые скобки должны использоваться попарно, а также допускаются символы перевода строки и другие пробельные символы форматирования. Кроме того, содержимое должно быть корректным XML, поэтому для включения этих символов в значения атрибутов или обычный текст могут понадобиться специальные управляющие последовательности XML для ", &, < и >. В качестве идентификатора строка HTML может быть любой корректной строкой XML. Однако, если она используется как атрибут метки, она интерпретируется особым образом и должна соответствовать синтаксису меток в стиле 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; 
} 

Этот (анонимный) подграф задаёт, что узлы A, B и C должны располагаться на одном ранге при построении графа с помощью dot.

Третья функция подграфов непосредственно связана с тем, как некоторые алгоритмы компоновки размещают граф. Если имя подграфа начинается с 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-сущностей. Так, чтобы включить в строку строчную греческую букву бета, можно использовать последовательность ASCII &beta;. В общем случае следует использовать только сущности, допустимые в выходной кодировке и имеющие соответствующий глиф в шрифте.


  1. В строках DOT, заключённых в кавычки, экранировать можно только двойную кавычку ". То есть в строках в кавычках пара символов \" преобразуется в "; все остальные символы остаются без изменений. В частности, \\ остаётся \\. Алгоритмы компоновки могут применять дополнительные управляющие последовательности.
  2. До версии 2.30 язык позволял использовать экранированные переводы строк в любом месте вне строк HTML. Новый сканер на основе лексического анализатора затрудняет реализацию этой возможности. Учитывая, что такое обобщение, по всей видимости, мало полезно, мы ограничили эту возможность строками в двойных кавычках, где она действительно может пригодиться.

© 2025 The Graphviz Authors
Licensed under the Eclipse Public License 1.0.
https://www.graphviz.org/doc/info/lang.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API