我正在尝试弄清楚如何传递可执行文件的位置作为OCaml编译器ppx
/ ocamlc
的{{1}}过滤器运行。
我的问题基本上是
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
这样的论点,这有点令人失望。
你应该怎样做才能将所有碎片拼接在一起?
答案 0 :(得分:1)
Ocaml编译器支持两个不同的预处理器系列:使用-pp
选项调用的文本预处理器和使用-ppx
选项调用的(二进制)AST预处理器。
文本预处理器应该将文本源文件的名称作为输入,并在stdout上输出OCaml源文件或OCaml二进制AST。对于那些,cat
确实实现了身份地图:ocamlc -pp cat
≡ocamlc
。这些预处理器的一个重要限制是它们不能链接在一起。
相反,-ppx
AST预处理器将输入AST二进制文件的名称和输出二进制AST文件的名称作为输入。换句话说,在这种情况下,身份地图可以使用cp
实现:ocamlc -ppx cp
≡ocamlc
。由于这些预处理器的输入和输出都是二进制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