我是 OCaml 的新手,但它的文档让我哭了。 我想在 ocaml 上编写一个解析器并将其集成到 c++ 项目中。
我已经使 c++ - OCaml 绑定(bind)正确,就像这里描述的那样 http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/calling_ocaml.html
所以我可以得到一个可执行文件,它使用这样的命令调用 OCaml 代码:
- cat 构建.sh
- #/bin/庆典
- mkdir -p 构建
- ocamlopt -c -o build/ocaml-called-from-c.cmx ocaml-called-from-c.ml
- ocamlopt -output-obj -o build/camlcode.o build/ocaml-called-from-c.cmx
- gcc -g -Wall -Wextra -c c-main-calls-ocaml.c -o build/c-main-calls-ocaml.o
- gcc build/camlcode.o build/c-main-calls-ocaml.o -lm -L ~/.opam/4.01.0/lib/ocaml -lasmrun -o c-main-calls-ocaml -ldl
但后来我添加了“open Genlex;;”到 ocaml-called-from-c.ml 并尝试编写简单的解析器,例如,如下所述:
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Genlex.html
正如它所说: “人们应该注意到,只有通过 camlp4 扩展才能使用解析器关键字和相关的流符号。这意味着必须对其源进行预处理,例如使用编译器的“-pp”命令行开关。”
但是
ocamlopt -pp camlp4 -o build/ocaml-called-from-c.cmx -c ocaml-called-from-c.ml
得到
解析错误:条目 [implem] 为空 运行外部预处理器时出错 命令行:camlp4 'ocaml-called-from-c.ml' >/tmp/ocamlpp162c63
没有 -pp 它落在:
解析器 | [< n1 = 解析原子; n2 = parse_remainder n1 >] -> n2
与
文件“ocaml-called-from-c.ml”,第 99 行,字符 13-14: 错误:语法错误
最佳答案
在我看来,Genlex 是为快速破解而设计的。如果您的语言非常有趣,您可能想要研究 Menhir,正如 Basile Starynkevitch 所建议的那样。
Genlex 文档告诉您的是,make_lexer
函数使用流。尽管流本身是核心语言的一部分(在 Stream module 中),但很酷的流语法是 OCaml 的扩展。语法曾经是语言的一部分,但不久前被移出到扩展中。
OCaml 的语法扩展领域目前处于相当不稳定的状态。我能找到的关于 Stream 扩展的最完整描述在 Chapter 2 of the old camlp4 manual 中。 .在 OCaml.org's Stream Expression page 也有很好的教程说明。 .
我能够使文档中的示例按如下方式工作。我在 OS X 10.9.2 上使用 OCaml 4.01.0。
我的源文件 gl.ml
看起来像这样。 (我添加了一个 main
函数。)
open Genlex
let lexer = make_lexer ["+";"-";"*";"/";"let";"="; "("; ")"]
let rec parse_expr = parser
| [< n1 = parse_atom; n2 = parse_remainder n1 >] -> n2
and parse_atom = parser
| [< 'Int n >] -> n
| [< 'Kwd "("; n = parse_expr; 'Kwd ")" >] -> n
and parse_remainder n1 = parser
| [< 'Kwd "+"; n2 = parse_expr >] -> n1+n2
| [< >] -> n1
let main () =
let s = Stream.of_channel stdin in
let n = parse_expr (lexer s) in
Printf.printf "%d\n" n
let () = main ()
我编译如下。
$ ocamlopt -o gl -pp camlp4o gl.ml
我运行如下:
$ echo '3 + (5 + 8)' | gl
16
因此,Genlex 可以发挥作用。
对于您的情况,我认为您的命令行如下所示:
$ ocamlopt -o gl.o -c -pp camlp4o gl.ml
这对我有用。它创建 gl.o
和 gl.cmx
。
这可能并不能解决您所有的问题,但希望对您有所帮助。
关于c++ - 如何使用 Genlex 构建 OCaml 源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24720757/