Reputation: 313
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.
Upvotes: 10
Views: 2010
Reputation: 23839
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.
Upvotes: 11
Reputation: 107849
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:
.mli
file to add a header. You can do pretty much anything this way, but it's ugly and annoying.Upvotes: 1
Reputation: 47944
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
Upvotes: 2