0

I would like to define a keyword_table which maps some strings to some tokens, and I would like to make this table visible for both parser.mly and lexer.mll.

It seems that the table has to be defined in 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 ]
%}

However, I could NOT use it in lexer.mll, for instance

{
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 *)
}

Could anyone tell me where is the problem? Isn't it possible to make a data visible for both parser.mly and lexer.mll?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
SoftTimur
  • 5,630
  • 38
  • 140
  • 292

2 Answers2

0

Yes, it is fairly straightforward. You could simply place the data in a third .ml file and reference that:

In the .mly:

%{ 
    open Data
%}

In the .mll:

{
    open Data
}

You will not be able to refer to the internal definitions of parse.mly in other files. When ocamlyacc runs, it will generate a parse.mli that won't make them available.

gsg
  • 9,167
  • 1
  • 21
  • 23
  • 1
    except that the values in the hash table are most likely tokens that must be defined inside the `mly` file. – Virgile Feb 03 '14 at 13:45
0

As mentioned in gsg's answer, ocamlyacc generates a mli interface together with the ml implementation of the parser, and only exports the type of tokens and the entry points. According to http://caml.inria.fr/mantis/view.php?id=1703, this is unlikely to change, so you basically have two solutions:

  • modify the generated mli afterwards (I usually have a rule in my Makefile that simply rm it, but you might want to just add the necessary signatures instead).
  • use menhir as suggested in the bug report mentioned above.
Virgile
  • 9,724
  • 18
  • 42