4

我想轉儲OCaml項目中的所有標識符的類型信息,基本上與遍歷鍵入的抽象語法樹(https://github.com/ocaml/ocaml/blob/trunk/typing/typedtree.mli)相同。由於我是OCaml編譯器的代碼庫新手,我不確定編譯器是否提供了apis,因此我們可以輕鬆編寫一個插件來完成這項工作,或者我們必須破解編譯器代碼?此外,這是如何與OCamlbuild進行交互的?感謝任何提示或建議。如何遍歷OCaml編譯器中鍵入的抽象語法樹

回答

4

假設你已經有某種類型的structure AST。

經典的方法是簡單地寫一個大的遞歸函數來自己遍歷AST。

但是現在模塊TypedtreeIter在OCaml編譯器源代碼中可用,並且它暴露於compiler-libs。爲了簡單遍歷,這非常方便。

TypedtreeIter提供了一個仿函數來構建你自己的遍歷類型AST的迭代器。這裏是一個非常簡單的例子打印所有模式標識符與它們的類型:

(* ocamlfind ocamlc -package compiler-libs.common -c example.ml *) 
open Typedtree 
open TypedtreeIter 

module MyIteratorArgument = struct 
    include DefaultIteratorArgument 

    let enter_pattern p = match p.pat_desc with 
    | Tpat_var (id, _) -> 
     Format.printf "@[<2>%[email protected] : %[email protected]]@." 
      (Ident.name id) 
      Printtyp.type_scheme p.pat_type 
    | _ ->() 
end 

module Iterator = TypedtreeIter.MakeIterator(MyIteratorArgument) 

模塊類型TypedtreeIter.IteratorArgument是指定你的迭代做什麼每個AST結構。你有兩個要點來執行你的工作:當遍歷進入一個構造時,以及當它離開時。例如,對於pattern,您有enter_patternexit_pattern。您不必擔心遞歸遍歷本身:它是函子MakeIterator的工作。給一個IteratorArgument模塊,它遞歸地連接所有enter_*exit_*,並返回一個包含一堆迭代器的模塊。

通常情況下,您只對AST的某些部分感興趣,並且想跳過其他部分。 DefaultIteratorArgument是一個模塊,其enter_*exit_*什麼都不做。你的IteratorArgument模塊應該包含DefaultIteratorArgument來繼承這個默認行爲,然後只實現一些特殊的部分。

如果您不僅想要遍歷打字的AST,而且要修改其中的一部分,請使用TypedtreeMap而不是TypedtreeIter。有一個TypedtreeMaphttps://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=default的小例子。

(我不使用ocamlbuild,所以我不能幫助這一點。)

+0

嗨,@camlspotter,謝謝你的好例子! 'TypedtreeIter'很整潔!我認爲有一件事是遺漏了迭代器仿函數沒有提供我們所在的'Env'。所以我們可能無法追蹤變量的定義站點。你之前是否遇到過這個問題,並且知道解決這個問題的代碼庫中的其他實用函數? – 2015-02-18 01:39:58

+0

每個類型的AST節點都有用於構建節點的類型環境。 – camlspotter 2015-02-18 09:39:38

3

OCaml提供自己的編譯器作爲名爲compiler-libs的庫。它包含了所有內容,允許用戶從具體的語法變爲可執行文件,並且可以控制所有中間步驟,當然還包括typedtree。

壞消息是它沒有記錄。我建議你,使用utopmerlin來探索這個庫。

你不需要任何特殊的事情與ocamlbuild使用compiler-libs,它是一個普通的圖書館。

+0

嗨,@ivg感謝您的答覆。在深入研究源代碼之前,一個簡單的問題是,該庫是否爲整個OCaml項目處理公開了API?或者由於OCaml對單獨編譯的大力支持,輸入整個項目的問題可以簡化爲逐個輸入每個文件?謝謝。 – 2015-02-08 03:58:20

+0

據我瞭解,它只公開編譯器部分,以便您可以使用庫建立自己的驅動程序。如果你真的需要使用ocaml項目並使用你自己調整好的編譯器進行編譯,那麼只需要調整編譯器就簡單多了。但爲了測試和調查,編譯器仍然是一個不錯的選擇。 – ivg 2015-02-08 04:04:41