如何使用 Camlp4 进行编译?
How to compile using Camlp4?
我正在测试 Camlp4 中的引号。我的tester.ml程序如下:
open Camlp4.PreCast;;
let x = <:Cstm< x = 1 + 2 >>;;
let y = <:expr< let y = 1 + 2 >>;;
print_string "done";;
我尝试过以各种方式编译它,例如。
ocamlc -pp "camlp4of pa_extend.cmo -loc" -I +camlp4 tester.ml
但是生成的可执行文件没有按预期打印出来 "done"。我该如何编译这个文件?
camlp4 --help
说:
-loc <name> Name of the location variable (default: _loc).
您忘记了 -loc
的参数。您可以通过 ocamlc
的 -verbose
选项检查其结果。 (-verbose
真的很方便找出编译中到底发生了什么):
$ ocamlc -verbose -pp "camlp4of pa_extend.cmo -loc" -I +camlp4 tester.ml
+ camlp4of pa_extend.cmo -loc "tester.ml" > /blahblah//ocamlpp2f0635
输入的文件名tester.ml
不被视为文件名,而是被视为位置变量的名称。使用空输入 camlp4of
输出一个空程序并由 ocamlc
编译。这就是为什么最终的可执行文件什么都不做的原因。
您的代码包含一个奇怪的引用名称 Cstrm
,并且 let y = 1 + 2
不是表达式而是结构项。以下是最接近编译的代码之一:
(* compilable by ocamlc -pp "camlp4of pa_extend.cmo" -I +camlp4 tester.ml *)
open Camlp4.PreCast;;
let x _loc = <:expr< x = 1 + 2 >>;;
let y _loc = <:str_item< let y = 1 + 2 >>;;
print_string "done";;
您可以使用 -printer Camlp4OCamlPrinter
选项以人类可读的形式检查 CamlP4 的输出。这是使用 CamlP4 的另一个重要技术:
$ camlp4of pa_extend.cmo -printer Camlp4OCamlPrinter tester.ml
open Camlp4.PreCast
let x _loc =
Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "=")))),
(Ast.ExId (_loc, (Ast.IdLid (_loc, "x")))))),
(Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "+")))),
(Ast.ExInt (_loc, "1")))),
(Ast.ExInt (_loc, "2")))))
let y _loc =
Ast.StVal (_loc, Ast.ReNil,
(Ast.BiEq (_loc, (Ast.PaId (_loc, (Ast.IdLid (_loc, "y")))),
(Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "+")))),
(Ast.ExInt (_loc, "1")))),
(Ast.ExInt (_loc, "2")))))))
let _ = print_string "done"
我正在测试 Camlp4 中的引号。我的tester.ml程序如下:
open Camlp4.PreCast;;
let x = <:Cstm< x = 1 + 2 >>;;
let y = <:expr< let y = 1 + 2 >>;;
print_string "done";;
我尝试过以各种方式编译它,例如。
ocamlc -pp "camlp4of pa_extend.cmo -loc" -I +camlp4 tester.ml
但是生成的可执行文件没有按预期打印出来 "done"。我该如何编译这个文件?
camlp4 --help
说:
-loc <name> Name of the location variable (default: _loc).
您忘记了 -loc
的参数。您可以通过 ocamlc
的 -verbose
选项检查其结果。 (-verbose
真的很方便找出编译中到底发生了什么):
$ ocamlc -verbose -pp "camlp4of pa_extend.cmo -loc" -I +camlp4 tester.ml
+ camlp4of pa_extend.cmo -loc "tester.ml" > /blahblah//ocamlpp2f0635
输入的文件名tester.ml
不被视为文件名,而是被视为位置变量的名称。使用空输入 camlp4of
输出一个空程序并由 ocamlc
编译。这就是为什么最终的可执行文件什么都不做的原因。
您的代码包含一个奇怪的引用名称 Cstrm
,并且 let y = 1 + 2
不是表达式而是结构项。以下是最接近编译的代码之一:
(* compilable by ocamlc -pp "camlp4of pa_extend.cmo" -I +camlp4 tester.ml *)
open Camlp4.PreCast;;
let x _loc = <:expr< x = 1 + 2 >>;;
let y _loc = <:str_item< let y = 1 + 2 >>;;
print_string "done";;
您可以使用 -printer Camlp4OCamlPrinter
选项以人类可读的形式检查 CamlP4 的输出。这是使用 CamlP4 的另一个重要技术:
$ camlp4of pa_extend.cmo -printer Camlp4OCamlPrinter tester.ml
open Camlp4.PreCast
let x _loc =
Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "=")))),
(Ast.ExId (_loc, (Ast.IdLid (_loc, "x")))))),
(Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "+")))),
(Ast.ExInt (_loc, "1")))),
(Ast.ExInt (_loc, "2")))))
let y _loc =
Ast.StVal (_loc, Ast.ReNil,
(Ast.BiEq (_loc, (Ast.PaId (_loc, (Ast.IdLid (_loc, "y")))),
(Ast.ExApp (_loc,
(Ast.ExApp (_loc, (Ast.ExId (_loc, (Ast.IdLid (_loc, "+")))),
(Ast.ExInt (_loc, "1")))),
(Ast.ExInt (_loc, "2")))))))
let _ = print_string "done"