ocaml编译器是使用编译器前端模块解析来解析源代码还是使用ocamlyacc来解析源代码?

时间:2018-09-11 08:15:27

标签: compiler-construction ocaml

我尝试阅读ocaml编译器源代码,使用4.07源代码

我从driver / main.ml读取

我注意到它使用driver / pparse.ml第161行函数“ parse”来解析lex buf (我添加一行Printf.printf“ pparse.parse”,在make world之后,我使用boot / ocamlrun ./ocamlc -nostdlib -I stdlib -c a.ml对其进行测试,控制台写为“ pparse.parse”):

let parse (type a) (kind : a ast_kind) lexbuf: a =
match kind with
| Structure->Parse.implementation lexbuf
| Signature->Parse.interface lexbuf

我想知道Parse.implementation是函数的实现,来自编译器前端库: https://caml.inria.fr/pub/docs/manual-ocaml/parsing.html

来自parseing / parse.ml,第61行:

let implementation = wrap Parser.implementation

在“ make world”之后,ocamlyacc在floder解析时生成parser.ml 在“ make world”之后,Parser.implementation函数是:

let implementation (lexfun:Lexing.lexbuf -> token) (lexbuf : Lexing.lexbuf) = 
(Parsing.yyparse yytables 1 lexfun lexbuf : Parsetree.structure)

我不知道哪个ocaml编译器真正使用。

我这样更改函数解析:

let parse (type a) (kind : a ast_kind) lexbuf : a =
match kind with
| Structure -> 
Printf.printf "pparse.parse";
let a=Parse.implementation lexbuf in
let writehandle = open_out "/home/wk/prog/LocationTest/parsed" in
let fmt = Format.formatter_of_out_channel writehandle in
Format.fprintf fmt "%a@." Pprintast.structure a ;
close_out writehandle;

并在“ make world”之后运行正常。但是在boot / ocamlrun ./ocamlc -nostdlib -I stdlib -c a.ml之后,解析的文件与a.ml相同,即使a.ml是一个复杂的程序

太复杂了吗?能帮我吗?谢谢

有没有一本书或其他文档可以教我ocaml的编译器?谢谢!

1 个答案:

答案 0 :(得分:1)

解析器本身由ocamlyacc(或OCaml 4.08中的竖向)从parsing/parser.ml生成为parsing/parser.mly。模块parsing/parse包装结果函数以添加一些解析器错误处理。最后,模块driver/pparseparsing/parse之上的另一层,用于设置解析器环境和预处理阶段。

然后,compiler-libs库重新导出编译器的一些内部模块。

有关其他补充信息,请参见https://github.com/ocaml/ocaml/blob/trunk/parsing/HACKING.adoc