2

我想预处理 OCaml 片段并根据某些表达式的类型对片段进行一些修改。例如,如果片段具有:

(f [1;2;3])

我会向 f 添加另一个参数,例如:

(f [1;2;3] [[0]])

.

但如果我看到类似的东西:

(f ["a"; "b"])

然后我可能想:

(f ["a"; "b"] [[""]])

我正在查看camlp4,尽管我对它并不彻底;我认为camlp4 没有关于表达式的类型信息。

有什么办法可以做到这一点吗?谢谢!

4

2 回答 2

1

CamlP4 是解析树级别的预处理器,尚未进行类型检查。因此,编写依赖于类型的行为……并非不可能,但非常困难:您需要将 P4 解析树发送到您可能修改过的 OCaml 类型检查器,然后从中检索类型化的 AST,然后以某种方式将其转换回 P4 的无类型化树。P4 的特殊 AST 数据类型使得这非常难以实现。此外,人们现在正在远离 P4 :-(

OCaml 使用其新的 -ppx 框架对类型进行预处理要容易得多,因为它可以更好地访问编译器内部。这不是很容易,但足够可行。如果您真的想要依赖类型的预处理,我建议使用 ppx。主要任务是:

  • 将无类型 Parsetree AST 发送到 OCaml 的类型检查器(可能进行一些修改)
  • 获取其完全类型化的 Typedtree AST,然后添加您想要的内容:在您的情况下,添加更多参数
  • 使用 Untypeast 模块将类型化的 AST 转换回 Parsetree
  • 输出最终的 Parsetree 作为预处理结果。

https://bitbucket.org/camlspotter/compiler-libs-hack解释了如何实现这种类型化的 ppx 预处理器。我希望它对你有帮助。

于 2014-11-03T01:54:53.157 回答
0

这种基于类型的转换是非常脆弱的,例如你做什么:

f []

或者

let g x = f x

如果您只需要它处理常量文字表达式的参数(您的两个示例都是),那么您可以使用camlp4或ppx做一些事情。(首选ppx,因为它是一种更简单的方法,但它仅适用于OCaml 4.02版)。

因此,使用 ppx 您可以找到f应用于某些文字表达式的所有用法并添加相应的额外参数。就个人而言,我认为这种预处理在代码中应该是显而易见的,所以我可能会使用:

[%f [1; 2; 3]]

而不是:

f [1; 2; 3]

用于语法(该[%id ...]语法是在 4.02 中添加的,专门用于语法扩展)。

于 2014-11-04T13:54:51.080 回答