假设您已经获得了类型的 ASTstructure
不知何故。
经典的方式就是自己写一个大的递归函数来遍历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
and exit_pattern
。您无需担心递归遍历本身:这是函子的工作MakeIterator
。给予IteratorArgument
模块它连接了所有enter_*
and exit_*
递归地返回一个带有一堆迭代器的模块。
通常您只对 AST 的某些部分感兴趣并想跳过其他部分。DefaultIteratorArgument
是一个模块,其enter_*
and exit_*
没做什么。你的IteratorArgument
模块应包括DefaultIteratorArgument
继承此默认行为,然后仅实现执行特殊操作的部分。
如果您不仅想遍历类型化 AST,还想修改其中的某些部分,请使用TypedtreeMap
代替TypedtreeIter
。有一个小例子TypedtreeMap
at https://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=default https://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=default.
(我不使用 ocamlbuild,所以我无法帮助这一点。)