マクロ
- Rust のマクロは、コードの重複排除と繰り返し削減のために使われる。
sqleibniz の文ノードは Node トレイトを実装する必要があり、これが多くのコード重複を招く。
- マクロを使うことで、構造体定義と
Node トレイト実装を自動化できる。
コード重複排除マクロ
- マクロは構造体を定義し、ドキュメントコメントを追加し、
Node トレイトを満たす関数を実装する。
- マクロは反復的なメタ変数定義を通じて、さまざまなフィールドを追加できる。
テスト
- Rust では、Go のテーブル駆動テストに似た方式を実装できる。
test_group_pass_assert! と test_group_fail! マクロを使って、さまざまな入力と期待される出力の組をテストできる。
パーサーテスト
- パーサーモジュールでも同様のマクロを使って SQL 文の結果をテストする。
EXPLAIN SQL 文をテストするために sql_stmt_prefix 関数が使われる。
マクロの欠点
rust-analyzer はマクロ内部ではうまく動作せず、ドキュメントも不足している。
文字マッチング
- Rust の
matches! マクロを使うと、文字を簡単に比較できる。
- 与えられた文字が SQLite の数値かどうかを確認する例がある。
トークンマッチング
- レキサーが文字ストリームをトークンストリームに変換した後、パーサーはそれを使って構文木を生成する。
match 文を使ってトークンの種類を認識する。
エラー表示
- エラー処理によって、ユーザーに明確なエラーメッセージを提供する。
オプション機能
- Rust の
Option 型を使って値の有無を確認し、条件をチェックしたりデフォルト値を提供したりできる。
is_some_and、map、map_or などのメソッドを使ってコードの可読性を高める。
イテレータ
- Rust のイテレータを使って文字をフィルタリングし、SQLite の数値パース規則に合わせて処理する。
1件のコメント
Hacker Newsの意見
Rustの借用チェッカーとメモリ管理の難しさのために、Rustの利用に苦労した。Rustの関数型プログラミング(FP)的な要素は気に入っていたが、別の言語を探すことに決めた。OCamlを見つけて満足している
RustとPLのアイデアに関する経験が不足しているように見える。ASTは代数的データ型として定義するほうがもっと簡単だと思う。マクロはほとんどの言語で異なる形で動作するが、主にコードの重複排除と反復の削減のために使われる
Haskellで書いたパーサーは、単純さと可読性の面で優れている。BNFとほとんど同じように読め、技術的な手続きがほとんどないため、実際の文法に集中できる
Ragel、Go、Java、C++、Cでパーサーを書いた経験がある。CでJSONパーサーを書くほうが、Rustのコードより簡単なこともある。eBNFでパーサーを作れる飽和点に達するまで、パーサーのインフラは進化してきた
RustでeBPFディスアセンブラとエミュレーターを書いたことがあり、Rustはパース作業に適していると思う。しかし、マクロの使用は言語内での通常の作業とは違って感じられる
Rob PikeによるGoでのレキシカルスキャンに関する講演が好きだ。教育的でエレガントなアプローチだ
パーサーコンビネータライブラリを使えば、高性能なプロトコルパーサーを組み込み環境にデプロイできる。同じライブラリを使って組み込み向けのプロトコルパーサーを書くこともできる
Rustで完全なASTパーサーを書く際、具体的なAST型の階層構造を表現するのが難しかった。奇妙な型トリックやマクロを使わなければならなかった
sqlite構文をパースするのは難しい作業だ。sqliteは刺激を与えてくれるソースだ。レールロードダイアグラムは非常に有用で、Lemonパーサージェネレーターはもっと評価されるべきだ
代数的データ型を持つ言語はsqlite構文のパースに適している。TypeScriptも良い選択肢になり得る。Rustでパーサーを書く方法についての簡単な紹介を書いた