tl;博士,我正在尝试使用
AST_mapper
和
ppx_driver
. 我不知道如何在
AST\U映射器
要使用的文档
ppx\U驱动程序
. 有没有关于如何使用的好例子
Ppx_driver.register_transformation_using_ocaml_current_ast
?
我正在尝试移植这个示例
AST_mapper
in the docs
与兼容
ppx\U驱动程序
. 具体来说,我希望创建一个二进制文件,该文件将源代码作为输入,使用此测试映射器转换源代码,然后输出转换后的源代码。不幸的是
default main provided by
Ast_mapper
仅接受Ocaml AST作为输入(并可能将其作为输出生成)。这是不受欢迎的,因为我不想把这件事做完
ocamlc
具有
-dsource
获取我的输出。
以下是我移植此功能的最佳尝试:
test\u映射器。毫升
open Asttypes
open Parsetree
open Ast_mapper
let test_mapper argv =
{ default_mapper with
expr = fun mapper expr ->
Pprintast.expression Format.std_formatter expr;
match expr with
| { pexp_desc = Pexp_extension ({ txt = "test" }, PStr [])} ->
Ast_helper.Exp.constant (Ast_helper.Const.int 42)
| other -> default_mapper.expr mapper other; }
let test_transformation ast =
let mapper = (test_mapper ast) in
mapper.structure mapper ast
let () =
Ppx_driver.register_transformation_using_ocaml_current_ast
~impl:test_transformation
"test_transformation"
需要注意的几点:
-
文档中的示例不是现成的(在介绍之前
ppx\U驱动程序
):
Const_int 42
必须替换为
Ast_helper.Const.int 42
-
出于某种原因
test_mapper
是
Parsetree.structure -> mapper
. (我不清楚为什么递归转换需要结构来创建映射器,但没关系。)但是,这种类型不是什么
Ppx\U驱动程序。使用\u ocaml\u current\u ast注册\u transformation\u
期望值。所以我写了一个草率的包装
test_transformation
使typechecker满意(这是基于
how
Ast_mapper.apply_lazy
appears to apply a mapper to an AST
因此从理论上讲,这应该是可行的)
不幸的是,在将其编译为二进制文件后:
ocamlfind ocamlc -predicates ppx_driver -o test_mapper test_mapper.ml -linkpkg -package ppx_driver.runner
并在示例文件上运行它:
样品毫升
let x _ = [%test]
具有以下功能:
./test_mapper sample.ml
我没有看到任何转换发生(示例文件是逐字返回的)。更重要的是,日志记录
Pprintast.expression
我在代码中留下的没有打印任何内容,这对我来说意味着我的映射器从未访问过任何内容。
我在野外找到的所有例子都是由Jane Street(他写道
ppx_*
)而且似乎要么没有注册他们的转换(也许有一些魔法检测正在进行,这在我的头上),要么如果他们注册了
they use
Ppx_driver.register_transformation ~rules
其中使用
Ppx_core.ContextFree
(这似乎不完整,对我的实际用例也不起作用——但就这个问题而言,我正试图保持事物的普遍适用性)。
有没有什么好的例子可以说明如何正确地做到这一点?为什么不
ppx\U驱动程序
使用我的转换?