LoginSignup
21
12

More than 3 years have passed since last update.

Rustのマクロを可視化するツール railroad

Last updated at Posted at 2019-12-10

この記事は Rustその3 Advent Calendarの10日目の記事です。空いていたのでちょっとしたツールをご紹介します。

Rustのマクロについて

Rustのマクロは、Rustの他の要素と比べて変わった文法なので最初は戸惑うかもしれません。しかし、やっていることは「どういう構文にマッチするのかを定義する」「その構文がコンパイル時にどう変換されるか定義する」の2つです。このうち、前者の「どういう構文にマッチするのか」がイメージしやすくなれば、マクロを書きやすくなるでしょう。というわけで、この部分を可視化します。

railroad

railroadは、その名の通り鉄道の線路のようにマクロの構文を可視化してくれます。ありがたいことに、Webブラウザで動くデモがありますので、以下から使わせてもらいます。

試しに、頻繁に使うマクロであるvec!を可視化してみます。vec!の定義は以下の通りです。置換後の内容は今回は関係ないので、{ ... }と省略してあっても問題ありません。

macro_rules! vec {
    ($ elem : expr ; $ n : expr) => { ... };
    ($ ($ x : expr), *) => { ... };
    ($ ($ x : expr,) *) => { ... };
}

これを上記のサイトのエディタにコピペすると、以下のような画像が生成されます。

zu1.png

vec!の書き方は、値と要素数の組、もしくは要素の繰り返しで最後の","が必要かどうか、の3つに分かれていることが視覚的にわかります。また凡例から、elem,n,xはexpression(式)であることがわかります。

もう少し複雑なものでもいけます。例えばlazy_static!なら以下のような定義になります。

macro_rules! lazy_static {
    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { ... };
    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { ... };
    ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { ... };
    () => { ... };
}

そして生成される画像は以下のようになります。

zu1.png

おわりに

以上のようにマクロの構文を可視化することができました。自作のマクロを作成している時や、使い方のよくわからないマクロがあった時もこれでイメージしやすくなると思います。

21
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
12