OCaml指定ppx可执行文件的路径

时间:2018-03-31 02:41:50

标签: ocaml ppx

我正在尝试弄清楚如何传递可执行文件的位置作为OCaml编译器ppx / ocamlc的{​​{1}}过滤器运行。

我的问题基本上是

  • ppx过滤器应采用什么格式作为输入?
  • 预计会生产什么?
  • 具体是ocamlopt,如何将其配置为接受所需格式并发出所需格式?
  • 为什么cppo不能作为“身份过滤器”使用并且根本不使用过滤器产生相同的结果?

例如,这是一个简单的OCaml程序。

cat

使用一个完全无关紧要的过滤器(* foo.ml *) let hi = ();; Printf.printf "hi there\n" ,我们可以看到过滤器应该作为输入处理什么样的东西。

cat

它看起来像某种二进制格式,也许是AST表示?

$ ocamlopt -ppx cat foo.ml | cat -v Caml1999M019M-^DM-^U??^@^@^@^G^@^@^@^A^@^@^@^C^@^@^@^B&foo.m ... File "foo.ml", line 1: Error: External preprocessor does not produce a valid file 没有配置选项,在使用显式文件调用时处理文本OCaml源文件。我有点困惑为什么它在以这种方式调用时会发出cppo指令...我相信这些指令对C编译器有意义,但对OCaml编译器没有意义。

例如:

#line

它在作为过滤器调用时有效,为行指令提供文件名$ cppo foo.ml # 1 "foo.ml" let hi = ();; Printf.printf "hi there\n"

<stdin>

阅读$ cat foo.ml | cppo # 1 "<stdin>" let hi = ();; Printf.printf "hi there\n" --help,没有提及输入和输出格式或cppo这样的论点,这有点令人失望。

你应该怎样做才能将所有碎片拼接在一起?

2 个答案:

答案 0 :(得分:1)

Ocaml编译器支持两个不同的预处理器系列:使用-pp选项调用的文本预处理器和使用-ppx选项调用的(二进制)AST预处理器。

文本预处理器应该将文本源文件的名称作为输入,并在stdout上输出OCaml源文件或OCaml二进制AST。对于那些,cat确实实现了身份地图:ocamlc -pp catocamlc。这些预处理器的一个重要限制是它们不能链接在一起。

相反,-ppx AST预处理器将输入AST二进制文件的名称和输出二进制AST文件的名称作为输入。换句话说,在这种情况下,身份地图可以使用cp实现:ocamlc -ppx cpocamlc。由于这些预处理器的输入和输出都是二进制AST,因此可以将多个ppx预处理器链接在一起。

cppo预处理器属于第一个系列,需要使用-pp

进行调用

答案 1 :(得分:0)

事实证明,我将ppx参数(包括扩展点)与camlp4(或可能是camlp5混淆,命名很奇怪,我并不完全理解它。)

camlp4 过滤器放在编译器前面的正确咒语似乎带有-pp标志

以下命令均生成a.out

$ ocamlc foo.ml
$ ocamlc -pp cat foo.ml
$ ocamlc -pp cppo foo.ml

有些令人惊讶的是,即使输出为空,这也有效。

$ ocamlc -pp /usr/bin/true foo.ml

以下命令都不会发出有效的OCaml并且不会产生任何内容

$ ocamlc -pp /usr/bin/false foo.ml
File "foo.ml", line 1:
Error: Error while running external preprocessor
$ ocamlc -pp /usr/bin/rev foo.ml
File "/var/.../ocamlpp27e608", line 1, characters 2-3:
Error: Syntax error