tl;博士我正在尝试使用AST_mapperand制作源转换二进制文件ppx_driver。我不知道如何获取AST_mapper文档中的示例以供ppx_driver. 有没有很好的使用示例Ppx_driver.register_transformation_using_ocaml_current_ast?
我正在尝试AST_mapper将文档中的示例移植到与ppx_driver. 具体来说,我希望创建一个以源为输入的二进制文件,使用此测试映射器转换源,然后输出转换后的源。不幸的是,由提供的默认 mainAst_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来让类型检查器开心(这是松散地基于如何Ast_mapper.apply_lazy将映射器应用于 AST,所以理论上它应该可以工作)
不幸的是,在将其编译成二进制文件后:
ocamlfind ocamlc -predicates ppx_driver -o test_mapper test_mapper.ml -linkpkg -package ppx_driver.runner
并在示例文件上运行它:
样本.ml
let x _ = [%test]
具有以下内容:
./test_mapper sample.ml
我没有看到任何转换发生(示例文件逐字反刍)。更重要的是,我在代码中留下的日志Pprintast.expression没有打印任何内容,这表明我的映射器从不访问任何内容。
我能够在野外找到的所有示例都是由 Jane Street(谁写的)开源的,ppx_*并且似乎没有记录它们的转换(也许有一些神奇的检测正在发生在我的脑海中)或者如果他们这样做了他们使用Ppx_driver.register_transformation ~rules哪些用途Ppx_core.ContextFree(这似乎并不完整,并且不适用于我的实际用例 - 但出于这个问题的目的,我试图让事情普遍适用)。
有没有很好的例子说明如何正确地做到这一点?为什么不ppx_driver使用我的转换?