问题描述
|
我在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”类型。即,如果在
expression.ml
中定义(使用type expr = ...
),则应使用
%type <Expresssion.expr> main
使用模块名称时,请注意大写字母“ 7”。
, 我不确定我是否正确理解。
但是,您是否在循环依赖中挣扎?假设T
包含您的类型并调用解析器P
。 P
不能产生T.t
类型,因为T
取决于P
,而不是相反。通常,我已经创建了第三个文件,其中包含类型信息ѭ14。
例如,
毫升
let parse filename : T\'.t =
filename
|> open_in
|> Lexing.from_channel
|> P.command L.token
下午
%type <T\'.t> command
%start command
%%
T \'。ml
type t = Label of String
| Integer of String
| Float of string
| Star of t
, Ocamlyacc不允许您指定要在界面(.mli
)文件中生成的文本。因此,无论您在接口中指定哪种类型(令牌或规则的类型),都需要使用完全限定的类型。
在这里看起来您可以使用完全限定的类型,但是有时这是不可能的,因为该类型涉及函子应用程序。有几种解决方法:
安排在单独的编译单元中构建所有函子。这很容易,但是不起作用,例如如果函子涉及令牌类型。
对ocamlyacc生成的.mli
文件进行后处理以添加标题。您可以通过这种方式做几乎所有事情,但这很丑陋和令人讨厌。
使用Menhir,这是Ocamlyacc的改进替代品。这是一个附加的依赖项,但确实解决了Ocamlyacc的主要缺点。