我想轉儲OCaml項目中的所有標識符的類型信息,基本上與遍歷鍵入的抽象語法樹(https://github.com/ocaml/ocaml/blob/trunk/typing/typedtree.mli)相同。由於我是OCaml編譯器的代碼庫新手,我不確定編譯器是否提供了apis,因此我們可以輕鬆編寫一個插件來完成這項工作,或者我們必須破解編譯器代碼?此外,這是如何與OCamlbuild進行交互的?感謝任何提示或建議。如何遍歷OCaml編譯器中鍵入的抽象語法樹
回答
假設你已經有某種類型的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_pattern
和exit_pattern
。您不必擔心遞歸遍歷本身:它是函子MakeIterator
的工作。給一個IteratorArgument
模塊,它遞歸地連接所有enter_*
和exit_*
,並返回一個包含一堆迭代器的模塊。
通常情況下,您只對AST的某些部分感興趣,並且想跳過其他部分。 DefaultIteratorArgument
是一個模塊,其enter_*
和exit_*
什麼都不做。你的IteratorArgument
模塊應該包含DefaultIteratorArgument
來繼承這個默認行爲,然後只實現一些特殊的部分。
如果您不僅想要遍歷打字的AST,而且要修改其中的一部分,請使用TypedtreeMap
而不是TypedtreeIter
。有一個TypedtreeMap
在https://bitbucket.org/camlspotter/compiler-libs-hack/src/340072a7c14cbce624b98a57bf8c4c6509c40a31/overload/mod.ml?at=default的小例子。
(我不使用ocamlbuild,所以我不能幫助這一點。)
OCaml提供自己的編譯器作爲名爲compiler-libs
的庫。它包含了所有內容,允許用戶從具體的語法變爲可執行文件,並且可以控制所有中間步驟,當然還包括typedtree。
壞消息是它沒有記錄。我建議你,使用utop
或merlin
來探索這個庫。
你不需要任何特殊的事情與ocamlbuild使用compiler-libs
,它是一個普通的圖書館。
嗨,@ivg感謝您的答覆。在深入研究源代碼之前,一個簡單的問題是,該庫是否爲整個OCaml項目處理公開了API?或者由於OCaml對單獨編譯的大力支持,輸入整個項目的問題可以簡化爲逐個輸入每個文件?謝謝。 – 2015-02-08 03:58:20
據我瞭解,它只公開編譯器部分,以便您可以使用庫建立自己的驅動程序。如果你真的需要使用ocaml項目並使用你自己調整好的編譯器進行編譯,那麼只需要調整編譯器就簡單多了。但爲了測試和調查,編譯器仍然是一個不錯的選擇。 – ivg 2015-02-08 04:04:41
- 1. Haskell編譯器中的遍歷型抽象語法樹
- 2. 遍歷抽象語法樹
- 3. 抽象語法樹構造和遍歷
- 4. 如何從F#編譯器服務獲取鍵入的抽象語法樹
- 5. OCaml - 遍歷樹
- 6. 二叉樹遍歷抽象
- 7. 解釋器後端,你如何遍歷你的抽象語法樹?
- 8. 在OCaml中抽象語法樹的S-表達式樹
- 9. 遍歷OCaml中
- 10. 編譯器如何構建語法樹?
- 11. 遍歷對象樹
- 12. 如何構建抽象語法樹
- 13. 如何在野牛中顯示語法的抽象語法樹?
- 14. 在C++中表示一個多遍抽象語法樹(AST)?
- 15. 開發抽象語法樹
- 16. 增強抽象語法樹
- 17. 打印抽象語法樹
- 18. GCC抽象語法樹
- 19. 抽象語法樹問題
- 20. 鍵入抽象語法樹與功能應用程序
- 21. 遍歷樹遍歷
- 22. 樹遍歷算法
- 23. 不能專門遍歷語法樹嗎?
- 24. 瞭解在g ++編譯的前端階段中生成的抽象語法樹
- 25. 使用抽象基類來遍歷整個JAXB對象樹
- 26. 如何將我的分析樹簡化爲抽象語法樹?
- 27. 抽象語法樹與對象模型
- 28. 如何評估一個新的編程語言的抽象語法樹
- 29. 用於在Python中編程抽象語法樹的庫
- 30. 樹的遍歷
嗨,@camlspotter,謝謝你的好例子! 'TypedtreeIter'很整潔!我認爲有一件事是遺漏了迭代器仿函數沒有提供我們所在的'Env'。所以我們可能無法追蹤變量的定義站點。你之前是否遇到過這個問題,並且知道解決這個問題的代碼庫中的其他實用函數? – 2015-02-18 01:39:58
每個類型的AST節點都有用於構建節點的類型環境。 – camlspotter 2015-02-18 09:39:38