2014-10-07 11 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)) 
)