我是OCaml的新手,但它的文档让我哭了。 我想在ocaml上编写一个解析器并将其集成到c ++项目中。
我已经制作了c ++ - OCaml绑定,就像这里描述的那样 http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/calling_ocaml.html
所以我可以得到一个用这样的命令调用OCaml代码的可执行文件:
但后来我添加了“open Genlex ;;”以ocaml-called-from-c.ml为例,尝试编写简单的解析器,如下所述:
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Genlex.html
正如它所说: “人们应该注意到,只有通过camlp4扩展才能使用解析器关键字和流的相关表示法。这意味着必须对其源进行预处理,例如使用编译器的”-pp“命令行开关。” / p>
但
ocamlopt -pp camlp4 -o build / ocaml-called-from-c.cmx -c ocaml-called-from-c.ml
得
解析错误:entry [implem]为空 运行外部预处理器时出错 命令行:camlp4'ocaml-called-from-c.ml'>的/ tmp / ocamlpp162c63
没有-pp它落在:
解析器 |并[d n1 = parse_atom; n2 = parse_remainder n1>] - > N2
与
文件“ocaml-called-from-c.ml”,第99行,字符13-14: 错误:语法错误
答案 0 :(得分:1)
在我看来,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
。
这可能无法解决您的所有问题,但我希望它有所帮助。