2

鉴于这种类型:

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$ 来表示“其余部分”,但考虑到我们希望记录的 value 字段具有以下值,它看起来也有点可疑右边的表达式 - 最初我没有结尾 $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

我不知道为什么它似乎想在记录的名称字段后有一个“}”。(否则,我在正确的轨道上吗?)

4

1 回答 1

3

错误是您使用camlp4orf,它使用代码的标准语法,但修改了引号的语法,以及字段 name value,它是 OCaml 修改语法中的关键字。最简单的解决方法是在camlp4oof任何地方使用标准语法,但您也可以重命名该字段。

PS:我真的认为没有必要编写Camlp4扩展来做到这一点。我建议与冗余一起生活并let foo = var "foo" true改用。这将简化维护、与其他代码库的交互等。

PPS:还有一些评论:

  • 你不想那样实现它;如果你想捕捉顶级声明短语let x = foo;;,你必须住在struct_item,而不是exprexpr你可能想捕捉形式的本地声明var <lid> = <expr> in <expr>

  • 如果您坚持使用 Camlp4,您应该避免使用 修改语法EXTEND,就像您现在正在做的那样。而是选择let foo = VAR true作为您的具体语法,并使用该Camlp4Filters机制将其转换为您想要的。这将更加健壮且易于实施。

于 2012-01-08T09:38:36.467 回答