[wg-camlp4] Matching on concrete syntax (was: Re: Camlp4 uses)

Alain Frisch alain.frisch at lexifi.com
Fri Mar 29 13:04:09 GMT 2013


On 01/29/2013 05:22 PM, Alain Frisch wrote:
> On 01/29/2013 04:37 PM, Xavier Clerc wrote:
>> However, during development,
>> it was a time-saver to be able to easily express and experiment new
>> ideas by manipulating "bits of the actual language". Camlp4 was kind
>> enough to translate them for me into AST code which I had to check.
>
> What about having a tool (either stand-alone or part of the compilers)
> which dumps the Parsetree representation of some code fragment in as
> textual OCaml values (probably without locations)?
>
> So you can type your "model" as source code and obtain quickly the
> Parsetree representation, copy/paste it into a nice pattern and replace
> some parts with variables.

I've hacked a quick implementation of such a tool, reusing the generic 
value printer from the toplevel:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/extension_points/tools/dump_ast.ml?revision=HEAD&view=markup

It parses either command-line arguments (currently, as types, 
expressions or patterns) or external .ml/.mli files, and shows the 
internal Parsetree representation.  By default, location and empty 
attribute fields are removed (they can be restored with command-line 
flags: -locs and -emptyattrs).

Examples:

$ ./ocamlast -w 50 -e "1 + x [@attr] * 2"
{pexp_desc =
   Pexp_apply
    ({pexp_desc = Pexp_ident {txt = Lident "*"}},
    [("",
      {pexp_desc =
        Pexp_apply
         ({pexp_desc =
            Pexp_ident {txt = Lident "+"}},
         [("",
           {pexp_desc =
             Pexp_constant (Const_int 1)});
          ("",
           {pexp_desc =
             Pexp_ident {txt = Lident "x"}})]);
       pexp_attributes =
        [("attr",
          {pexp_desc =
            Pexp_construct ({txt = Lident "()"},
             None, false)})]});
     ("",
      {pexp_desc = Pexp_constant (Const_int 2)})])}


$ ./ocamlast -w 50 -emptyattrs -t "int list * string"
{ptyp_desc =
   Ptyp_tuple
    [{ptyp_desc =
       Ptyp_constr ({txt = Lident "list"},
        [{ptyp_desc =
           Ptyp_constr ({txt = Lident "int"}, []);
          ptyp_attributes = []}]);
      ptyp_attributes = []};
     {ptyp_desc =
       Ptyp_constr ({txt = Lident "string"}, []);
      ptyp_attributes = []}];
  ptyp_attributes = []}


This should should simplify the learning curve of the Parsetree, and 
even allow quick copy/paste to write patterns/expressions on Parsetree. 
  That said, creating Parsetree fragments manually is quite tedious, and 
I've created a module to make this easier:

http://caml.inria.fr/cgi-bin/viewvc.cgi/ocaml/branches/extension_points/parsing/ast_helper.mli?revision=HEAD&view=markup

Currently, this module exposes "builder functions" which are very close 
to Parsetree constructors/records (making locations and attributes 
optional), but one can easily improve its interface (either by changing 
the existing functions, e.g. to use optional and labelled arguments, or 
by exposing other function to cover common cases).


Alain


More information about the wg-camlp4 mailing list