blockdiag の parser を書き直してて気づいた、graphviz の妙な表現集

秋口から blockdiag の parser を書き換えていました。
blockdiag の parser は funcparserlib の graphviz parser (dot parser) のサンプルがベースになっており、
当初の実装はとてもシンプルだったのですが、blockdiag のために文法を足していく中で見通しが悪くなっていました。

parser を書き換える中で、いくつか "ユーザが書かないであろう" 微妙な記述をパースできることに気づきました。
今日、ふと思いついて graphviz に投げ込んでみたところ、ちゃんと処理できたので紹介してみます。

属性を並べることができる

dot 言語ではノードやエッジの属性を [ ... ] 記号で定義することができますが、
実はこの属性定義をいくつも続けて書くことができます。

digraph {
  A [height = 1] [width = 2];
}

多くの記事ではカンマ区切りで説明してますよね。

属性リストの末尾にカンマを付けても良い

属性を定義するときに、リストの末尾にカンマを付けても怒られません。

digraph {
  A [height = 1, width = 2,];
}

機械生成しやすくていいですね。知りませんでした。

属性定義は空でもよい

こういうの。

digraph {
  A [];
}

並べていい、というやつと組み合わせて

digraph {
  A [][][][][][][][][][];
}

のようにも書けます。

閉じてなくても良い

なぜか閉じなくても動きます。

digraph {
  A [height = 1
}

次の行にセミコロンがあれば、続けて図を書き続けることができます。

digraph {
  A [height = 1
  ;
  B
}

まとめ

思ったより graphviz parser って大雑把なんですね。

blockdiag の方は書き換えてしまったので、許容しないようになってしまっています。

おまけ

昨日気づいたのですが、blockdiag ではこんな定義も通っていました(次のリリースで通らなくなります)。

group {
  A -> B;
}

先頭に書いた単語は無視されるという謎仕様だったためです orz