Ocaml 创建简单的camlp4语法扩展
鉴于这一类型:Ocaml 创建简单的camlp4语法扩展,ocaml,camlp4,Ocaml,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 }
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
其结果是:
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
我不知道为什么它似乎希望在记录的name字段后面有一个“}”。(否则,我在这里是正确的吗?错误在于您使用了
camlp4orf
,它对代码使用标准语法,但对引号使用修订语法,以及字段名value
,这是OCaml修订语法中的一个关键字。最简单的修复方法是使用camlp4oof
到处使用标准语法,但也可以重命名该字段
PS:我真的不认为有必要编写Camlp4扩展来实现这一点。我建议生活在冗余中,而使用letfoo=var“foo”true
。这将简化维护、与其他代码库的交互等
PPS:还有几点意见:
- 你不想以这种方式实现它;如果您想捕捉顶级声明短语
let x=foo代码>,您必须生活在
中,而不是struct_item
,并且在expr
中,您可能希望捕获expr
格式的本地声明var=in
- 如果您坚持使用Camlp4,您应该避免像现在这样使用
修改语法。相反,选择EXTEND
作为您的具体语法,并使用let foo=VAR true
机制将其转换为您想要的语法。这将更加健壮且易于实现Camlp4Filters
@JeffMercado-你的意思应该是:>?(这给出了相同的错误)老实说,我不知道是什么原因导致了错误,只是在我看来,这个表达式可能是问题的一个主要因素。是的,这主要是对Camlp4扩展的一个实验,不一定是为了认真使用。我试着按照您的建议更改为camlp4oof,它确实可以编译,但它并没有按照预期工作(也许您的第一个要点就解决了这一问题):在顶层我做到了:##加载“camlp4o.cma”;##加载“pa_var.cmo”#var x=真;;给出:警告26:未使用的变量x。错误:未绑定的记录字段标签名称也类似于使用Camlp4Filters的建议-阅读更不完整的文档;-)这个页面与我想做的相关吗?有关筛选器的示例,请参见camlp4/Camlp4Filters/camlp4exceptiontacer.ml
。我强烈建议不要使用camlp4oof,因为它(至少在所有发布的版本中)存在细微的解析错误。学习修订后的语法(相当简单)并使用camlp4orf。@ygrek-我以为我在使用修订后的语法,但没有意识到“value”是该语法中的一个关键字。
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