2016-01-29 42 views
2

Chapter 12 Lexer and parser generators,我无法编译下面的例子:Ocamllex填充处理程序例如

{ 

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 
} 

我也不明白是怎么模块组成工作,并且它从何而来。 注意:我目前使用的是4.02.1 ocaml编译器。

回答

2

此代码定义了模块Make,这是一个仿函数。也就是说,它将模块作为参数并返回一个模块。

它接受的模块参数是一个任意的monad,它实质上是一种说明当你做某件事后跟其他事情发生时会发生什么的方式。

你可以找到单子的描述在这里:http://blog.enfranchisedmind.com/2007/08/a-monad-tutorial-for-ocaml

我的代码通过改变充功能这个编译:

let refill_handler k lexbuf = 
    M.bind (M.on_refill lexbuf) (fun() -> k lexbuf) 

原来的定义似乎并不匹配类型的重新加注处理程序。 (但是我可能会错过一些东西;这种代码需要很多适应。)