Previous Up Next
Chapter 6 OCaml syntax trees
This chapter explains how to create OCaml syntax trees using quotations.

The OCaml syntax tree is defined in the module MLast (file ``mLast.mli''): it is of course always possible to create your syntax tree nodes by combining values of these types. But, for that, you need a precise documentation of all the constructors, how they have to be used, and which syntactic construct they correspond to.

Chapter 4 explained us that quotations are helpful to represent abstract values with concrete syntax. This is very adapted for abstract syntax trees, since they have corresponding concrete syntaxes. In this case, you have nothing to learn: if you know the concrete syntax, you know the abstract syntax. Actually, you need to know the revised syntax (chapter 5) because it is the syntax used in these quotations.

The provided quotation extension is the file q_MLast.cmo. Once this file loaded, you can write any complicated piece of program in concrete syntax, e.g.:
         <:expr< match f $x$ with [ $uid:p$ -> $x$ | C z -> 7 ] >>
This example corresponds exactly to this code (written in normal syntax):
         MLast.ExMat
          (loc, MLast.ExApp (loc, MLast.ExLid (loc, "f"), x),
           [MLast.PaUid (loc, p), None, x;
            MLast.PaApp
             (loc, MLast.PaUid (loc, "C"), MLast.PaLid (loc, "z")), None,
            MLast.ExInt (loc, "7")]);;
These two forms are absolutely equivalent, but the first one is much simpler and more readable. Notice the expressions between dollar signs $: they are antiquotations (see chapter 4). We are going to see how to use them.

For the moment, here is the list of the quotations defined in the file q_MLast.cmo: Each of these quotations use the revised syntax (chapter 5). You have to know that their expression form (i.e. not pattern) all contain the variable named "loc". It allows you to specify a source location to the syntax tree. There must then exist a variable "loc" visible in the environment where the quotation is used.

Notice that in the Camlp4 grammar system (chapter 3), the variable "loc" in defined in all semantic actions of the rules: Camlp4 grammar system and Camlp4 quotations of abstract syntax trees are made to work together.

6.1 Antiquotations

The antiquotations allow to insert abstract syntax trees inside other abstract syntax trees. They are enclosed by dollar signs $. Between these dollars, you can put any expression or pattern in the enclosing syntax.

For example, if you have a variable "x" of type MLast.expr, you may want to create ``the tree node corresponding to the call of some function "f" with this expression. This can be written:
           <:expr< f $x$ >>
Note that if the quotation is is position of pattern, the content of the quotation must be a pattern: here are legal pieces of program (in normal syntax):
           function <:expr< f $x$ >> -> x;;
           function <:expr< f $_$ >> -> 1;;
6.2 Antiquotations labels

Some of these antiquotations may be used with a label (an identifier ending with a colon character ":" in the beginning of the antiquotation). It is for the case when the concrete syntax is not enough to know what we are talking about.

For example, if x is a variable of type string, we need ways to create 1/ the tree node corresponding to the variable whose name is the value of x 2/ the tree node corresponding to the string whose content is the value of x 3/ the tree node corresponding to the constructor whose name is the value of x.

Labels allow to do that: in the first case, it must be "lid" (for ``l(owercase) id(entifier)''), in the second case, "str" (for ``str(ing)''), in the third case, "uid" (for ``u(ppercase) id(entifier)''), i.e. respectively:
           <:expr< f $lid:x$ >>
           <:expr< f $str:x$ >>
           <:expr< f $uid:x$ >>
Therefore:
    let x = "foo" in <:expr< f $lid:x$ >> is equivalent to: <:expr< f foo >>
    let x = "foo" in <:expr< f $str:x$ >>       "           <:expr< f "foo" >>
    let x = "Foo" in <:expr< f $uid:x$ >>       "           <:expr< f Foo >>
Important remark: the antiquotations of type string (str) and character (chr) must contain an ``escaped'' string: some characters like backslashes, quotes, doubles quotes must be prefixed by a backslash. To be sure, use the OCaml library functions "String.Escaped" and "Char.Escaped".

A label often encountered is "list": it is when the syntactic construct may expect a list at this place. Here are examples with two antiquotations, one being labelled, the other not:
             <:expr< [| $list:x$ |] >>
             <:expr< [| $x$ |] >>
Notice that the antiquotations must respect the enclosing syntax rules: if x and y are of type MLast.expr and z of type MLast.expr list, the code:
             <:expr< [| $list: x::y::z $ |] >>
is correct in normal syntax, but if you use the revised syntax, you must write it:
             <:expr< [| $list: [x; y :: z] $ |] >>
6.3 Description

Well, we could describe all nodes one by one, but they are actually already described in the reference manual. Refer to it.



Previous Up Next