为什么在 ocaml 编译器源代码中打印 Parsetree.implementation 的数量失败?
Why print the number of Parsetree.implementation fail at ocaml compiler source code?
这段代码工作正常:
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_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_fun是Parse.implementation,然后是"make world",得到错误:
Error: This expression has type 'a list
but an expression was expected of type a
我不知道为什么同样的方法在这种情况下失败了,谢谢!
首先,我是否建议您不要通过查看编译器代码库来学习 OCaml?编译器代码库充满了陈旧的习语、微妙的不变量、高度优化的算法,而且对于初学者来说文档不足。因此,如果您正在努力学习 OCaml,它通常不是一个学习的好地方。
对于您手头的错误,问题是 parse_fun lexbuf
的结果不是 structure
,而是局部抽象类型 a
。此局部抽象类型受 file_aux
的 kind
参数约束。 kind
的类型是 a ast_kind
,它是定义为
的通用抽象数据类型(又名 GADT)
type 'a ast_kind =
| Structure: structure ast_kind
| Signature: signature ast_kind
因此a
可能是结构或签名。这些都是列表,但您需要将此事实公开给类型检查器才能计算列表长度:
let len (type a) (kind:a ast_kind) (l:a) = match kind with
| Signature -> List.length l
| Structure -> List.length l
这段代码工作正常:
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_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_fun是Parse.implementation,然后是"make world",得到错误:
Error: This expression has type 'a list
but an expression was expected of type a
我不知道为什么同样的方法在这种情况下失败了,谢谢!
首先,我是否建议您不要通过查看编译器代码库来学习 OCaml?编译器代码库充满了陈旧的习语、微妙的不变量、高度优化的算法,而且对于初学者来说文档不足。因此,如果您正在努力学习 OCaml,它通常不是一个学习的好地方。
对于您手头的错误,问题是 parse_fun lexbuf
的结果不是 structure
,而是局部抽象类型 a
。此局部抽象类型受 file_aux
的 kind
参数约束。 kind
的类型是 a ast_kind
,它是定义为
type 'a ast_kind =
| Structure: structure ast_kind
| Signature: signature ast_kind
因此a
可能是结构或签名。这些都是列表,但您需要将此事实公开给类型检查器才能计算列表长度:
let len (type a) (kind:a ast_kind) (l:a) = match kind with
| Signature -> List.length l
| Structure -> List.length l