2014-07-13 3 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

這可能不能解決你所有的問題,但我希望它有幫助。