如何使用Genlex构建OCaml源代码

时间:2014-07-13 08:14:54

标签: c++ linux bash gcc ocaml

我是OCaml的新手,但它的文档让我哭了。 我想在ocaml上编写一个解析器并将其集成到c ++项目中。

我已经制作了c ++ - OCaml绑定,就像这里描述的那样 http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/calling_ocaml.html

所以我可以得到一个用这样的命令调用OCaml代码的可执行文件:

  • cat build.sh
  • #/ bin / bash
  • mkdir -p build
  • 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 < / LI>

但后来我添加了“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'&gt;的/ tmp / ocamlpp162c63

没有-pp它落在:

解析器              |并[d n1 = parse_atom; n2 = parse_remainder n1&gt;] - &gt; N2

文件“ocaml-called-from-c.ml”,第99行,字符13-14: 错误:语法错误

1 个答案:

答案 0 :(得分:1)

在我看来,Genlex旨在快速破解。如果您的语言非常有趣,您可能需要查看Menhir,正如Basile Starynkevitch所建议的那样。

Genlex文档告诉您的是make_lexer函数使用流。虽然流本身是核心语言的一部分(在Stream module中),但酷流语法是OCaml的扩展。语法曾经是语言的一部分,但不久之前已被移出到扩展中。

目前,OCaml的语法扩展区域处于一种相当流畅的状态。我可以找到Stream扩展的最完整描述是Chapter 2 of the old camlp4 manualOCaml.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.ogl.cmx

这可能无法解决您的所有问题,但我希望它有所帮助。