2014-07-13 22 views
0

我是OCaml的新手,但其文档使我哭了。 我想在ocaml上编写一个解析器并将其集成到C++项目中。如何构建使用Genlex的OCaml源码

我做了C++ - OCaml的绑定权就像是这里描述 http://www.mega-nerd.com/erikd/Blog/CodeHacking/Ocaml/calling_ocaml.html

,所以我可以在调用OCaml的代码这样的命令的可执行文件:

  • 猫build.sh
  • #/斌/庆典
  • 的mkdir -p建立
  • ocamlopt -c -o建立/ ocaml的所谓从 - c.cmx ocaml-called-from-c.ml
  • ocamlopt -output-obj -o build/camlcode.o build/ocaml-called-from-c.cmx
  • gcc -g -Wall -Wtratra -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

但是后来我添加了“打开Genlex ;;”到ocaml-called-from-c.ml并尝试写例如简单的解析器,因为它说明如下:

http://caml.inria.fr/pub/docs/manual-ocaml/libref/Genlex.html

因为它说: “每个人都应该注意的是,使用解析器关键字和只有通过camlp4扩展才能获得流的相关表示法,这意味着必须使用编译器的“-pp”命令行开关预处理其源。

ocamlopt -pp camlp4 -o编译/ ocaml的所谓从 - c.cmx -c ocaml-called-from-c.ml

得到

解析错误:入门[implem]是空 错误,同时运行外部预处理器 命令行:camlp4 'ocaml-called-from-c.ml'>的/ tmp/ocamlpp162c63

而不-pp它落在:

解析器 | [< n1 = parse_atom; N2 = parse_remainder 1>] - > N2

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

+0

您可以尝试用'-syntax camlp4o'替换'-pp camlp4o'。 AFAIR pp用于指定camlp4的语法扩展。如果你使用ocamlfind来调用OCaml,它也会很好。如果你将链接粘贴到github上,我们可以很容易地解决你的问题。 – Kakadu

+0

看看[Menhir](http://gallium.inria.fr/~fpottier/menhir/),它有很好的文档记录! –

回答

1

在我意见,Genlex旨在用于快速入侵。正如Basile Starynkevitch所建议的,如果你的语言非常有趣,那么你可能想看看Menhir。

Genlex文档告诉你的是,make_lexer函数使用流。虽然流本身是核心语言的一部分(在Stream module中),但酷流语法是OCaml的扩展。语法曾经是该语言的一部分,但前一段时间被迁移到扩展中。

OCaml语法扩展的区域目前处于一种相当流畅的状态。我可以找到流扩展的最完整的描述是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

这可能不能解决你所有的问题,但我希望它有帮助。