2014-10-07 48 views
1

我不熟悉OCaml,但已参与分析一些OCaml代码。 这段代码令我困惑。基于运算符优先级,正确的分组是什么?OCaml优先

let new_fmt() = 
    let b = new_buf() in 
    let fmt = Format.formatter_of_buffer b in 
    (fmt, 
    fun() -> 
    Format.pp_print_flush fmt(); 
    let s = Buffer.contents b in 
    Buffer.reset b; 
    s 
) 

这里有三个操作符:“;”,“,”和“fun”。根据参考手册,优先级为 的顺序是逗号>分号>有趣,我相信会导致下面的分组。 哪一个是OCaml编译器挑选的?或者是否有另一个正确的分组?

分组1:

let new_fmt() = 
    let b = new_buf() in 
    let fmt = Format.formatter_of_buffer b in 
    ((fmt, 
    fun() -> 
    Format.pp_print_flush fmt()); 
    (let s = Buffer.contents b in 
    Buffer.reset b; 
    s) 
) 

分组2:

let new_fmt() = 
    let b = new_buf() in 
    let fmt = Format.formatter_of_buffer b in 
    (fmt, 
    (fun() -> 
    Format.pp_print_flush fmt(); 
    let s = Buffer.contents b in 
    (Buffer.reset b; 
    s)) 
) 

回答

1

分组2是正确的。

如果您不确定事情是如何解析的,编辑助手可能会帮助您(有时):ocaml-mode或tuareg-mode(以及其他编辑助手)应该为您提供与代码解析方式相对应的自动缩进:

let new_fmt() = 
    let b = new_buf() in 
    let fmt = Format.formatter_of_buffer b in 
    (fmt, 
     fun() -> 
     Format.pp_print_flush fmt(); 
     let s = Buffer.contents b in 
     Buffer.reset b; 
     s 
    ) 

let s = ...的identation低于fun() ->这意味着该部分是内fun() -> ...。如果它以外的fun() ->它应该以不同的方式缩进,在fun() ->的同一级别。

另一种非常精确但可能过于复杂的方法是检查代码是如何直接由ocamlc -dparsetree source.ml解析的。

2

对于它的价值,没有在代码中使用另算。它由无符号表示:将函数应用于OCaml中的值的操作由并列表示。该运算符的优先级高于其他运算符。

此代码

fun() -> a ; b 

解析为

fun() -> (a; b) 

不是

(fun() -> a) ; b 

它遵循,因为就像你说的;fun更高的优先级(尽管这个术语有点疑似)。

同样

let c = d in e; f 

解析作为

let c = d in (e; f) 

不是作为

(let c = d in e); f 

所以,最终的表达解析这样的:

(fmt, 
fun() -> (Format.pp_print_flush fmt(); 
      let s = Buffer.contents b in 
      (Buffer.reset b; s)) 
)