在OCaml.mll程序中打开模块

在OCaml.mll程序中打开模块,ocaml,Ocaml,我是OCaml新手,我一直在研究一个解析器(.mll文件)。我在代码中的某个地方使用了StringMap,我不确定在哪里以及如何打开模块。当我运行它时,它说 错误:未绑定模块StringMap 所以我知道我必须做module StringMap=Map.Make(String),但是我应该把它放在哪里呢 代码如下: { type token = EOF | Word of string } rule token = parse (*...*) { (* use StringMap

我是OCaml新手,我一直在研究一个解析器(.mll文件)。我在代码中的某个地方使用了StringMap,我不确定在哪里以及如何打开模块。当我运行它时,它说

错误:未绑定模块StringMap

所以我知道我必须做
module StringMap=Map.Make(String)
,但是我应该把它放在哪里呢

代码如下:

{ type token = EOF | Word of string }

rule token = parse (*...*)
{   
    (* use StringMap in here *)
}
这应该行得通

{
  module StringMap = Map.Make(String)

  type token = EOF | Word of string
}

rule token = parse ...
请注意,这不会“打开”模块
StringMap
。它只是定义了模块。这很好,最好尽可能避免打开模块

更新

如果您不打算在lexer中使用
StringMap
模块(经过一段时间的思考,我认为您可能不会),您可以这样做:

{ type token = EOF | Word of string }

rule token = parse ...

{
    module StringMap = Map.Make(String)

    ... any other code ...
}
更新2

下面是一个完整的工作示例。我希望这不是矫枉过正;我不想失去它的乐趣

{ }

rule scan = parse
  | '\n'        { scan lexbuf }
  | _ as c      { Some c }
  | eof         { None }

{
  module CharMap = Map.Make(Char)

  let main () =
    let lexbuf = Lexing.from_channel stdin in
    let rec loop map =
        match scan lexbuf with
        | Some c ->
            let map' =
                if CharMap.mem c map then
                    CharMap.add c (CharMap.find c map + 1) map
                else
                    CharMap.add c 1 map
            in
            loop map'
        | None -> map
    in
    let m = loop CharMap.empty in
    CharMap.iter (fun c ct -> Printf.printf "%c %d\n" c ct) m

  let () = main ()
}
这对我很有用:

$ ocamllex l.mll
4 states, 257 transitions, table size 1052 bytes
$ ocamlc -o l l.ml
$ echo swell | l
e 1
l 2
s 1
w 1

谢谢你,杰弗里!!!我花了30分钟把它放在每个地方,除了那一个…我只是有一个简单的附加问题。Jeffrey,对于两个花括号之间规则标记后面的代码位,它必须是1个函数吗?它可以是任何代码,而不仅仅是一个函数。(见更新)嗯,我试过了,但每当我放一行不是函数的一部分时,它就会给我一个语法错误。例如,我有
module StringMap=Map.Make(String)
后跟(在另一行上)
让lexbuf=Lexing.from\u channel stdin在//more code
中,上面的一行抛出语法错误。语法错误不是因为那里有额外的代码。这只是代码中的一个语法错误。您确实可以拥有任何可能出现在.ml文件中的代码。(要理解这一点,您可以查看生成的.ml文件。)