我正在尝试了解有关OCaml扩展点的更多信息,但我无法跟踪AST中记录类型的表示。
我从这篇博文中窃取了以下示例:
http://whitequark.org/blog/2014/04/16/a-guide-to-extension-points-in-ocaml/
使用源文件(foo.ml):
let _ = [%getenv "USER"]
输出ocamlc -dparsetree fool.ml:
[
structure_item (test.ml[1,0+0]..[1,0+24])
Pstr_eval
expression (test.ml[1,0+8]..[1,0+24])
Pexp_extension "getenv"
[
structure_item (test.ml[1,0+17]..[1,0+23])
Pstr_eval
expression (test.ml[1,0+17]..[1,0+23])
Pexp_constant Const_string("USER",None)
]
]
从asttypes.mli和parsetree.mli我可以按照行的解析树模式匹配
Pexp_constant Const_string("USER",None)
但是,当解析树表示记录类型时,我无法再跟踪发生的情况。似乎记录字段的表示顺序与它们在类型定义中出现的顺序不同,并且解析树中不需要(或显示)所有字段。
来自parsetree.mli:
type expression = {
pexp_desc: expression_desc;
pexp_loc: Location.t;
pexp_attributes: attributes;
}
解析树输出似乎只显示位置和有效负载,但我可能读错了。
如何正确读取AST的记录类型?对于类型表达式,它应该是:
(* record type declaration and pexp_loc field *)
expression (test.ml[1,0+8]..[1,0+24])
(* pexp_desc field *)
Pexp_extension "getenv"
[
...
]
答案 0 :(得分:2)
您似乎缺少研究AST和使用扩展点的基本工具。这些工具是Alain Frisch撰写的ppx_tools。其中一个工具正是为了探索AST的具体表示而设计的,其名称为dumpast
。我们将其应用于以下文件ast_record.mli
:
type card = {
name: string;
address: string;
age: int;
}
输出
ocamlfind ppx_tools/dumpast ast_record.mli
ast_record.mli
==>
[{psig_desc =
Psig_type
[{ptype_name = {txt = "card"}; ptype_params = []; ptype_cstrs = [];
ptype_kind =
Ptype_record
[{pld_name = {txt = "name"}; pld_mutable = Immutable;
pld_type = {ptyp_desc = Ptyp_constr ({txt = Lident "string"}, [])}};
{pld_name = {txt = "address"}; pld_mutable = Immutable;
pld_type = {ptyp_desc = Ptyp_constr ({txt = Lident "string"}, [])}};
{pld_name = {txt = "age"}; pld_mutable = Immutable;
pld_type = {ptyp_desc = Ptyp_constr ({txt = Lident "int"}, [])}}];
ptype_private = Public; ptype_manifest = None}]}]
=========
确认记录标签的顺序被保留。
顺便提一下,我建议您研究这些 ppx_tools 的源代码,也可能是Lwt附带的 ppx 扩展。它们非常简短,写得非常好,是一个值得推荐的灵感来源。