2

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_mapperParsetree.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使用我的转换?

4

1 回答 1

1

如果要使用单个模块制作独立的重写器,则需要添加

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而不是手动使用模块进行解析没有compiler-libs什么Pparse意义。

于 2018-01-15T18:46:36.630 回答