ppx_driver (register_transformation_using_ocaml_current_ast) 的 AST 转换有什么好的用法示例?

Any good usage examples of an AST transformation with ppx_driver (register_transformation_using_ocaml_current_ast)?

tl;dr 我正在尝试使用 AST_mapperppx_driver 制作源转换二进制文件。我不知道如何获取 AST_mapper 文档中的示例以供 ppx_driver 使用。有没有关于如何使用 Ppx_driver.register_transformation_using_ocaml_current_ast 的好例子?

我正在尝试移植示例 AST_mapper in the docs to be compatible with ppx_driver. Specifically, I'm looking to create a binary that takes source as input, transforms the source using this test mapper, and then outputs the transformed source. Unfortunately, the 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"

注意几点:

不幸的是,将其编译成二进制文件后:

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 which uses Ppx_core.ContextFree (这似乎并不完整并且不适用于我的实际用例 - 但出于这个问题的目的,我试图保持一般适用的东西)。

有没有很好的例子说明如何正确执行此操作?为什么 ppx_driver 不使用我的转换?

如果你想用单个模块做一个独立的重写器,你需要添加

let () = Ppx_driver.standalone ()

到 运行 重写器并链接到 ppx_driver 而不是 ppx_driver.runnerppx_driver.runner 运行 驱动程序一旦加载,因此在您的转换被注册之前。另请注意,您至少应该指定一个特定的 Ast 版本并使用 Ppx_driver.register_transformation 而不是 Ppx_driver.register_transformation_using_current_ocaml_ast 否则使用 ppx_driver 而不是使用 [=17= 手动解析几乎没有意义] 和 Pparse 模块。