我创建了一个语法扩展,允许将类型定义为
type.yjson type_name {
/* type_declaration */
}
能够直接从json文件构建记录值。 语法扩展插入模块和执行此操作所必需的功能。 直到这里,没问题。语法扩展正是我想要的。
如果我想在我的代码中的其他地方使用“yjson”(即:函数参数),我就会遇到一些问题。
这是我试过的:
EXTEND Gram
str_item:
[
[ KEYWORD "type"; KEYWORD "."; "yjson"; tdl_raw = type_declaration ->
这是我使用“yjson”作为函数参数时得到的错误
[fun_binding] expected after [ipatt] (in [let_binding])
我真的不明白这里发生了什么。似乎规则不匹配,为什么我会得到一个解析错误?
答案 0 :(得分:5)
我并不完全理解P4的机制,但[ [ "blahblah" -> ...
使blahblah
成为该语言的新关键字,因此您不能再使用blahblah
作为函数参数。
要查看此内容,请尝试使用camlp4of预处理您的pa _ *。ml并查看"blahblah"
如何扩展为Gram.Skeyword "blahblah"
。似乎这个Skeyword _
通过P4的Structure.using
传递给Insert.insert
,字符串被注册为新关键字。
要使yjson
可用作正常变量,请在规则中使用id = LIDENT
代替"yjson"
,然后检查id
的内容是"yjson"
或不在你的行动中。
答案 1 :(得分:4)
如果我可以稍微偏离主题,我认为为类型导向的代码生成设计自定义语法是错误的,因为已经存在两种不同的语法(一种用于type_conv,另一种用于派生)其中一个(type-conv)正在成为事实上的标准。
type foo = {
...
} with json
如果您为此选择语法, 应该使用此语法,除非您有充分的理由不这样做。事实上,type-conv本身是一个帮助实用程序,可以让你编写自己的类型导向代码生成器,所以你也可以直接使用type-conv来做你想做的事情。
(你可能知道Martin Jambon的Atdgen,它有意识地选择不使用Camlp4; Alain Frisch正在进行的工作直接支持OCaml语法中的注释,但还没有准备好消费。 )