tl; dr我正试图使用AST_mapper
和ppx_driver
创建源转换二进制文件。我无法弄清楚如何在AST_mapper
文档中使用ppx_driver
文档。有没有关于如何使用Ppx_driver.register_transformation_using_ocaml_current_ast
的好例子?
我尝试移植示例AST_mapper
in the docs以与ppx_driver
兼容。具体来说,我希望创建一个以源为输入的二进制文件,使用此测试映射器转换源,然后输出转换后的源。不幸的是,default main provided by Ast_mapper
只接受Ocaml AST作为输入(并且可能将其作为输出产生)。这是不可取的,因为我不想通过ocamlc
和-dsource
来运行此操作来获取输出。
这是我最好的尝试移植它:
test_mapper.ml
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_driver
之前):Const_int 42
必须替换为Ast_helper.Const.int 42
test_mapper
为Parsetree.structure -> mapper
。 (我不清楚为什么递归变换需要结构来创建映射器,但无论如何。)但是,这种类型并不是Ppx_driver.register_transformation_using_ocaml_current_ast
所期望的。所以我写了一个草率的包装器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
在示例文件上运行它:
sample.ml
let x _ = [%test]
以下内容:
./test_mapper sample.ml
我没有看到任何转换发生(示例文件逐字回流)。更重要的是,我在代码中留下的日志记录Pprintast.expression
并没有打印任何内容,这表明我的映射器从不访问任何内容。
我在野外找到的所有例子都是Jane Street(他写ppx_*
)开源的,似乎要么没有记录他们的转变(也许还有一些?魔法检测正在进行中,或者如果他们they use Ppx_driver.register_transformation ~rules
使用Ppx_core.ContextFree
(这似乎并不完整并且不会为我工作真实的用例 - 但是出于这个问题的目的,我试图保持一般的适用性。)
有没有很好的例子说明如何正确地做到这一点?为什么没有ppx_driver
使用我的转换?
答案 0 :(得分:1)
如果您想使用单个模块制作独立的重写器,则需要添加
let () = Ppx_driver.standalone ()
运行重写器和链接ppx_driver
而非ppx_driver.runner
:ppx_driver.runner
在加载后立即运行驱动程序,因此在注册转换之前。另请注意,您至少应指定一个特定的Ast版本并使用Ppx_driver.register_transformation
而不是Ppx_driver.register_transformation_using_current_ocaml_ast
,否则使用ppx_driver
而不是使用{{1}手动解析}和compiler-libs
模块。