0

我试图弄清楚如何传递可执行文件的位置以作为ppxOCaml 编译器ocamlc/的过滤器运行ocamlopt

我的问题是,基本上

  • ppx 过滤器应该采用什么格式作为输入?
  • 预计会产生什么?
  • cppo具体的情况下,您如何配置它以接受所需的格式并发出所需的格式?
  • 为什么不cat作为“身份过滤器”工作并且根本不使用过滤器产生相同的结果?

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

(* foo.ml *)
let hi = ();;

Printf.printf "hi there\n"

使用一个非常简单的过滤器cat,我们可以看到过滤器期望处理什么样的东西作为输入。

$ 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

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

cppo,没有配置它的选项,在使用显式文件调用时处理文本 OCaml 源文件。我有点困惑为什么它在以#line这种方式调用时会发出指令……我相信这些指令对 C 编译器有意义,但对 OCaml 编译器没有意义。

例如:

$ 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"

阅读--helpfor cppo,没有提及输入和输出格式或类似的参数-ppx,这有点令人失望。

你应该怎么做才能把所有的碎片缝合在一起?

4

2 回答 2

2

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

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

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

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

于 2018-04-03T21:10:08.130 回答
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
于 2018-03-31T03:08:08.227 回答