问题
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
?
回答1:
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 myMakefile
that simplyrm
it, but you might want to just add the necessary signatures instead). - use
menhir
as suggested in the bug report mentioned above.
回答2:
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.
来源:https://stackoverflow.com/questions/21490612/make-a-table-containing-tokens-visible-for-both-mly-an-mll