使用OCamlyacc的外部类型声明

时间:2011-06-15 15:01:43

标签: ocaml parser-generator ocamlyacc

我在expr.ml文件中有一个expr类型。在parser.mly(OCamlyacc文件)中,我定义了expr规则并给出了类型:

    %start expr
    %type <expr> expr

但是,我得到了:

    File "parser.mli", line 34, characters 48-52:
    Error: Unbound type constructor expr

我尝试添加

    %{
      open Expr
    %}
<。>在.mly文件的开头,但它仍然无法正常工作。如何在外部文件中定义此expr类型并将其用作规则的返回值?感谢。

3 个答案:

答案 0 :(得分:10)

您需要使用模块名称限定expr类型。即,如果在expression.ml中定义(使用type expr = ...),则应使用

%type <Expresssion.expr> main

使用模块名称时请注意大写E

答案 1 :(得分:2)

我不确定我是否理解正确。

但是你正在努力解决循环依赖问题?假设T包含您的类型并调用解析器PP无法生成T.t类型,因为T取决于P,而不是相反。{1}}通常,我创建了第三个文件,其中包含类型信息T'

例如,

T.ml

 let parse filename : T'.t =
     filename
         |> open_in
         |> Lexing.from_channel
         |> P.command L.token

P.mly

%type <T'.t> command
%start command
%%

T'.ml

type t = Label of String
       | Integer of String
       | Float of string
       | Star of t

答案 2 :(得分:1)

Ocamlyacc不允许您指定要在界面(.mli)文件中生成的文本。因此,无论您何时指定进入接口的类型(标记或规则的类型),都需要使用完全限定类型。

这里看起来你可以使用完全限定类型,但有时这是不可能的,因为类型涉及一个仿函数应用程序。有几种解决方法:

  • 安排在单独的编译单元中构建所有仿函数。这很容易,但不起作用,例如如果仿函数涉及令牌类型。
  • 对ocamlyacc生成的.mli文件进行后处理以添加标头。你可以用这种方式做任何事情,但它很丑陋而烦人。
  • 使用Menhir,改进Ocamlyacc。这是一个额外的依赖,但它确实解决了Ocamlyacc的主要缺点。