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

2023-12-24

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


假设您已经获得了类型的 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,所以我无法帮助这一点。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 似乎有时 Delphi 是区分大小写的 - “覆盖方法应该与祖先的大小写匹配”

    今天我遇到了一个 奇怪 的提示 覆盖方法 xxxx 应匹配祖先 yyyy 的大小写 解决方案是完全按照祖先中的方式声明方法名称 我相信这是自 Delphi Net 编译器以来编译器中保留的东西 与祖先中完全相同的方法声明方法使编译器 沉默
  • 如何强制 OCaml 推断出更通用的类型?

    我想定义一个接受可选参数的函数 该参数是一个函数 a gt b 默认值应该是identity 实际上就是 a gt a 但我认为没有理由它不应该与更通用的兼容 a gt b 当我尝试时 let optional apply f i matc
  • 编译器琐事:这段代码的结果是什么

    我今天正在审查一些代码 并遇到了一些代码 此片段准确地描述了 public abstract class FlargBase public FlargBase this DoSomething public abstract void Do
  • ubuntu 的 CSS 更少(并且自动编译)? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我尝试过 simples 但现在 l
  • 野牛语义类型检查分析

    我一直试图到处寻找例子 但徒劳无功 我正在尝试编写一个基本的 Ruby 解释器 为此 我编写了一个 Flex 词汇文件 其中包含标记识别句子和一个语法文件 我希望我的语法包含语义类型检查 我的语法文件包含 例如 arg arg arg 这应
  • 为什么计算斐波那契数需要很长时间?

    几天前我开始学习Ocaml 我尝试编写一个斐波那契数字程序 let rec fib a if a 1 a 2 then 1 else fib a 1 fib a 2 该代码不是最佳的 因为我不知道如何处理异常情况 但现在 如果我尝试计算 f
  • 非模板类与模板类的多个定义

    为什么编译器会抱怨多个 cpp 文件中定义的非模板类 但对于其定义在各个 cpp 文件中重复的模板类 通过包含该类的 inl 文件 却没问题 即使类是否在多个 cpp 文件中显式实例化 非模板情况是因为在这种情况下您的程序违反了一个定义规则
  • OCaml - 什么数据类型是 some 和 none?

    如果我正在使用Some and None列表中的组合 列表的数据类型是什么 是不是总是 a 或者有某种类型Some None let listVar type here list Some 4 Some 3 None Some 2 如果我把
  • ocaml 命令行找不到“topfind”

    我已经安装了opam run opam init run opam switch 4 06 0这创造了一个4 06 0里面的目录 opam 运行 评估opam confing env 出口 OCAML TOPLEVEL PATH as op
  • 寻找有效的移位/加法/LEA 指令序列来乘以给定常量(避免 MUL/IMUL)

    我正在尝试编写一个 C 程序 mult c 它有一个接收 1 个 int 参数的 main 函数 用atoi argv 1 这是一些常数k我们想要乘以 该程序将生成一个汇编文件mult s实现 int mult int x return x
  • 如何在 Ocaml 中表示一个简单的有限状态机?

    我用 C 和 Java 编写过一些状态机 但从未用过像 Ocaml 这样的函数式语言 问题是我不知道我是否可以从对象语言版本中调整代码 因为在 Ocaml 中记录和变体比类更强大 所以 我需要一个事件驱动的有限状态机 像 UML 中的分层结
  • 使 C# 编译器相信执行将在成员返回后停止

    我认为目前这是不可能的 或者这是否是一个好主意 但这是我刚才正在考虑的事情 我使用 MSTest 对我的 C 项目进行单元测试 在我的一项测试中 我执行以下操作 MyClass instance try instance getValue
  • C# 编译器编译 .txt .obj .java 文件

    using System class Program public static void Main Console WriteLine Hello World Console ReadLine 我将文件另存为1 java 2 obj an
  • 将代码拆分为多个 .cpp 会减少编译时间吗?

    假设我正在处理一个相当复杂的课程 一半的方法已经完成并经过测试 但我仍在开发另一半 如果我将完成的代码放在一个 cpp 中 将其余代码放在另一个 cpp 中 那么当我仅更改 正在进行的 cpp 中的代码时 Visual Studio 或任何
  • Java代码编译器优化[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我想知道 给定一个 java 代码 我如何才能看到 Java 编译器如何优化它 有没有 JDK 工具可以实现这一点 试图用谷歌搜索 但没有
  • 编译过程

    谁能解释一下编译是如何工作的 我似乎无法弄清楚编译是如何工作的 更具体地说 这是一个例子 我正在尝试在 MSVC 6 中编写一些代码来加载 Lua 状态 我已经 设置库的附加目录并将文件包含到正确的目录中 使用 extern C 因为 Lu
  • 用ast重写代码; Python

    我正在学习 AST 它看起来很强大 但我很困惑代码去了哪里以及为什么它消失了 说我想重写 example def fake x n y useless list n return x as example def fake x n retu
  • 使用解析将 ** 运算符更改为幂函数?

    我的要求是将 运算符更改为幂函数 例如 1 Input B 2 Output power B 2 2 B 2 T 2 X Output power B 2 我写了下面的正则表达式来解决这个问题 rx r a zA Z0 9 a zA Z0
  • 如果内存是字节可寻址的,为什么我们需要对齐填充?

    既然我们可以单独寻址内存的每个字节 为什么编译器要格外小心以确保结构及其成员与内存中的 32 位边界对齐 我在这里可能是错的 但是在 32 位系统上 从 0x0800 开始获取 4 个字节是不是和从 0x0801 开始获取 4 个字节一样快
  • 最大方法名称长度

    有谁知道您选择的编程语言中方法名称的最大长度是多少 我本来打算将此作为一个 C 特定问题 但我认为了解整个范围会很好 还涉及哪些因素 语言规范对此有限制吗 What does the compiler limit it to 32 位和 6

随机推荐

  • Laravel 可选()如何工作?

    创建新模型时 我尝试使用optional 设置值时帮助程序分配值 然而 当user在此上下文中未设置对象 我收到此错误 Undefined property stdClass user this gt events gt create ca
  • jquery 效果突出显示在 asp.net 更新面板中不起作用

    我有两个更新面板如下 当单击链接按钮时我试图突出显示 div
  • 使用 purrr 的地图时出错,可能

    我正在尝试运行一个循环卡方dataframe 我在用着map and possibly 都来自purrr 即使抛出错误也允许循环运行 在我的 data frame 中的某个地方 我有一列显然少于两个值 我找不到它 但这就是为什么我要尝试跑步
  • 使用 .cer 文件签署 .exe(signtool.exe 要求的证书名称是什么?)

    我已经为我的课程购买了证书 我购买它的网站给我发了一份 cer file 43 一些 真的很长 名称 9962812767788 cer 没有发送任何其他文件 但我几乎 100 确定我不需要更多文件 当我点击它时 cer文件中 有如下信息
  • 通过配置选项将 CMake 与 icc 结合使用的推荐方法?

    我想将英特尔编译器 icc 或 icpc 与基于 CMake 的项目一起使用 在 Linux 上 我当然可以在调用 cmake 时导出 CXX 变量 例如喜欢 CXX icpc cmake 这很好用 不过 我想通过自定义选项提供此选择 为此
  • 错误:-[UIImage _deleteExternalReferenceFromPermanentLocation] 无法识别的选择器发送到实例

    当我删除包含图像 作为可转换值存储在外部记录中 的托管对象时 出现崩溃并出现以下错误 Terminating app due to uncaught exception NSInvalidArgumentException reason U
  • 如何获取 iOS 设备上关联接入点的 IP 地址

    使用案例 我们有一个 iOS 应用程序 您可以在 iOS 设备及其关联的无线接入点之间运行网络测试以测试吞吐量 该应用程序可以很好地获取 iOS 设备的 IP 地址 但用户必须输入接入点的 IP Problem 任务是获取关联接入点的 IP
  • SQL Server中唯一键是聚集索引还是非聚集索引?

    我是 SQL Server 新手 在学习聚集索引时 我感到很困惑 唯一键是聚集索引还是非聚集索引 unique key只保存列中唯一的值 包括null 所以根据这个概念 unique key应该是聚集索引 对吧 但当我读完这篇文章时 我感到
  • 陷入函数和布尔值的困境

    我有一个名为firstRun 其中我有两个定义的布尔值filesDeleted and dirsDeleted 也在函数里面我有if filesDeleted true dirsDeleted true 当我尝试调试应用程序时出现错误 Us
  • LINQ 内连接

    我有两个收藏 List
  • magento 肥皂 api v2 目录产品信息不工作

    当我如下调用api函数时 我收到以下错误 我确信所有传递的变量都设置正确 因为其他 magento api 函数工作得很好 产品不存在 错误 发生内部错误 我假设这是调用语法的错误 我找不到正确的调用示例目录产品信息使用 sku 而不是产品
  • Sugar ORM Android 具有多个数据库

    我正在尝试为具有多个数据库的多个用户创建一个应用程序 每次用户登录时 应用程序都会选择特定用户的数据库并从中获取值 是否可以使用 Sugar ORM 来实现它 因为在 Sugar ORM 中 我们只能在清单中指定一个数据库
  • 如何垂直对齐段落中的文本?

    我想知道如何对齐文本p元素垂直居中 这是我的风格 p event desc font bold 12px Helvetica Neue Helvetica Arial sans serif line height 14px height 3
  • Pygame碰撞代码

    首先 我必须说我是法国人 这样你就明白为什么我会犯所有这些错误 哈哈 我正在使用 python pygame 和 pymunk 开发一个物理游戏 一个球 我称之为 X 必须到达 Y 点 这是一款平台游戏 2d 游戏 为了帮助球到达 Y 点
  • 服务器端 d3 - 将 SVG 编码为 Base64 图像

    我正在尝试将 D3 图表编码为 base64 图像以在 HTML 电子邮件中使用 到目前为止我有 var express require express var app express var jsdom require jsdom app
  • 教程中发现 TensorFlow 错误

    我还敢问吗 目前这是一项新技术 我找不到解决这个看似简单的错误的方法 我要学习的教程可以在这里找到 http www tensorflow org tutorials mnist pros index html deep mnist for
  • 删除沙盒

    我还有一个关于应用程序沙箱的问题 所以我需要访问用户的主目录 同时应用程序应该能够关闭 Mac 这要求不使用沙箱 我的问题是我不知道如何删除沙箱以及如何将应用程序提交到 Mac App Store 我认为档案是沙盒的 因为我曾经打开过它一次
  • pycurl 和 SSL 证书

    我正在尝试编写 pycurl 脚本来访问安全站点 HTTPS c pycurl Curl c setopt pycurl USERAGENT Mozilla 5 0 Windows NT 6 1 WOW64 rv 8 0 Gecko 201
  • 共享主机上 OpenWebConfiguration 的 ASP.NET 安全异常

    将我的网站从本地开发环境移动到共享主机后 我得到 Security Exception Description The application attempted to perform an operation not allowed by
  • 如何在 OCaml 编译器中遍历类型化抽象语法树

    我正在尝试转储 OCaml 项目中所有标识符的类型信息 基本上与遍历类型化抽象语法树相同 https github com ocaml ocaml blob trunk typing typedtree mli https github c