在Chapter 12 Lexer and parser generators中,我无法编译以下示例:
{
type token = EOL | INT of int | PLUS
module Make (M : sig
type 'a t
val return: 'a -> 'a t
val bind: 'a t -> ('a -> 'b t) -> 'b t
val fail : string -> 'a t
(* Set up lexbuf *)
val on_refill : Lexing.lexbuf -> unit t
end)
= struct
let refill_handler k lexbuf arg =
M.bind (M.on_refill lexbuf) (fun () -> k lexbuf arg)
}
refill {refill_handler}
rule token = parse
| [' ' '\t']
{ token lexbuf }
| '\n'
{ M.return EOL }
| ['0'-'9']+ as i
{ M.return (INT (int_of_string i)) }
| '+'
{ M.return PLUS }
| _
{ M.fail "unexpected character" }
{
end
}
我也不明白Make模块是如何工作的,以及它来自哪里。 注意:我目前正在使用4.02.1 ocaml编译器。
答案 0 :(得分:2)
此代码定义模块Make,它是一个仿函数。也就是说,它将模块作为参数并返回一个模块。
它接受的模块参数是一个任意的monad,它本质上是一种说明当你做一些其他东西时会发生什么的方法。
您可以在此处找到monad的说明:http://blog.enfranchisedmind.com/2007/08/a-monad-tutorial-for-ocaml
我通过将refill函数更改为:
来获取要编译的代码let refill_handler k lexbuf =
M.bind (M.on_refill lexbuf) (fun () -> k lexbuf)
原始定义似乎与补充处理程序的类型不匹配。 (但我可能会遗漏一些东西;这种代码需要很多习惯。)