制作一个包含令人可见的标记的表格.mly和.mll由menhir显示

时间:2014-02-07 07:20:01

标签: parsing ocaml lexical-analysis ocamllex menhir

我想定义一个keyword_table,它将某些字符串映射到某些标记,我希望这个表格对parser.mlylexer.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 *)
}

正如this comment所示,menhir有解决方案,有人可以告诉我任何细节吗?

2 个答案:

答案 0 :(得分:3)

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

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

还有另一种解决方案。您可以在解析器中使用%parameter<module signature>声明来对整个解析器进行参数化,而不是在给定签名内指定的类型和函数注释。主要优点是此签名在解析器的接口文件中提供,因此解析器可以与其他模块共享此签名(可以根据签名构建模块)。

我建议引用to menhir examples,即查看calc-two以了解外部令牌,并calc-param了解如何创建参数化解析器。

答案 1 :(得分:0)

我通常将keyword_table放在lexer.mll中,我认为没有理由将其放入parser.mly。 如果您需要从lexer.mllparser.mly访问它(但为什么要从parser.mly访问它?),最简单的解决方案是将其放在第三个文件中{{1}并使用keyword.ml(或Keyword.keyword_tableopen Keyword)。