3

我想定义一个keyword_table将一些字符串映射到一些标记的 a,并且我想让这个表对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 *)
}

正如这个评论所暗示的,menhir有一个解决方案,谁能告诉我任何细节?

4

2 回答 2

3

第一个选项是在单独的.mly文件中定义标记。使用选项执行menhir此文件--only-tokens将生成一个模块,其中包含type token您可以在使用--external-tokens选项编译的解析器中使用的模块。

如果这解决了令牌问题,您可以按照 Thomash 的建议在单独的文件中指定解析器和词法分析器使用的所有其他函数。

还有一个替代解决方案。您可以在解析器中使用%parameter<module signature>声明,通过给定签名内指定的类型和函数注释对整个解析器进行参数化。主要优点是这个签名是在解析器的接口文件中提供的,所以解析器可以与其他模块共享这个签名(可以基于签名构造模块)。

我建议参考示例,即查看menhircalc-two了解外部令牌并calc-param了解如何创建参数化解析器。

于 2014-02-12T03:05:13.127 回答
0

我通常把它放进去keyword_tablelexer.mll我认为没有理由把它放进去parser.mly。如果您需要同时从lexer.mlland访问它parser.mly(但为什么要从 parser.mly 访问它?),最简单的解决方案是将它放在第三个文件中keyword.ml并使用Keyword.keyword_table(或open Keywordand keyword_table)。

于 2014-02-07T15:39:45.967 回答