关于 graphviz 的使用(残卷)
最近学习编译原理,苦于使用 draw.io 这样的软件绘制示意图的时候特别麻烦,于是试图找到更为简单的方案,而 graphviz 就是一个很舒爽的解决方案——它提供了一个名为 dot 的 DSL 用以生成 svg,png 以及其他图像格式的文件。所以这里对它进行一些学习。这软件或许在其他地方也能够使用,比如绘制流程图,状态转移图之类的时候。
先尝尝鲜——下面是一个表示(19+2)*2
的语法树的 dot 代码——
1 |
|
其使用 dot 生成的对应的图如下——
说使用 dot 生成,是因为 graphviz 实际上提供了多种命令来生成图,其代表各种不同的布局引擎,其各有特点——
命令 | 特性 |
---|---|
dot | 渲染的图具有明确方向性。 |
neato | 渲染的图缺乏方向性。 |
twopi | 渲染的图采用放射性布局。 |
circo | 渲染的图采用环型布局。 |
fdp | 渲染的图缺乏方向性。 |
sfdp | 渲染大型的图,图片缺乏方向性。 |
下面通过一些实例和注释描述其使用。
List
这里试图展示 Lisp 中的 cons/list 的结构。一般来说这种结构使用所谓的“箱子表示法 ”(box notation),如下图来自《ANSI Common Lisp》。
这里,每一个 node 都有两个“箱子”(之后都这么称呼),dot 中使用 record 类型的 shape 可以让 node 如此展示。其使用方法如下。
1 |
|
上面的代码试图展示一个 UML 类图。需要注意的是 node0 中 label 的内容。其包含三个元符号——{},<>和|。
其中,|可以认为是各个箱子的分隔符;{}则是对特定数量箱子起作用,其将更改箱子排列的方向(这个元符号用以构造结构更为复杂的箱子)。<>用来定义“锚点”,使可以被 edge 所引用。
为实现箱型表示法,还有一点需要实现——默认排列是从上到下的,需要改成从左到右,这是通过 graph 的 rankdir 属性实现的。需要注意的是,rankdir 会改变 record 的默认方向。
1 |
|
……看起来要表达规则的图形的时候这玩意并不太适合。
先就这样吧……这玩意出现的 bug 浇灭了我继续的兴趣。反正当前学到的东西足够画 AST 了。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!