在 OCaml .mll 程序中打开模块

Opening Modules in an OCaml .mll program

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

Error: Unbound module 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 ...

请注意,这不是 "open" 模块 StringMap。它只是定义模块。这很好,最好避免打开模块。

更新

如果你不打算在你的词法分析器中使用 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