OCaml PPXes return 扩展可以被其他 PPX 扩展解析吗?

Can OCaml PPXes return extensions to be parsed by other PPX extensions?

给定如下所示的语法扩展

let a = [%jsx div className="hello"]

我有一个 PPX 可以将它转换成(类似的东西)

let a = ReactJS.create_element "div" ~props:(object%js val className = "hello" end)

我需要 OCaml 来后续转换 %js 语法扩展,它由 js_of_ocaml 提供。

但是,从表面上看,PPX 扩展只对源进行一次传递,而不是递归地应用它。

有可能做到吗?或者我是否需要尝试将 js_of_ocaml PPX 和 运行 导入我自己的?或者是简单地去掉中间人并在我自己的代码中产生相同转换的最佳方法?

编辑 - 更多信息:

因此,应用 PPX 的顺序似乎不是这里的问题。我得到以下信息:

+ ocamlfind ocamlc -c -package reactjs,reactjs_ppx,react,js_of_ocaml,js_of_ocaml.ppx -o tutorial.cmo tutorial.ml File "tutorial.ml", line 3, characters 14-99: Uninterpreted extension 'js'.

我感觉我(又)产生了错误的 AST。 用于生成 js%object 的代码如下所示:

Exp.extension ({txt="js"; loc=loc}, PStr [ Str.eval ( Exp.object_ ( Cstr.mk (Pat.any ()) fields ) ) ] )

是的,您可以创建一个具有多个 -ppx <ppx> 编译器选项的 PPX 链:

ocamlc -ppx a -ppx b input.ml

input.ml应该传递给PPXa,然后它的输出应该发送给b,最后输出给ocamlc.

使用 ocamlfind,您可以指定多个 PPX 包,例如:

ocamlfind ocamlc -package ppx_A,ppx_B input.ml

应用多个 PPX 预处理器。应用顺序应该根据ppx_Appx_B之间的包依赖关系来计算。如果ppx_B包依赖ppx_A,则无需提及ppx_Aocamlfind ocamlc -package ppx_B input.ml自动在ppx_B之前应用ppx_A

是的,正如camlspotter所说,你可以做到,但它会有点脆弱(你需要依赖ppx应用程序的顺序)。

请不要在您的应用程序中复制 js_of_ocaml 的 ppx(或尝试进行相同的转换,这是一个复杂的转换)。如果我们更新 ppx,它将中断。

我一直在考虑将 ppx 的某些部分公开为一个库(特别是映射器),供您使用。你能联系 js_of_ocaml 错误跟踪器吗?