我想定义一个将一些字符串映射到一些标记的keyword_table
,我想让这个表对parser.mly
和lexer.mll
都可见。
似乎该表必须在parser.mly
中定义,
%{
open Utility (* where hash_table is defined to make a table from a list *)
let keyword_table = hash_table [
"Call", CALL; "Case", CASE; "Close", CLOSE; "Const", CONST;
"Declare", DECLARE; "DefBool", DEFBOOL; "DefByte", DEFBYTE ]
%}
但是,例如,我无法在lexer.mll
中使用它
{
open Parser
let x = keyword_table (* doesn't work *)
let x = Parser.keyword_table (* doesn't work *)
let x = Parsing.keyword_table (* doesn't work *)
}
谁能告诉我问题出在哪里?难道不能使数据对parser.mly
和lexer.mll
都可见吗?
正如 gsg 的回答中提到的,ocamlyacc
与解析器的ml
实现一起生成一个mli
接口,并且只导出令牌的类型和入口点。根据 http://caml.inria.fr/mantis/view.php?id=1703 的说法,这不太可能改变,因此您基本上有两种解决方案:
- 之后修改生成的
mli
(我通常在Makefile
中有一个规则,只是简单地rm
它,但您可能只想添加必要的签名)。 - 按照上述错误报告中的建议使用
menhir
。
是的,这相当简单。您可以简单地将数据放在第三个 .ml 文件中并引用:
在 .mly 中:
%{
open Data
%}
在 .mll 中:
{
open Data
}
您将无法在其他文件中引用parse.mly
的内部定义。当ocamlyacc
运行时,它将生成一个无法使它们可用的parse.mli
。