用于检查OCaml代码是否编译的OCaml程序

时间:2011-02-19 21:08:42

标签: ocaml dynamic-compilation

我想编写一个具有compile函数的OCaml模块,该模块将接受包含OCaml程序的字符串,并将编译结果输出为Correct或Error,并在Error情况下输出该行的信息和第一个错误的字符。我不关心错误是什么(至少目前为止)。

基本模块类型为:

module type Compile =
    sig
        type result = Correct | Error of (int*int)
        val compile : string -> result
    end

至少有两种根本不同的方式来实现它:

  1. 快速入侵 - 将带有程序的字符串写入文件,使用Unix进程在命令行上调用ocamlc并解析stderr;
  2. 正确的方法 - 使用OCaml工具分析代码。
  3. 关于(1),我无法掌握stderr的内容。我开始使用 Unix.open_process_in,它将stdout重定向到in_channel,然后我可以读取。 由于ocamlc输出的编译错误转到stderr(而不是stdout),我试图使用

    let ic = Unix.open_process_in "ocamlc test.ml 2>&1" 
    

    以便stderr的内容在命令行重定向到stdout。这样,我希望,ic 将包含编译错误。不幸的是,情况并非如此,ic仅包含End_of_file

    然后我转到Unix.create_process命令,因为它允许我为out,in,err选择新的频道。但是我在选择这些频道时遇到了麻烦。出来的频道应该是什么,以便我可以在我的节目中阅读它?

    关于(2),您认为(合理)简单的方法是什么?

    非常感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

关于2),OCaml安装通常有一个compiler-lib目录,其中包含构成编译器的许多模块,包括解析器。这没有记录,但可用于编译和类型检查。对于解析,还有Camlp4,它可以用来做除了预处理之外的事情(我想你可以将Camlp4加载到你的程序中并将其用作库,可能在修补它之后),但是只包含语法而不是typechecker。

答案 1 :(得分:2)

关于1)我认为你做错了什么。在我的机器上:

> ocaml unix.cma
        Objective Caml version 3.12.0

# let ic = Unix.open_process_in "ocamlc test.ml 2>&1";;
val ic : in_channel = <abstr>
# input_line ic;;
- : string = "File \"test.ml\", line 1, characters 0-1:"
# input_line ic;;
- : string = "Error: I/O error: test.ml: No such file or directory"
# input_line ic;;
Exception: End_of_file.

对于Unix.create_process,一种方法是将Unix.stdin传递给new_stdout,以便您可以通过程序的标准输入读取流程的输出(假设您不知道)我想使用你的程序的标准输入来做其他事情)。 但更简单的方法是使用Unix.open_process_full

关于2)您可以尝试使用toplevellib.cma(但请注意,这完全没有记录且不受支持)。请查看分发中的toplevel/toploop.mli,特别是Toploop.execute_phrase