如何在OCaml编译器中遍历类型化的抽象语法树

Wei Chen

我正在尝试转储OCaml项目中所有标识符的类型信息,基本上与遍历类型化抽象语法树相同(https://github.com/ocaml/ocaml/blob/trunk/typing/typedtree.mli) 。由于我不熟悉OCaml编译器的代码库,因此不确定该编译器是否提供了api,因此我们可以轻松编写插件来完成这项工作,还是必须破解编译器代码?另外,这如何与OCamlbuild交互?感谢您的任何提示或建议。

卡姆斯波特

假设您已经拥有某种类型的AST类型structure

经典方法是简单地编写一个大的递归函数以自己遍历AST。

但是,现在TypedtreeIterOCaml编译器源代码中提供了可用的模块,并且已将其公开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_patternexit_pattern您无需担心递归遍历本身:这是函子的工作MakeIterator给定一个IteratorArgument模块,它将所有的enter_*exit_*递归地连接起来并返回带有一堆迭代器的模块。

通常,您只对AST的某些部分感兴趣,而想跳过其他部分。DefaultIteratorArgument是一个模块,其enter_*exit_*什么也不做。您的IteratorArgument模块应包括DefaultIteratorArgument继承此默认行为,然后仅实现执行某些特殊操作的部分。

如果您不仅要遍历键入的AST,还要修改其中的某些部分,请使用TypedtreeMap代替TypedtreeIterTypedtreeMaphttps://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=default上有一个小示例

(我不使用ocamlbuild,所以我无能为力。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Qt中设置编译器?

来自分类Dev

如何从Haskell中的语法规范构建抽象语法树?

来自分类Dev

如何在Xcode中更改编译器

来自分类Dev

编译器如何在内存中布置代码

来自分类Dev

使用抽象类型时的编译器错误

来自分类Dev

我如何为这样的抽象语法树构建解释器?

来自分类Dev

S表达式树到OCaml中的抽象语法树

来自分类Dev

填充如何在C编译器中工作

来自分类Dev

编译器如何从map中找出模板类型

来自分类Dev

如何在给定类型和名称的情况下在编译器中查找方法?

来自分类Dev

如何在LESS编译器中引发错误

来自分类Dev

编译器如何确定sml中的类型

来自分类Dev

如何在抽象语法树上递归进行“树遍历”?

来自分类Dev

如何在gitlab CI中检测编译器警告

来自分类Dev

如何在Python抽象语法树(AST)中获取实际的用户定义变量名?

来自分类Dev

编译器接受的OCaml中明显无效的幻像类型

来自分类Dev

如何从Haskell中的语法规范构建抽象语法树?

来自分类Dev

使用抽象类型时的编译器错误

来自分类Dev

如何在monodevelop中添加ac / c ++编译器?

来自分类Dev

OCaml变量类型:混淆编译器

来自分类Dev

如何在我的编译器中运行Java代码

来自分类Dev

C#编译器如何区分抽象方法的具体子类impl和抽象库中的重载?

来自分类Dev

如何从编译器中提取语法

来自分类Dev

如何在Google Closure编译器中为对象类型指定@param @return?

来自分类Dev

此代码如何在编译器中执行?

来自分类Dev

如何在Eclipse中重新启用编译器警告?

来自分类Dev

没有类型转换的 Java 编译器如何在子类中调用正确的 equals() 函数?

来自分类Dev

如何在cmake中自动查找编译器路径?

来自分类Dev

如何在 Lazarus IDE 中定义编译器符号?

Related 相关文章

  1. 1

    如何在Qt中设置编译器?

  2. 2

    如何从Haskell中的语法规范构建抽象语法树?

  3. 3

    如何在Xcode中更改编译器

  4. 4

    编译器如何在内存中布置代码

  5. 5

    使用抽象类型时的编译器错误

  6. 6

    我如何为这样的抽象语法树构建解释器?

  7. 7

    S表达式树到OCaml中的抽象语法树

  8. 8

    填充如何在C编译器中工作

  9. 9

    编译器如何从map中找出模板类型

  10. 10

    如何在给定类型和名称的情况下在编译器中查找方法?

  11. 11

    如何在LESS编译器中引发错误

  12. 12

    编译器如何确定sml中的类型

  13. 13

    如何在抽象语法树上递归进行“树遍历”?

  14. 14

    如何在gitlab CI中检测编译器警告

  15. 15

    如何在Python抽象语法树(AST)中获取实际的用户定义变量名?

  16. 16

    编译器接受的OCaml中明显无效的幻像类型

  17. 17

    如何从Haskell中的语法规范构建抽象语法树?

  18. 18

    使用抽象类型时的编译器错误

  19. 19

    如何在monodevelop中添加ac / c ++编译器?

  20. 20

    OCaml变量类型:混淆编译器

  21. 21

    如何在我的编译器中运行Java代码

  22. 22

    C#编译器如何区分抽象方法的具体子类impl和抽象库中的重载?

  23. 23

    如何从编译器中提取语法

  24. 24

    如何在Google Closure编译器中为对象类型指定@param @return?

  25. 25

    此代码如何在编译器中执行?

  26. 26

    如何在Eclipse中重新启用编译器警告?

  27. 27

    没有类型转换的 Java 编译器如何在子类中调用正确的 equals() 函数?

  28. 28

    如何在cmake中自动查找编译器路径?

  29. 29

    如何在 Lazarus IDE 中定义编译器符号?

热门标签

归档