2014-11-03 11 views
1

我想要預先處理OCaml片段,並根據某些表達式的類型對代碼片段進行一些修改。例如,如果片段中:OCaml - 使用類型信息進行預處理

(f [1;2;3]) 

我想另一個參數添加到f象:

(f [1;2;3] [[0]]) 

但如果我看到:

(f ["a"; "b"]) 

然後,我可能想:

(f ["a"; "b"] [[""]]) 

我看着camlp4,雖然我與它不徹底;我認爲camlp4沒有關於表達式的類型信息。

有什麼辦法可以做到這一點? 謝謝!

回答

1

CamlP4是未進行類型檢查的解析樹級別的預處理器。因此,編寫依賴於類型的行爲是......並非不可能,但非常困難:您需要將P4解析樹發送給您可能已修改的OCaml類型檢查程序,然後從中檢索類型化的AST,然後以某種方式將其翻譯回P4的非類型化樹。 P4的特殊AST數據類型使得這非常難以實現。另外,現在人們正在轉向使用P4 :-(

OCaml使用新的-ppx框架進行預處理會更容易,因爲它可以更好地訪問編譯器內部,它不是很容易,但足夠可行。如果你真的想你的類型取決於預處理我建議使用PPX主要taksks是:

  • 發送非類型化分析樹AST到OCaml中的類型檢查(可能有一些修改)
  • 獲得其完整類型Typedtree AST再加入你想要什麼:在你的情況下,添加更多的參數
  • 將鍵入的AST使用Untypeast模塊返回Parsetree
  • 輸出最終的Parsetree作爲預處理結果。

https://bitbucket.org/camlspotter/compiler-libs-hack解釋瞭如何實現這種類型的ppx預處理器。我希望它能幫助你。

0

這種基於類型的轉變是非常脆弱的,比如你是什麼做的:

f [] 

let g x = f x 

如果你只需要它爲那些常變量工作文字表達式(這兩個例子都是),那麼你可以用camlp4或ppx做些什麼。 (ppx的首選,因爲它是一個更簡單的方法,但它只適用於OCaml版本4.02)。

因此,通過ppx,您可以找到f的每個用法應用於某個文字表達式並添加相應的額外參數。就個人而言,我覺得這種預處理應在代碼中是顯而易見的,所以我可能會使用:

[%f [1; 2; 3]] 

而不是:

f [1; 2; 3] 

的語法(在4.02特別添加了[%id ...]語法用於語法擴展)。