我正在尝试转储OCaml项目中所有标识符的类型信息,基本上与遍历类型化抽象语法树相同(https://github.com/ocaml/ocaml/blob/trunk/typing/typedtree.mli) 。由于我不熟悉OCaml编译器的代码库,因此不确定该编译器是否提供了api,因此我们可以轻松编写插件来完成这项工作,还是必须破解编译器代码?另外,这如何与OCamlbuild交互?感谢您的任何提示或建议。
假设您已经拥有某种类型的AST类型structure
。
经典方法是简单地编写一个大的递归函数以自己遍历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构造执行的操作。您有两个要执行的工作:遍历何时进入构造以及何时从构造退出。对于pattern
,例如,你有enter_pattern
和exit_pattern
。您无需担心递归遍历本身:这是函子的工作MakeIterator
。给定一个IteratorArgument
模块,它将所有的enter_*
和exit_*
递归地连接起来,并返回带有一堆迭代器的模块。
通常,您只对AST的某些部分感兴趣,而想跳过其他部分。DefaultIteratorArgument
是一个模块,其enter_*
和exit_*
什么也不做。您的IteratorArgument
模块应包括DefaultIteratorArgument
继承此默认行为,然后仅实现执行某些特殊操作的部分。
如果您不仅要遍历键入的AST,还要修改其中的某些部分,请使用TypedtreeMap
代替TypedtreeIter
。TypedtreeMap
在https://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=default上有一个小示例。
(我不使用ocamlbuild,所以我无能为力。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句