我想预处理OCaml代码段,并根据某些表达式的类型对代码段进行一些修改。例如,如果代码段包含:
(f [1;2;3])
我会在f中添加另一个参数:
(f [1;2;3] [[0]])
但如果我看到类似的东西:
(f ["a"; "b"])
然后我可能想:
(f ["a"; "b"] [[""]])
我正在看camlp4,虽然我并不彻底;我认为camlp4没有关于表达式的类型信息。
我有什么方法可以做到这一点? 谢谢!
答案 0 :(得分:1)
CamlP4是解析树级别的预处理器,尚未进行类型检查。因此,编写依赖于类型的行为......并非不可能,但非常困难:您需要将P4解析树发送到您可能已修改的OCaml类型检查器,然后从中检索键入的AST,然后将其转换回P4的无类型树,不知何故。 P4的特殊AST数据类型使得这非常难以实现。此外,人们现在正在远离P4: - (
使用新的-ppx框架对类型进行OCaml预处理要容易得多,因为它可以更好地访问编译器内部。这不是很容易,但足够可行。如果你真的想要你的类型相关的预处理,我建议使用ppx。主要任务是:
https://bitbucket.org/camlspotter/compiler-libs-hack解释了如何实现这种类型的ppx预处理器。我希望它可以帮助你。
答案 1 :(得分:0)
这种基于类型的转换非常脆弱,例如您如何处理:
f []
或
let g x = f x
如果你只需要它来处理常量文字表达式(你的例子都是)的参数,那么你可以用camlp4或ppx做一些事情。 (ppx是首选,因为它是一种更简单的方法,但它只适用于OCaml版本4.02)。
因此,对于ppx,您可以找到应用于某些文字表达式的f
的每个用法,并添加相应的额外参数。就个人而言,我认为这种预处理在代码中应该是显而易见的,所以我可能会使用:
[%f [1; 2; 3]]
而不是:
f [1; 2; 3]
用于语法(4.02中添加了[%id ...]
语法,专门用于语法扩展)。