2016-01-29 7 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 
} 

Я тоже не понимаю, как модуль Make работает, и где оно происходит от. Примечание: В настоящее время я использую компилятор 4.02.1 ocaml.

ответ

2

Этот код определяет модуль Make, который является функтором. То есть он принимает модуль как параметр и возвращает модуль.

Параметр модуля, который он принимает, является произвольной монадой, которая в сущности является способом сказать, что происходит, когда вы делаете что-то, за которым следует что-то другое.

Вы можете найти описание монад здесь: 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) 

Первоначальное определение, кажется, не соответствует типу обработчика пополнения. (Но я мог бы что-то упустить, этот код требует многого.)