Source(Tool)

Source(Tool) #

src/tool ディレクトリ内のコードについて記述する。 src/tool 内には brgen の様々なツールのソースコードが含まれている。 以下各ディレクトリについて述べる

brgen #

コードジェネレータードライバーである。Go 言語で書かれている。 このプログラムはカレントディレクトリにある brgen.json もしくは-c オプションで指定したファイルを 読み込んでコードジェネレーターを実行する。 このプログラムは src2json に brgen(lang)が記述されたファイルを渡し、 その結果を各コードジェネレーターに渡し、コードジェネレーターが生成したコードを 指定のファイルに保存する。

初期はコードジェネレーターは 1 ファイル 1 プロセスのような状態であり、 ファイル数が多くなるとかなりの時間がかかり、OOM が発生して生成が不安定になったり ともすればシステムにダメージを与えかねない状態であった。 そのため、https://github.com/on-keyday/brgen/pull/59 などによって 基本的なジェネレーターは 1 言語 1 プロセスになるように変更されている。 なお、開発初期については簡便性のため引き続き 1 ファイル 1 プロセスも可としている。

ジェネレーターとの仕様のやり取りについては https://github.com/on-keyday/brgen/blob/main/spec/generator_spec_file.md に規定された方法で行う。ジェネレーターはこれらのインターフェイスを最低限満たす必要がある。

src2json #

brgen(lang)が記述されたソースファイルを AST に変換し、JSON 形式にして出力する。 C++で記述されている。 このプログラムは brgen から呼び出される。 また、libs2j というオーバーヘッド削減のために動的ライブラリ化された モジュールも存在し、brgen(gen) は使用可能であればそちらを使う。

s2jgo #

libs2j を Go 言語から呼び出すためのラッパーである。 Windows では syscall.DLL を使い、Linux などでは cgo を使って dlopen や dlsym を使っている。 対応していない場合は stub が使用される。

cmptest #

brgen の生成されたコードのテストを行うためのツールである。 このツールでは指定されたバイナリデータを指定されたフォーマットでパースし、 再生成できることを検証する。

生成情報ファイルとテスト構成ファイルを入力に取る。 生成情報ファイルは brgen に-test-info オプションを指定すると生成される、 コードジェネレーターによって生成されたファイルの情報を含んだファイルである。 https://github.com/on-keyday/brgen/blob/main/spec/brgen_test_info_schema.json に スキーマが定義されている。 テスト構成ファイルは、テストの入力のバイナリデータと各言語ごとのテスト生成、実行方法を指定する。 https://github.com/on-keyday/brgen/blob/main/spec/brgen_cmptest_config_schema.json に スキーマがある。

本リポジトリ内には testkit ディレクトリがあるが、そこに cmptest のサンプルが存在する。 本リポジトリではそれを CI 上でテストとして走らせている。

json2cpp2 #

json2cpp2 は C++向けソースコードジェネレーターである。 C++で書かれている。json2cpp の後継である。 生成されるコードは作者の作っている作者以外使っている人がいない 独自ライブラリが使われているため、使えるかは微妙である。が、作者が 使えればそれでいいので気にしたら負けである。

json2cpp というディレクトリもあるがもはやそちらはメンテナンスされておらず、 レガシーである。いつかは削除される。

json2go #

json2go は Go 言語向けソースコードジェネレーターである。 Go で書かれている。なんやかんや一番作者によく使われている。 こちらは標準ライブラリとある程度互換性のあるインターフェイスである。

現状の問題点としては union が union じゃないので union のフィールドを増やしすぎると 構造体の大きさがえげつないことになることである。改善したい。

json2ts #

json2ts は TypeScript/JavaScript 向けソースコードジェネレーターである。 C++で書かれている。JavaScript モードはオプションで切り替えられる。

json2vm #

json2vm は brgen のコードを Virtual Machine のバイトコードに変換して実行するツールである。 これは brgen のジェネレーターが言語仕様を完全に実装しなくてもいいとはしているが 言語仕様を完璧に網羅したツールが最低限 1 つくらいはあったほうがいいだろうという考えで作っている。 今のところ他のツールに気を取られていてあまり開発は進んでいない。

json2mermaid #

json2mermaid は brgen(lang)の AST を mermaid 記法で出力する。

json2rust #

json2rust は Rust 向けコードジェネレーターである。が、ほとんど開発が進んでいない。 ほとんどハリボテである。 しかも 後述のツールで C++で書かれた AST を無理くり Rust に変換したため、Rust 的には あまりよろしくない unwrap()を使わないとやってられん状態である。 とにかく AST の単なるフィールドにアクセスするだけでも非常に骨が折れるため、作者は参ってしまい開発が止まっている。 ptr!(a.b.c)みたいな記法でアクセスできるようにするマクロを作成したので 多少は楽になったと思われる。

ctobgn #

ctobgn は C 言語の構造体や列挙体の定義を brgen のコードに変換する簡易的なツールである。 ごくごく基本的な構文しか変換できないがそれでも全部を書き写すよりは楽だし、 写し間違いもなくなる。

gen/ #

このディレクトリは各言語ごとの brgen(lang)用 AST を生成するためのツール群のソースコードが入っている。すべて Go 言語で書かれている。src2json の–dump-types オプションをつけたときに出てくる出力を元に生成する。

なお、実際のところ、このツールは Node がルートであることさえ満たせば結構柔軟に コードを生成できるため、他のプロジェクトなどでも使える可能性はある。 (map に対応していないのはわりかし痛い気もするが…)

TODO(on-keyday): 以降も書く