Using external type declarations with OCamlyacc
Asked Answered
C

3

10

I have a type expr in an expr.ml file. In parser.mly (OCamlyacc file), I define the expr rule and give the type :

    %start expr
    %type <expr> expr

However, I get :

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

I tried adding

    %{
      open Expr
    %}

at the beginning of the .mly file but it still doesn't work. How may I define this expr type in an external file and use it as the return value of my rule? Thanks.

Cecillececily answered 15/6, 2011 at 15:1 Comment(0)
I
11

You need to qualify expr type with the module name. I.e., if it is defined in expression.ml (using type expr = ...) you should use

%type <Expresssion.expr> main

Note the capital E when using the module name.

Impute answered 15/6, 2011 at 17:7 Comment(0)
C
2

I"m not sure if I'm understanding correctly.

But you are struggling with a circular dependency? Let's say T contains your type and calls the parser, P. P cannot produce type T.t since T depends on P, not the other way around. Normally, I've created a third file that contains the type information, T'.

For example,

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
Christiachristian answered 15/6, 2011 at 15:28 Comment(0)
V
1

Ocamlyacc doesn't let you specify text to be generated in the interface (.mli) file. So wherever you specify a type that goes into the interface (the type of a token or rule), you need to use a fully-qualified type.

Here it looks like you can use a fully-qualified type, but sometimes that's not possible because the type involves a functor application. There are several workarounds:

  • Arrange to build all functors in a separate compilation unit. This is easy, but doesn't work e.g. if the functors involve the token type.
  • Do post-processing on the ocamlyacc-generated .mli file to add a header. You can do pretty much anything this way, but it's ugly and annoying.
  • Use Menhir, an improved replacement of Ocamlyacc. It's an additional dependency, but it does solve Ocamlyacc's main shortcomings.
Vagabond answered 16/6, 2011 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.