Questions regarding `ocamlc -dparsetree hello.ml`

  1. The output of ocamlc -dparsetree hello.ml looks awfully like s-exprs. Is there a easy way to parse it ?

  2. How can I write a program that does the equiv of ocamlc -dparsetree hello.ml (i.e. parses it, and has the AST in memory, instead of printing it out).

  3. If I’m writing a *.ml → *.rs converter, is it better to (1) shell to system ocaml, then parse the output of ocamlc -dparsetree hello.ml or (2) link parts of ocaml itself, and parse directly into in memory representation.

  4. If I’m linking vs ocaml, is there a way to link just the ocaml parser instead all of ocaml ?

  5. If all I want is just a parser (i.e. no need for typing / code gen), is there an alternative package to pull from opam instead of ocaml itself ?

Thanks!

XY problem: taking a restricted *.ml file as input, parsing the data types: tuples, records, variants, and outputting a *.rs file.

I looked at the output of that command on the file let x = 1. Could I make a suggestion? Maybe take the OCaml AST type, and apply the SEXP deriver to it, and prettyprint that ? Or JSON – whichever you prefer? B/c otherwise … well, I think it’ll be a bit of a PITA to write a parser for that “-dparsetree” format. Maybe I’m wrong, but it looks like it wasn’t meant to be parsed.

I could be wrong.

The flag -dparsetree is a debugging flag, which outputs debugging information. It doesn’t make sense to try to parse this output.

You should use the Pparse module from the compiler library: OCaml compiler library : Pparse.

The compiler libraries are distributed within the ocaml opam package.

2 Likes

If that helps, you can get the AST of a .ml e.g. like this:

let parse_print file =
  if not (Filename.check_suffix file ".ml") then
    failwith "Invalid extension"
  else
    let ast = Pparse.parse_implementation ~tool_name:"test_past" file in
    (* Do something with your AST *)
    let open Format in
    printf "The file contains %d top-level structure items@\n" 
           (List.length ast);
    List.iteri (fun i item  ->
      let i = i + 1 in
      printf "(* begin %d *)@\n%a@\n(* end %d *)@\n"
      i
      Pprintast.structure_item item
      i) ast

The full documentation of the Parsetree module is here.
Assuming the code above is in a file test_past.ml the following dune file will compile it:

(executable
 (name test_past)
 (libraries compiler-libs.common))

EDIT: something similar also works for .mli files.

1 Like

A fair bit of warning though, if the code is intended to work with various (in particular oldish) versions of OCaml, you may end up with boilerplate of ifdefs or other kind of conditional compilation tricks depending of what is used in the AST. In such cases, OCaml Migrate Parsetree could help.

I’m

Thanks for letting. This is a prototype, I’m okay with it only working on OCaml 5.0.0 :slight_smile: