如何通过OCamlbuild使用Menhir错误消息生成?

时间:2016-11-15 08:02:02

标签: makefile ocaml ocamlbuild menhir

我正在使用--compile-errors的{​​{1}}功能,我对它非常满意。我还使用menhir来管理项目的编译。由于该项目非常基础,到目前为止,构建基础设施仍然微不足道。

我在项目的根目录下有一个ocamlbuild文件和一个简单的_tags。我还没有Makefile个文件。 myocamlbuild.ml文件只包含一行:

_tags

Makefile的相关部分是

<src/*>: package(ppx_deriving.std)

OCamlbuild和Menhir通常很好地集成,但all: src/ParsingErrors.ml ocamlbuild $(OPTIONS) src/Main.native src/ParsingErrors.ml: src/Handcrafted.messages src/Parser.mly menhir --compile-errors src/Handcrafted.messages src/Parser.mly > src/ParsingErrors.ml OPTIONS = -j 4 -use-menhir -use-ocamlfind -yaccflag --table -pkgs menhirLib,str,unix 似乎是一个相当新的功能。我的设置并不理想,因为我不喜欢在我的源目录而不是构建目录中有一个自动生成的文件--compile-errors。向OCamlbuild解释我希望Menhir构建此错误消息文件的最佳方法是什么?更改我的文件的命名约定(例如,src/ParsingErrors.mlsrc/Parser.messages)如果它简化了事情,就不会打扰我。

注意:虽然我在其他项目中有src/Parser.ml个文件,但我是从在线资源中复制的。我发现它们难以破译,我不太懂得如何写这些东西。

2 个答案:

答案 0 :(得分:3)

寻找这个问题答案的最佳位置是Menhir的分布,因为Menhir在自己的编译过程中使用了“menhir --compile-errors”和ocamlbuild。

source tarball中要查找的文件为src/myocamlbuild.ml

以下是相关摘录:

(* This rule generates an .ml file [target] from an .mly file [grammar] and a
   .messages file [messages]. *)

(* If the name of a witness file is passed, it is made an additional
   dependency. This triggers a separate rule (see below) which performs a
   completeness check, that is, which checks that the .messages file lists
   every possible syntax error. *)

let compile_errors grammar messages (witness : string list) target =
  rule
    "menhir/compile_errors"
    ~prod:target
    ~deps:([ grammar; messages ] @ witness)
    (fun env _ ->
      let grammar = env grammar in
      let tags = tags_of_pathname grammar ++ "ocaml" ++ "menhir" in
      Cmd(S[
        !Options.ocamlyacc; (* menhir *)
        T tags;
        P grammar;
        A "--compile-errors"; P (env messages);
        Sh ">"; Px (env target);
      ]))

(* A generic version of the above rule, with uniform naming. *)

let generic_compile_errors (check_completeness : bool) =
  compile_errors
    (* sources: *)
    "%.mly" "%Messages.messages"
    (* if present, this dependency forces a completeness check: *)
    (if check_completeness then [ "%Messages.witness" ] else [])
    (* target: *)
    "%Messages.ml"

我很乐意与ocamlbuild维护者讨论是否可以将Menhir的myocamlbuild.ml的某些部分移动到ocamlbuild的标准规则集中。 (嗨加布里埃尔!)

答案 1 :(得分:2)

当前的ocamlbuild版本确实不支持该功能。要在myocamlbuild.ml插件中添加它,您必须定义新的构建规则。如果您对myocamlbuild.ml内的内容感到害怕,您可能会对新的ocamlbuild manual感兴趣,尤其是its section on plugins

我刚刚在ocamlbuild存储库上打开了issue report #121来跟踪这个缺失的功能。您是否有兴趣学习ocamlbuild为此编写适当的规则并将其贡献给下一个ocamlbuild版本?如果是的话,请随意使用github问题并开始询问如何实现它,我很乐意提供帮助。如果没有,我会在有空的时候尝试自己实施。

与此同时,请注意,为特定文件定义一次性规则要比一般规则容易得多。如果您准备硬编码您使用的源文件,您可能会看到与Makefile规则非常相似的内容。我今天没有时间写这个规则并且检查这个规则,但如果其他人没有在中间做过,我明天会回来。