大学のソフトウェア実験でMLのインタプリタを作っているのですが、テスト用にMLプログラムの自動生成プログラムを書きました。
generator.sh
は一部 @basemusi 君に書いてもらってます。
型推論器のデバッグ用に作ったのでこの名前ですが、インタプリタ部分でも使えるはずです。
中身の説明
main.cpp
文法の開始記号から生成規則をランダムに適用していっています。
一番小さい非終端記号の aexpr
に到達した回数が一定以上になると木をそれ以上大きくしないようにして木の大きさを調整しています。
生成規則の選び方をハードコーディングしていたり、木を作りながらその場でどんどん標準出力に出すというひどい実装です。30分くらいで書いたので許してください。
generator.sh
main.cpp
では文法に合うデタラメなプログラムを生成するので、この出力を OCaml インタプリタに食わせて、型が正しく付いたものだけを出力するようにしています。
実行例
実行例を掲載します。
seed は固定なので、どの環境でも同じものが出力されると思います。
他のものを出力したければ、generator.sh
をいじって seed を変更してみてください。
# bash generator.sh -n 10 let a = fun c -> 7 + 7 + 3 < 7;; fun a -> 1 + 9 + 2;; let b = fun b -> 5 + ( let rec c = fun c -> fun c -> true in 9 ) + 6;; 8;; let rec a = fun b -> 8 + 7 + 5 + 8;; let a = 9;; 6;; 4 + 5 + 7;; let c = 4 + 3 + 6 + 6 + 3 < 4;; let rec b = fun b -> false;; # bash generator.sh -n 10 -1 false;; 5;; 4;; 1 + 2 + 5;; 4;; 7 + ( 8 ) < 5;; 2 < 7;; false;; 2 + 9 + 2;; 7 + 7 + ( 7 );; # bash generator.sh -n 10 -2 1 + 2 + 5;; let b = 6 < 6 + 4;; let b = 9;; let a = 7 + ( 8 );; let a = 6;; let c = 1;; let c = 2 + 7 + 8;; 3 < 5;; let b = 8 + 8 + 3;; let c = if let b = 2 + 3 < 3 + 1 in false then 6 else 2;; # bash generator.sh -n 10 -3 let c = 3 < 2;; false;; let b = 6 < 6 + 4;; let a = 7 + ( 8 );; let a = 6;; let a = fun b -> 9 + 2;; let c = 2 + 7 + 8;; 3 < 5;; let b = 8 + 8 + 3;; let b = 4 + 6;;
おわりに
雑に書いたので実装はひどいですが、デバッグにはある程度使えるはずなので、来年以降実験を履修するひとは使ってみてください。
何か間違いや質問などがあればお願いします。
最後まで読んでいただきありがとうございました。