【问题标题】:Using external type declarations with OCamlyacc在 OCamlyacc 中使用外部类型声明
【发布时间】:2011-09-15 15:13:37
【问题描述】:

我在 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 类型并将其用作我的规则的返回值?谢谢。

【问题讨论】:

    标签: ocaml parser-generator ocamlyacc


    【解决方案1】:

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

    %type <Expresssion.expr> main
    

    使用模块名时注意大写E

    【讨论】:

      【解决方案2】:

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

      但是您正在为循环依赖而苦苦挣扎?假设T 包含您的类型并调用解析器PP 不能生成 T.t 类型,因为 T 依赖于 P,而不是相反。通常,我创建了包含类型信息的第三个文件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
      

      【讨论】:

        【解决方案3】:

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

        在这里,您似乎可以使用完全限定类型,但有时这是不可能的,因为该类型涉及函子应用程序。有几种解决方法:

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

        【讨论】:

          猜你喜欢
          • 2018-05-25
          • 1970-01-01
          • 1970-01-01
          • 2014-12-10
          • 1970-01-01
          • 1970-01-01
          • 2016-04-26
          • 1970-01-01
          相关资源
          最近更新 更多