2016-04-11 61 views
2

给定一个语法扩展,看起来像这样OCaml PPXes是否可以返回要由其他PPX扩展解析的扩展?

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

我已经得到了它转换为(像)

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

我需要的OCaml随后转变%JS语法扩展一个PPX,它由js_of_ocaml提供。

但是,从外观上看,PPX扩展的东西在源代码上做了一个遍历,并且不会递归应用它。

它可以这样做吗?或者我需要尝试导入js_of_ocaml PPX并在我自己的内部运行它?或者是在我自己的代码中简单地删除中间人并产生相同转换的最佳方法?

编辑 - 更多信息:

因此,它不会出现被应用PPXes的顺序是这里的问题。我得到如下:

+ 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 ) ) ] )

回答

2

是的,您可以像camlspotter说的那样做,但会变得脆弱(您需要依赖ppx应用程序的顺序)。

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

我一直在考虑将ppx的某些部分作为一个库(特别是mapper)公开,然后您可以使用它。您可以联系js_of_ocaml错误跟踪器吗?

+0

完成 - https:// github。com/ocsigen/js_of_ocaml/issues/460 –

+0

所以事实证明,我需要的东西已经导出 - 我只需要把它放到我的项目中,现在一切都很开心! –

1

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

ocamlc -ppx a -ppx b input.ml 

input.ml应该传递给PPX a,那么它的输出应该发送到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

+0

所以我偷看了订购的东西,它看起来不是这个问题:我已经更新了这个问题,以反映这个问题 –