Compiler construction 为什么在ocaml编译器源代码中打印Parsetree.implementation失败的数目?
此代码工作正常:Compiler construction 为什么在ocaml编译器源代码中打印Parsetree.implementation失败的数目?,compiler-construction,ocaml,Compiler Construction,Ocaml,此代码工作正常: let ()= let filename = "/home/wk/prog/LocationTest/b.ml" in Location.input_name := filename ; let readhandle = open_in filename in let buf = Lexing.from_channel readhandle in Location.init buf filename ; let ast = Parse.implementation
let ()=
let filename = "/home/wk/prog/LocationTest/b.ml" in
Location.input_name := filename ;
let readhandle = open_in filename in
let buf = Lexing.from_channel readhandle in
Location.init buf filename ;
let ast = Parse.implementation buf in
Printf.printf "%d" (List.length ast) ;
ast的类型是Parsetree.structure,它是“structure\u item list”,所以我可以使用list.length获取它的长度
我使用相同的方法调试ocaml 4.07编译器源代码:
我更改了ocaml 4.07编译器源代码/driver/pparse.ml 181-183:
let lexbuf = Lexing.from_channel ic in
Location.init lexbuf inputfile;
Profile.record_call "parser" (fun () -> parse_fun lexbuf)
为此:
let lexbuf = Lexing.from_channel ic in
Location.init lexbuf inputfile;
let xx=parse_fun lexbuf in
Printf.printf "%d" (List.length xx);
Profile.record_call "parser" (fun () -> xx)
parse_的乐趣是parse.implementation,然后是“make world”,得到错误:
Error: This expression has type 'a list
but an expression was expected of type a
我不知道为什么在这种情况下同样的方法会失败,谢谢 首先,我可以建议您不要通过查看编译器代码库来学习OCaml吗?编译器的代码库中充满了旧的习惯用法、微妙的不变量、经过大量优化的算法,对于初学者来说,这些代码的文档记录非常少。因此,如果您正在努力使用OCaml,那么它通常不是一个学习的好地方 对于您手头的错误,问题在于
parse\u fun lexbuf
的结果不是结构,而是本地抽象类型a
。此局部抽象类型受file\u aux
的kind
参数约束。kind
的类型是ast\u kind
,它是一种广义抽象数据类型(又名GADT),定义为
type 'a ast_kind =
| Structure: structure ast_kind
| Signature: signature ast_kind
因此,a
可以是结构或签名。这两个都是列表,但您需要向typechecker公开这一事实,以便能够计算列表长度:
let len (type a) (kind:a ast_kind) (l:a) = match kind with
| Signature -> List.length l
| Structure -> List.length l
完整的错误信息是什么?