2012-01-08 27 views
2

鑑於此類型:創建一個簡單的語法camlp4擴展

type 'a variable = { name: string; mutable value: 'a } 

我試圖創建一個語法擴展,將接受這種語法:

var foo = true 

...並將其轉換爲:

let foo = { name = "foo"; value = true } 

這裏是我的嘗試:

open Camlp4.PreCast 
open Syntax 

type 'a variable = { name: string; mutable value: 'a } 

EXTEND Gram 
    expr: LEVEL "top" 
    [ [ "var"; v = a_LIDENT; "="; e = expr -> 
     <:expr< let $lid:v$ = { name= $`str:v$ ; value = $e$ } in $e$ >> 
    ] ] 
    ; 
END 

(我非常確定它需要在替換結束時使用$ e $作爲「剩餘」的一種表達方式,但是由於我們希望記錄的值字段對右邊的表達式的值 - 最初我並沒有結束$ E $那裏得到了同樣的錯誤)

我嘗試編譯:

ocamlc -I +camlp4 camlp4lib.cma -pp camlp4orf -c pa_var.ml 

導致:

File "pa_var.ml", line 10, characters 50-51: 
While expanding quotation "expr" in a position of "expr": 
    Parse error: "}" expected after [label_expr_list] (in [expr]) 

File "pa_var.ml", line 1, characters 0-1: 
Error: Preprocessor error 

我不知道爲什麼它似乎希望在記錄的名稱字段後面有一個「}」。 (否則,我在正確的軌道上嗎?)

+0

我在這裏可能是錯的,但在<>') – 2012-01-08 01:43:40

+0

@JeffMercado - 你是說它應該是:<:expr >? (這給出了相同的錯誤) – aneccodeal 2012-01-08 03:17:31

+0

說實話,我不知道這是什麼可能導致錯誤,它只是在我看來,表達式可能是一個主要因素在這個問題。 – 2012-01-08 03:24:18

回答

3

錯誤是您使用camlp4orf,它使用標準語法的代碼,但修訂語法的報價,連同字段名稱value,這是一個關鍵字在OCaml中修改語法。最簡單的解決方法是使用camlp4oof來隨處使用標準語法,但您也可以重命名該字段。 PS:我真的不認爲有必要寫一個Camlp4擴展來做到這一點。我建議與冗餘生活並使用let foo = var "foo" true來代替。這將簡化維護工作,與其他代碼庫交互等

PPS:一對夫婦更多的評論:

  • 你不想要實現它的方式;如果你想捕捉最上層的聲明短語let x = foo;;,你必須住在struct_item,而不是expr,並在expr你可能想要捕獲var <lid> = <expr> in <expr>表格的本地聲明。

  • 如果你堅持使用Camlp4,你應該避免使用EXTEND修改語法,就像你現在正在做的那樣。相反,選擇let foo = VAR true作爲您的具體語法,並使用Camlp4Filters機制將其轉換爲您想要的。這將更加可靠並且易於實現。

+0

是的,這主要是一個使用Camlp4擴展的實驗,不一定用於嚴重使用。我嘗試改變爲camlp4oof,正如你所建議的那樣,它會編譯,但它不能按預期工作(也許這是你的第一個要點):在頂層我做了:##「」camlp4o.cma「;;#加載「pa_var.cmo」;;#var x = true ;;給出:警告26:未使用的變量x。 錯誤:未綁定的記錄字段標籤名稱 – aneccodeal 2012-01-08 17:53:16

+0

也類似於使用Camlp4Filters的建議 - 更多不完整的文檔要閱讀;-)此頁面與我想要執行的操作相關嗎? http://brion.inria.fr/gallium/index.php/Reflective_OCaml – aneccodeal 2012-01-08 17:55:11

+0

有關過濾器的示例,請參閱'camlp4/Camlp4Filters/Camlp4ExceptionTracer.ml'。 – gasche 2012-01-08 21:06:33