OCaml プロジェクトのすべての識別子の型情報をダンプしようとしています。基本的には、型付き抽象構文ツリー ( https://github.com/ocaml/ocaml/blob/trunk/typing/typedtree.mli )をトラバースするのと同じです。 . 私は OCaml コンパイラのコードベースに慣れていないので、コンパイラが API を提供しているので、プラグインを簡単に記述してジョブを実行できるのか、それともコンパイラ コードをハックする必要があるのかわかりません。また、これは OCamlbuild とどのように相互作用しますか? ヒントやアドバイスをありがとう。
2 に答える
structure
どういうわけか型付きの AST をすでに取得していると仮定します。
古典的な方法は、自分で AST をトラバースする大きな再帰関数を単純に作成することです。
しかし、現在TypedtreeIter
、OCaml コンパイラのソース コードで利用可能なモジュールがあり、それが公開されていcompiler-libs
ます。単純なトラバーサルの場合、これは非常に便利です。
TypedtreeIter
型指定された AST に対して独自のイテレータを構築するためのファンクタを提供します。すべてのパターン識別子をそのタイプとともに出力する非常に単純な例を次に示します。
(* ocamlfind ocamlc -package compiler-libs.common -c example.ml *)
open Typedtree
open TypedtreeIter
module MyIteratorArgument = struct
include DefaultIteratorArgument
let enter_pattern p = match p.pat_desc with
| Tpat_var (id, _) ->
Format.printf "@[<2>%s@ : %a@]@."
(Ident.name id)
Printtyp.type_scheme p.pat_type
| _ -> ()
end
module Iterator = TypedtreeIter.MakeIterator(MyIteratorArgument)
モジュール タイプTypedtreeIter.IteratorArgument
は、AST コンストラクトごとにイテレータが何をするかを指定するものです。ジョブを実行するポイントは 2 つあります。トラバーサルがコンストラクトに入るときと、コンストラクトから出るときです。たとえばpattern
、 と がenter_pattern
ありexit_pattern
ます。再帰トラバーサル自体について心配する必要はありません。それは functor の仕事ですMakeIterator
。モジュールを指定するとIteratorArgument
、すべてのenter_*
andexit_*
が再帰的に接続され、一連のイテレータを含むモジュールが返されます。
通常、AST の一部のみに関心があり、他の部分はスキップしたいと考えています。とが何もしないDefaultIteratorArgument
モジュールです。モジュールは、このデフォルトの動作を継承するためにインクルードする必要があり、特別なことを行う部分のみを実装する必要があります。enter_*
exit_*
IteratorArgument
DefaultIteratorArgument
型指定された AST をトラバースするだけでなく、その一部を変更する場合は、TypedtreeMap
代わりにTypedtreeIter
. https://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=defaultTypedtreeMap
に小さな例があります。
(私はocamlbuildを使っていないので、その点はどうしようもありません。)
OCaml は という名前のライブラリとして独自のコンパイラを提供しますcompiler-libs
。そこにはすべてが含まれており、具体的な構文から実行可能ファイルに移行することができ、もちろん typedtree を含むすべての中間ステップを制御できます。
悪いニュースは、それが文書化されていないことです。utop
このライブラリを使用またはmerlin
探索することをお勧めします。
ocamlbuild を使用するために特別なことをする必要はありませんcompiler-libs
。これは通常のライブラリです。