OCaml compiler library : Parsetree

# Module Parsetree

    module Parsetree: sig .. end

Abstract syntax tree produced by parsing

Warning: this module is unstable and part of compiler-libs.

    type constant = {

`` | `pconst_desc : `constant_desc`;`
`` | `pconst_loc : `Location.t`;`

`}`

    type constant_desc =

`|` | `Pconst_integer of `string * char option`` | `(*` | Integer constants such as `3` `3l` `3L` `3n`. Suffixes `[g-z][G-Z]` are accepted by the parser. Suffixes except `'l'`, `'L'` and `'n'` are rejected by the typechecker | `*)`
`|` | `Pconst_char of `char`` | `(*` | Character such as `'c'`. | `*)`
`|` | `Pconst_string of `string * Location.t * string option`` | `(*` | Constant string such as `"constant"` or `{delim|other constant|delim}`. The location span the content of the string, without the delimiters. | `*)`
`|` | `Pconst_float of `string * char option`` | `(*` | Float constant such as `3.4`, `2e5` or `1.4e-4`. Suffixes `g-z` `G-Z` are accepted by the parser. Suffixes are rejected by the typechecker. | `*)`

    type location_stack = Location.t list

## Extension points

    type attribute = {

`` | `attr_name : `string Asttypes.loc`;`
`` | `attr_payload : `payload`;`
`` | `attr_loc : `Location.t`;`

`}`

Attributes such as `[@id ARG]` and `[@@id ARG]`.

Metadata containers passed around within the AST. The compiler ignores unknown attributes.

    type extension = string Asttypes.loc * payload

Extension points such as `[%id ARG] and [%%id ARG]`.

Sub-language placeholder -- rejected by the typechecker.

    type attributes = attribute list

    type payload =

`|` | `PStr of `structure``
`|` | `PSig of `signature`` | `(*` | `: SIG` in an attribute or an extension point | `*)`
`|` | `PTyp of `core_type`` | `(*` | `: T` in an attribute or an extension point | `*)`
`|` | `PPat of `pattern * expression option`` | `(*` | `? P` or `? P when E`, in an attribute or an extension point | `*)`

## Core language

### Type expressions

    type core_type = {

`` | `ptyp_desc : `core_type_desc`;`
`` | `ptyp_loc : `Location.t`;`
`` | `ptyp_loc_stack : `location_stack`;`
`` | `ptyp_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type core_type_desc =

`|` | `Ptyp_any` | `(*` | `_` | `*)`
`|` | `Ptyp_var of `string`` | `(*` | A type variable such as `'a` | `*)`
`|` | `Ptyp_arrow of `Asttypes.arg_label * core_type * core_type`` | `(*` | `Ptyp_arrow(lbl, T1, T2)` represents: `T1 -> T2` when `lbl` is `Nolabel`, `~l:T1 -> T2` when `lbl` is `Labelled`, `?l:T1 -> T2` when `lbl` is `Optional`. | `*)`
`|` | `Ptyp_tuple of `(string option * core_type) list`` | `(*` | `Ptyp_tuple(tl)` represents a product type: `T1 * ... * Tn` when `tl` is `(None, T1); ...; (None, Tn)` `L1:T1 * ... * Ln:Tn` when `tl` is `(Some L1, T1); ...; (Some Ln, Tn)` A mix, e.g., `L1:T1 * T2` when `tl` is `(Some L1, T1); (None, T2)` Invariant: `n >= 2`. | `*)`
`|` | `Ptyp_constr of `Longident.t Asttypes.loc * core_type list`` | `(*` | `Ptyp_constr(lident, l)` represents: `tconstr` when `l=[]`, `T tconstr` when `l=[T]`, `(T1, ..., Tn) tconstr` when `l=[T1 ; ... ; Tn]`. | `*)`
`|` | `Ptyp_object of `object_field list * Asttypes.closed_flag`` | `(*` | `Ptyp_object([ l1:T1; ...; ln:Tn ], flag)` represents: `< l1:T1; ...; ln:Tn >` when `flag` is `Closed`, `< l1:T1; ...; ln:Tn; .. >` when `flag` is `Open`. | `*)`
`|` | `Ptyp_class of `Longident.t Asttypes.loc * core_type list`` | `(*` | `Ptyp_class(tconstr, l)` represents: `#tconstr` when `l=[]`, `T #tconstr` when `l=[T]`, `(T1, ..., Tn) #tconstr` when `l=[T1 ; ... ; Tn]`. | `*)`
`|` | `Ptyp_alias of `core_type * string Asttypes.loc`` | `(*` | `T as 'a`. | `*)`
`|` | `Ptyp_variant of `row_field list * Asttypes.closed_flag * Asttypes.label list option`` | `(*` | `Ptyp_variant([`A;`B], flag, labels)` represents: `[ `A|`B ]` when `flag` is `Closed`, and `labels` is `None`, `[> `A|`B ]` when `flag` is `Open`, and `labels` is `None`, `[< `A|`B ]` when `flag` is `Closed`, and `labels` is `Some []`, `[< `A|`B > `X `Y ]` when `flag` is `Closed`, and `labels` is `Some ["X";"Y"]`. | `*)`
- `|` | `Ptyp_poly of `string Asttypes.loc list * core_type`` | `(*` | `'a1 ... 'an. T` Can only appear in the following context: As the `Parsetree.core_type` of a `Ppat_constraint` node corresponding to a constraint on a let-binding:
      let x : 'a1 ... 'an. T = e ...
Under `Cfk_virtual` for methods (not values). As the `Parsetree.core_type` of a `Pctf_method` node. As the `Parsetree.core_type` of a `Pexp_poly` node. As the `pld_type` field of a `Parsetree.label_declaration`. As a `Parsetree.core_type` of a `Ptyp_object` node. As the `pval_type` field of a `Parsetree.value_description`. | `*)`
`|` | `Ptyp_package of `package_type`` | `(*` | `(module S)`. | `*)`
`|` | `Ptyp_open of `Longident.t Asttypes.loc * core_type`` | `(*` | `M.(T)` | `*)`
`|` | `Ptyp_extension of `extension`` | `(*` | `[%id]`. | `*)`

    type package_type = {

`` | `ppt_path : `Longident.t Asttypes.loc`;`
`` | `ppt_cstrs : `(Longident.t Asttypes.loc * core_type) list`;`
`` | `ppt_loc : `Location.t`;`
`` | `ppt_attrs : `attributes`;`

`}`

As `Parsetree.package_type` typed values:

- `{ppt_path: S; ppt_cstrs: []}` represents `(module S)`,
- `{ppt_path: S; ppt_cstrs: [(t1, T1) ; ... ; (tn, Tn)]}` represents `(module S with type t1 = T1 and ... and tn = Tn)`.

    type row_field = {

`` | `prf_desc : `row_field_desc`;`
`` | `prf_loc : `Location.t`;`
`` | `prf_attributes : `attributes`;`

`}`

    type row_field_desc =

`|` | `Rtag of `Asttypes.label Asttypes.loc * bool * core_type list`` | `(*` | `Rtag(`A, b, l)` represents: ``A` when `b` is `true` and `l` is `[]`, ``A of T` when `b` is `false` and `l` is `[T]`, ``A of T1 & .. & Tn` when `b` is `false` and `l` is `[T1;...Tn]`, ``A of & T1 & .. & Tn` when `b` is `true` and `l` is `[T1;...Tn]`. The `bool` field is true if the tag contains a constant (empty) constructor. `&` occurs when several types are used for the same constructor (see 4.2 in the manual) | `*)`
`|` | `Rinherit of `core_type`` | `(*` | `[ | t ]` | `*)`

    type object_field = {

`` | `pof_desc : `object_field_desc`;`
`` | `pof_loc : `Location.t`;`
`` | `pof_attributes : `attributes`;`

`}`

    type object_field_desc =

`|` | `Otag of `Asttypes.label Asttypes.loc * core_type``
`|` | `Oinherit of `core_type``

### Patterns

    type pattern = {

`` | `ppat_desc : `pattern_desc`;`
`` | `ppat_loc : `Location.t`;`
`` | `ppat_loc_stack : `location_stack`;`
`` | `ppat_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type pattern_desc =

`|` | `Ppat_any` | `(*` | The pattern `_`. | `*)`
`|` | `Ppat_var of `string Asttypes.loc`` | `(*` | A variable pattern such as `x` | `*)`
`|` | `Ppat_alias of `pattern * string Asttypes.loc`` | `(*` | An alias pattern such as `P as 'a` | `*)`
`|` | `Ppat_constant of `constant`` | `(*` | Patterns such as `1`, `'a'`, `"true"`, `1.0`, `1l`, `1L`, `1n` | `*)`
`|` | `Ppat_interval of `constant * constant`` | `(*` | Patterns such as `'a'..'z'`. Other forms of interval are recognized by the parser but rejected by the type-checker. | `*)`
`|` | `Ppat_tuple of `(string option * pattern) list * Asttypes.closed_flag`` | `(*` | `Ppat_tuple(pl, Closed)` represents `(P1, ..., Pn)` when `pl` is `(None, P1); ...; (None, Pn)` `(~L1:P1, ..., ~Ln:Pn)` when `pl` is `(Some L1, P1); ...; (Some Ln, Pn)` A mix, e.g. `(~L1:P1, P2)` when `pl` is `(Some L1, P1); (None, P2)` `Ppat_tuple(pl, Open)` is similar, but indicates the pattern additionally ends in a `..`. Invariant: If Closed, `n >= 2`. If Open, `n >= 1`. | `*)`
`|` | `Ppat_construct of `Longident.t Asttypes.loc * (string Asttypes.loc list * pattern) option`` | `(*` | `Ppat_construct(C, args)` represents: `C` when `args` is `None`, `C P` when `args` is `Some ([], P)` `C (P1, ..., Pn)` when `args` is `Some ([], Ppat_tuple [P1; ...; Pn])` `C (type a b) P` when `args` is `Some ([a; b], P)` | `*)`
`|` | `Ppat_variant of `Asttypes.label * pattern option`` | `(*` | `Ppat_variant(`A, pat)` represents: ``A` when `pat` is `None`, ``A P` when `pat` is `Some P` | `*)`
`|` | `Ppat_record of `(Longident.t Asttypes.loc * pattern) list * Asttypes.closed_flag`` | `(*` | `Ppat_record([(l1, P1) ; ... ; (ln, Pn)], flag)` represents: `{ l1=P1; ...; ln=Pn }` when `flag` is `Closed` `{ l1=P1; ...; ln=Pn; _}` when `flag` is `Open` Invariant: `n > 0` | `*)`
`|` | `Ppat_array of `pattern list`` | `(*` | Pattern `[| P1; ...; Pn |]` | `*)`
`|` | `Ppat_or of `pattern * pattern`` | `(*` | Pattern `P1 | P2` | `*)`
`|` | `Ppat_constraint of `pattern * core_type`` | `(*` | Pattern `(P : T)` | `*)`
`|` | `Ppat_type of `Longident.t Asttypes.loc`` | `(*` | Pattern `#tconst` | `*)`
`|` | `Ppat_lazy of `pattern`` | `(*` | Pattern `lazy P` | `*)`
`|` | `Ppat_unpack of `string option Asttypes.loc`` | `(*` | `Ppat_unpack(s)` represents: `(module P)` when `s` is `Some "P"` `(module _)` when `s` is `None` Note: `(module P : S)` is represented as `Ppat_constraint(Ppat_unpack(Some "P"), Ptyp_package S)` | `*)`
`|` | `Ppat_exception of `pattern`` | `(*` | Pattern `exception P` | `*)`
`|` | `Ppat_effect of `pattern * pattern``
`|` | `Ppat_extension of `extension`` | `(*` | Pattern `[%id]` | `*)`
`|` | `Ppat_open of `Longident.t Asttypes.loc * pattern`` | `(*` | Pattern `M.(P)` | `*)`

### Value expressions

    type expression = {

`` | `pexp_desc : `expression_desc`;`
`` | `pexp_loc : `Location.t`;`
`` | `pexp_loc_stack : `location_stack`;`
`` | `pexp_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type expression_desc =

`|` | `Pexp_ident of `Longident.t Asttypes.loc`` | `(*` | Identifiers such as `x` and `M.x` | `*)`
`|` | `Pexp_constant of `constant`` | `(*` | Expressions constant such as `1`, `'a'`, `"true"`, `1.0`, `1l`, `1L`, `1n` | `*)`
`|` | `Pexp_let of `Asttypes.rec_flag * value_binding list * expression`` | `(*` | `Pexp_let(flag, [(P1,E1) ; ... ; (Pn,En)], E)` represents: `let P1 = E1 and ... and Pn = EN in E` when `flag` is `Nonrecursive`, `let rec P1 = E1 and ... and Pn = EN in E` when `flag` is `Recursive`. | `*)`
`|` | `Pexp_function of `function_param list * type_constraint option * function_body`` | `(*` | `Pexp_function ([P1; ...; Pn], C, body)` represents any construct involving `fun` or `function`, including: `fun P1 ... Pn -> E` when `body = Pfunction_body E` `fun P1 ... Pn -> function p1 -> e1 | ... | pm -> em` when `body = Pfunction_cases [ p1 -> e1; ...; pm -> em ]` `C` represents a type constraint or coercion placed immediately before the arrow, e.g. `fun P1 ... Pn : ty -> ...` when `C = Some (Pconstraint ty)`. A function must have parameters: in `Pexp_function (params, _, body)`, if `params` does not contain a `Pparam_val _`, `body` must be `Pfunction_cases _`. | `*)`
`|` | `Pexp_apply of `expression * (Asttypes.arg_label * expression) list`` | `(*` | `Pexp_apply(E0, [(l1, E1) ; ... ; (ln, En)])` represents `E0 ~l1:E1 ... ~ln:En` `li` can be `Nolabel` (non labeled argument), `Labelled` (labelled arguments) or `Optional` (optional argument). Invariant: `n > 0` | `*)`
`|` | `Pexp_match of `expression * case list`` | `(*` | `match E0 with P1 -> E1 | ... | Pn -> En` | `*)`
`|` | `Pexp_try of `expression * case list`` | `(*` | `try E0 with P1 -> E1 | ... | Pn -> En` | `*)`
`|` | `Pexp_tuple of `(string option * expression) list`` | `(*` | `Pexp_tuple(el)` represents `(E1, ..., En)` when `el` is `(None, E1); ...; (None, En)` `(~L1:E1, ..., ~Ln:En)` when `el` is `(Some L1, E1); ...; (Some Ln, En)` A mix, e.g., `(~L1:E1, E2)` when `el` is `(Some L1, E1); (None, E2)` Invariant: `n >= 2` | `*)`
`|` | `Pexp_construct of `Longident.t Asttypes.loc * expression option`` | `(*` | `Pexp_construct(C, exp)` represents: `C` when `exp` is `None`, `C E` when `exp` is `Some E`, `C (E1, ..., En)` when `exp` is `Some (Pexp_tuple[E1;...;En])` | `*)`
`|` | `Pexp_variant of `Asttypes.label * expression option`` | `(*` | `Pexp_variant(`A, exp)` represents ``A` when `exp` is `None` ``A E` when `exp` is `Some E` | `*)`
`|` | `Pexp_record of `(Longident.t Asttypes.loc * expression) list * expression option`` | `(*` | `Pexp_record([(l1,P1) ; ... ; (ln,Pn)], exp0)` represents `{ l1=P1; ...; ln=Pn }` when `exp0` is `None` `{ E0 with l1=P1; ...; ln=Pn }` when `exp0` is `Some E0` Invariant: `n > 0` | `*)`
`|` | `Pexp_field of `expression * Longident.t Asttypes.loc`` | `(*` | `E.l` | `*)`
`|` | `Pexp_setfield of `expression * Longident.t Asttypes.loc * expression`` | `(*` | `E1.l <- E2` | `*)`
`|` | `Pexp_array of `expression list`` | `(*` | `[| E1; ...; En |]` | `*)`
`|` | `Pexp_ifthenelse of `expression * expression * expression option`` | `(*` | `if E1 then E2 else E3` | `*)`
`|` | `Pexp_sequence of `expression * expression`` | `(*` | `E1; E2` | `*)`
`|` | `Pexp_while of `expression * expression`` | `(*` | `while E1 do E2 done` | `*)`
`|` | `Pexp_for of `pattern * expression * expression * Asttypes.direction_flag * expression`` | `(*` | `Pexp_for(i, E1, E2, direction, E3)` represents: `for i = E1 to E2 do E3 done` when `direction` is `Upto` `for i = E1 downto E2 do E3 done` when `direction` is `Downto` | `*)`
`|` | `Pexp_constraint of `expression * core_type`` | `(*` | `(E : T)` | `*)`
`|` | `Pexp_coerce of `expression * core_type option * core_type`` | `(*` | `Pexp_coerce(E, from, T)` represents `(E :> T)` when `from` is `None`, `(E : T0 :> T)` when `from` is `Some T0`. | `*)`
`|` | `Pexp_send of `expression * Asttypes.label Asttypes.loc`` | `(*` | `E # m` | `*)`
`|` | `Pexp_new of `Longident.t Asttypes.loc`` | `(*` | `new M.c` | `*)`
`|` | `Pexp_setinstvar of `Asttypes.label Asttypes.loc * expression`` | `(*` | `x <- 2` | `*)`
`|` | `Pexp_override of `(Asttypes.label Asttypes.loc * expression) list`` | `(*` | `{< x1 = E1; ...; xn = En >}` | `*)`
`|` | `Pexp_letmodule of `string option Asttypes.loc * module_expr * expression`` | `(*` | `let module M = ME in E` | `*)`
`|` | `Pexp_letexception of `extension_constructor * expression`` | `(*` | `let exception C in E` | `*)`
`|` | `Pexp_assert of `expression`` | `(*` | `assert E`. Note: `assert false` is treated in a special way by the type-checker. | `*)`
`|` | `Pexp_lazy of `expression`` | `(*` | `lazy E` | `*)`
`|` | `Pexp_poly of `expression * core_type option`` | `(*` | Used for method bodies. Can only be used as the expression under `Cfk_concrete` for methods (not values). | `*)`
`|` | `Pexp_object of `class_structure`` | `(*` | `object ... end` | `*)`
`|` | `Pexp_newtype of `string Asttypes.loc * expression`` | `(*` | `fun (type t) -> E` | `*)`
`|` | `Pexp_pack of `module_expr * package_type option`` | `(*` | `(module ME)` or `(module ME : S)`. | `*)`
`|` | `Pexp_open of `open_declaration * expression`` | `(*` | - `M.(E)` `let open M in E` `let open! M in E` | `*)`
`|` | `Pexp_letop of `letop`` | `(*` | - `let* P = E0 in E1` `let* P0 = E00 and* P1 = E01 in E1` | `*)`
`|` | `Pexp_extension of `extension`` | `(*` | `[%id]` | `*)`
`|` | `Pexp_unreachable` | `(*` | `.` | `*)`

    type case = {

`` | `pc_lhs : `pattern`;`
`` | `pc_guard : `expression option`;`
`` | `pc_rhs : `expression`;`

`}`

Values of type `Parsetree.case` represents `(P -> E)` or `(P when E0 -> E)`

    type letop = {

`` | `let_ : `binding_op`;`
`` | `ands : `binding_op list`;`
`` | `body : `expression`;`

`}`

    type binding_op = {

`` | `pbop_op : `string Asttypes.loc`;`
`` | `pbop_pat : `pattern`;`
`` | `pbop_exp : `expression`;`
`` | `pbop_loc : `Location.t`;`

`}`

    type function_param_desc =

`|` | `Pparam_val of `Asttypes.arg_label * expression option * pattern`` | `(*` | `Pparam_val (lbl, exp0, P)` represents the parameter: `P` when `lbl` is `Nolabel` and `exp0` is `None` `~l:P` when `lbl` is `Labelled l` and `exp0` is `None` `?l:P` when `lbl` is `Optional l` and `exp0` is `None` `?l:(P = E0)` when `lbl` is `Optional l` and `exp0` is `Some E0` Note: If `E0` is provided, only `Optional` is allowed. | `*)`
`|` | `Pparam_newtype of `string Asttypes.loc`` | `(*` | `Pparam_newtype x` represents the parameter `(type x)`. `x` carries the location of the identifier, whereas the `pparam_loc` on the enclosing `function_param` node is the location of the `(type x)` as a whole. Multiple parameters `(type a b c)` are represented as multiple `Pparam_newtype` nodes, let's say:
     [ { pparam_kind = Pparam_newtype a; pparam_loc = loc1 };
               { pparam_kind = Pparam_newtype b; pparam_loc = loc2 };
               { pparam_kind = Pparam_newtype c; pparam_loc = loc3 };
             ]
Here, the first loc `loc1` is the location of `(type a b c)`, and the subsequent locs `loc2` and `loc3` are the same as `loc1`, except marked as ghost locations. The locations on `a`, `b`, `c`, correspond to the variables `a`, `b`, and `c` in the source code. | `*)`

    type function_param = {

`` | `pparam_loc : `Location.t`;`
`` | `pparam_desc : `function_param_desc`;`

`}`

    type function_body =

`|` | `Pfunction_body of `expression``
`|` | `Pfunction_cases of `case list * Location.t * attributes`` | `(*` | In `Pfunction_cases (_, loc, attrs)`, the location extends from the start of the `function` keyword to the end of the last case. The compiler will only use typechecking-related attributes from `attrs`, e.g. enabling or disabling a warning. | `*)`

See the comment on `Pexp_function`.

    type type_constraint =

`|` | `Pconstraint of `core_type``
`|` | `Pcoerce of `core_type option * core_type`` | `(*` | See the comment on `Pexp_function`. | `*)`

### Value descriptions

    type value_description = {

`` | `pval_name : `string Asttypes.loc`;`
`` | `pval_type : `core_type`;`
`` | `pval_prim : `string list`;`
`` | `pval_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`
`` | `pval_loc : `Location.t`;`

`}`

Values of type `Parsetree.value_description` represents:

- `val x: T`, when `pval_prim` is `[]`
- `external x: T = "s1" ... "sn"` when `pval_prim` is `["s1";..."sn"]`

### Type declarations

    type type_declaration = {

`` | `ptype_name : `string Asttypes.loc`;`
`` | `ptype_params : `(core_type * (Asttypes.variance * Asttypes.injectivity)) list`;` | `(*` | `('a1,...'an) t` | `*)`
`` | `ptype_cstrs : `(core_type * core_type * Location.t) list`;` | `(*` | `... constraint T1=T1' ... constraint Tn=Tn'` | `*)`
`` | `ptype_kind : `type_kind`;`
`` | `ptype_private : `Asttypes.private_flag`;` | `(*` | for `= private ...` | `*)`
`` | `ptype_manifest : `core_type option`;` | `(*` | represents `= T` | `*)`
`` | `ptype_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`
`` | `ptype_loc : `Location.t`;`

`}`

Here are type declarations and their representation, for various `ptype_kind` and `ptype_manifest` values:

- `type t` when `type_kind` is `Ptype_abstract`, and `manifest` is `None`,
- `type t = T0` when `type_kind` is `Ptype_abstract`, and `manifest` is `Some T0`,
- `type t = C of T | ...` when `type_kind` is `Ptype_variant`, and `manifest` is `None`,
- `type t = T0 = C of T | ...` when `type_kind` is `Ptype_variant`, and `manifest` is `Some T0`,
- `type t = {l: T; ...}` when `type_kind` is `Ptype_record`, and `manifest` is `None`,
- `type t = T0 = {l : T; ...}` when `type_kind` is `Ptype_record`, and `manifest` is `Some T0`,
- `type t = ..` when `type_kind` is `Ptype_open`, and `manifest` is `None`.

    type type_kind =

`|` | `Ptype_abstract`
`|` | `Ptype_variant of `constructor_declaration list``
`|` | `Ptype_record of `label_declaration list`` | `(*` | Invariant: non-empty list | `*)`
`|` | `Ptype_open`

    type label_declaration = {

`` | `pld_name : `string Asttypes.loc`;`
`` | `pld_mutable : `Asttypes.mutable_flag`;`
`` | `pld_type : `core_type`;`
`` | `pld_loc : `Location.t`;`
`` | `pld_attributes : `attributes`;` | `(*` | `l : T [@id1] [@id2]` | `*)`

`}`

- `{ ...; l: T; ... }` when `pld_mutable` is `Immutable`,

- `{ ...; mutable l: T; ... }` when `pld_mutable` is `Mutable`.

Note: `T` can be a `Ptyp_poly`.

    type constructor_declaration = {

`` | `pcd_name : `string Asttypes.loc`;`
`` | `pcd_vars : `string Asttypes.loc list`;`
`` | `pcd_args : `constructor_arguments`;`
`` | `pcd_res : `core_type option`;`
`` | `pcd_loc : `Location.t`;`
`` | `pcd_attributes : `attributes`;` | `(*` | `C of ... [@id1] [@id2]` | `*)`

`}`

    type constructor_arguments =

`|` | `Pcstr_tuple of `core_type list``
`|` | `Pcstr_record of `label_declaration list`` | `(*` | Values of type `Parsetree.constructor_declaration` represents the constructor arguments of: `C of T1 * ... * Tn` when `res = None`, and `args = Pcstr_tuple [T1; ... ; Tn]`, `C: T0` when `res = Some T0`, and `args = Pcstr_tuple []`, `C: T1 * ... * Tn -> T0` when `res = Some T0`, and `args = Pcstr_tuple [T1; ... ; Tn]`, `C of {...}` when `res = None`, and `args = Pcstr_record [...]`, `C: {...} -> T0` when `res = Some T0`, and `args = Pcstr_record [...]`. | `*)`

    type type_extension = {

`` | `ptyext_path : `Longident.t Asttypes.loc`;`
`` | `ptyext_params : `(core_type * (Asttypes.variance * Asttypes.injectivity)) list`;`
`` | `ptyext_constructors : `extension_constructor list`;`
`` | `ptyext_private : `Asttypes.private_flag`;`
`` | `ptyext_loc : `Location.t`;`
`` | `ptyext_attributes : `attributes`;` | `(*` | ... `@@id1` `@@id2` | `*)`

`}`

Definition of new extensions constructors for the extensive sum type `t` (`type t += ...`).

    type extension_constructor = {

`` | `pext_name : `string Asttypes.loc`;`
`` | `pext_kind : `extension_constructor_kind`;`
`` | `pext_loc : `Location.t`;`
`` | `pext_attributes : `attributes`;` | `(*` | `C of ... [@id1] [@id2]` | `*)`

`}`

    type type_exception = {

`` | `ptyexn_constructor : `extension_constructor`;`
`` | `ptyexn_loc : `Location.t`;`
`` | `ptyexn_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`

`}`

Definition of a new exception (`exception E`).

    type extension_constructor_kind =

`|` | `Pext_decl of `string Asttypes.loc list * constructor_arguments * core_type option`` | `(*` | `Pext_decl(existentials, c_args, t_opt)` describes a new extension constructor. It can be: `C of T1 * ... * Tn` when: `existentials` is `[]`, `c_args` is `[T1; ...; Tn]`, `t_opt` is `None` `C: T0` when `existentials` is `[]`, `c_args` is `[]`, `t_opt` is `Some T0`. `C: T1 * ... * Tn -> T0` when `existentials` is `[]`, `c_args` is `[T1; ...; Tn]`, `t_opt` is `Some T0`. `C: 'a... . T1 * ... * Tn -> T0` when `existentials` is `['a;...]`, `c_args` is `[T1; ... ; Tn]`, `t_opt` is `Some T0`. | `*)`
`|` | `Pext_rebind of `Longident.t Asttypes.loc`` | `(*` | `Pext_rebind(D)` re-export the constructor `D` with the new name `C` | `*)`

## Class language

### Type expressions for the class language

    type class_type = {

`` | `pcty_desc : `class_type_desc`;`
`` | `pcty_loc : `Location.t`;`
`` | `pcty_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type class_type_desc =

`|` | `Pcty_constr of `Longident.t Asttypes.loc * core_type list`` | `(*` | - `c` `['a1, ..., 'an] c` | `*)`
`|` | `Pcty_signature of `class_signature`` | `(*` | `object ... end` | `*)`
`|` | `Pcty_arrow of `Asttypes.arg_label * core_type * class_type`` | `(*` | `Pcty_arrow(lbl, T, CT)` represents: `T -> CT` when `lbl` is `Nolabel`, `~l:T -> CT` when `lbl` is `Labelled l`, `?l:T -> CT` when `lbl` is `Optional l`. | `*)`
`|` | `Pcty_extension of `extension`` | `(*` | `%id` | `*)`
`|` | `Pcty_open of `open_description * class_type`` | `(*` | `let open M in CT` | `*)`

    type class_signature = {

`` | `pcsig_self : `core_type`;`
`` | `pcsig_fields : `class_type_field list`;`

`}`

Values of type `class_signature` represents:

- `object('selfpat) ... end`
- `object ... end` when `pcsig_self` is `Ptyp_any`

    type class_type_field = {

`` | `pctf_desc : `class_type_field_desc`;`
`` | `pctf_loc : `Location.t`;`
`` | `pctf_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`

`}`

    type class_type_field_desc =

`|` | `Pctf_inherit of `class_type`` | `(*` | `inherit CT` | `*)`
`|` | `Pctf_val of `(Asttypes.label Asttypes.loc * Asttypes.mutable_flag * Asttypes.virtual_flag * core_type)`` | `(*` | `val x: T` | `*)`
`|` | `Pctf_method of `(Asttypes.label Asttypes.loc * Asttypes.private_flag * Asttypes.virtual_flag * core_type)`` | `(*` | `method x: T` Note: `T` can be a `Ptyp_poly`. | `*)`
`|` | `Pctf_constraint of `(core_type * core_type)`` | `(*` | `constraint T1 = T2` | `*)`
`|` | `Pctf_attribute of `attribute`` | `(*` | `[@@@id]` | `*)`
`|` | `Pctf_extension of `extension`` | `(*` | `[%%id]` | `*)`

    type 'a class_infos = {

`` | `pci_virt : `Asttypes.virtual_flag`;`
`` | `pci_params : `(core_type * (Asttypes.variance * Asttypes.injectivity)) list`;`
`` | `pci_name : `string Asttypes.loc`;`
`` | `pci_expr : `'a`;`
`` | `pci_loc : `Location.t`;`
`` | `pci_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`

`}`

Values of type `class_expr class_infos` represents:

- `class c = ...`
- `class ['a1,...,'an] c = ...`
- `class virtual c = ...`

They are also used for "class type" declaration.

    type class_description = class_type class_infos

    type class_type_declaration = class_type class_infos

### Value expressions for the class language

    type class_expr = {

`` | `pcl_desc : `class_expr_desc`;`
`` | `pcl_loc : `Location.t`;`
`` | `pcl_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type class_expr_desc =

`|` | `Pcl_constr of `Longident.t Asttypes.loc * core_type list`` | `(*` | `c` and `['a1, ..., 'an] c` | `*)`
`|` | `Pcl_structure of `class_structure`` | `(*` | `object ... end` | `*)`
`|` | `Pcl_fun of `Asttypes.arg_label * expression option * pattern * class_expr`` | `(*` | `Pcl_fun(lbl, exp0, P, CE)` represents: `fun P -> CE` when `lbl` is `Nolabel` and `exp0` is `None`, `fun ~l:P -> CE` when `lbl` is `Labelled l` and `exp0` is `None`, `fun ?l:P -> CE` when `lbl` is `Optional l` and `exp0` is `None`, `fun ?l:(P = E0) -> CE` when `lbl` is `Optional l` and `exp0` is `Some E0`. | `*)`
`|` | `Pcl_apply of `class_expr * (Asttypes.arg_label * expression) list`` | `(*` | `Pcl_apply(CE, [(l1,E1) ; ... ; (ln,En)])` represents `CE ~l1:E1 ... ~ln:En`. `li` can be empty (non labeled argument) or start with `?` (optional argument). Invariant: `n > 0` | `*)`
`|` | `Pcl_let of `Asttypes.rec_flag * value_binding list * class_expr`` | `(*` | `Pcl_let(rec, [(P1, E1); ... ; (Pn, En)], CE)` represents: `let P1 = E1 and ... and Pn = EN in CE` when `rec` is `Nonrecursive`, `let rec P1 = E1 and ... and Pn = EN in CE` when `rec` is `Recursive`. | `*)`
`|` | `Pcl_constraint of `class_expr * class_type`` | `(*` | `(CE : CT)` | `*)`
`|` | `Pcl_extension of `extension`` | `(*` | `[%id]` | `*)`
`|` | `Pcl_open of `open_description * class_expr`` | `(*` | `let open M in CE` | `*)`

    type class_structure = {

`` | `pcstr_self : `pattern`;`
`` | `pcstr_fields : `class_field list`;`

`}`

Values of type `Parsetree.class_structure` represents:

- `object(selfpat) ... end`
- `object ... end` when `pcstr_self` is `Ppat_any`

    type class_field = {

`` | `pcf_desc : `class_field_desc`;`
`` | `pcf_loc : `Location.t`;`
`` | `pcf_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`

`}`

    type class_field_desc =

`|` | `Pcf_inherit of `Asttypes.override_flag * class_expr * string Asttypes.loc option`` | `(*` | `Pcf_inherit(flag, CE, s)` represents: `inherit CE` when `flag` is `Fresh` and `s` is `None`, `inherit CE as x` when `flag` is `Fresh` and `s` is `Some x`, `inherit! CE` when `flag` is `Override` and `s` is `None`, `inherit! CE as x` when `flag` is `Override` and `s` is `Some x` | `*)`
`|` | `Pcf_val of `(Asttypes.label Asttypes.loc * Asttypes.mutable_flag * class_field_kind)`` | `(*` | `Pcf_val(x,flag, kind)` represents: `val x = E` when `flag` is `Immutable` and `kind` is `Cfk_concrete(Fresh, E)` `val virtual x: T` when `flag` is `Immutable` and `kind` is `Cfk_virtual(T)` `val mutable x = E` when `flag` is `Mutable` and `kind` is `Cfk_concrete(Fresh, E)` `val mutable virtual x: T` when `flag` is `Mutable` and `kind` is `Cfk_virtual(T)` | `*)`
`|` | `Pcf_method of `(Asttypes.label Asttypes.loc * Asttypes.private_flag * class_field_kind)`` | `(*` | - `method x = E` (`E` can be a `Pexp_poly`) `method virtual x: T` (`T` can be a `Ptyp_poly`) | `*)`
`|` | `Pcf_constraint of `(core_type * core_type)`` | `(*` | `constraint T1 = T2` | `*)`
`|` | `Pcf_initializer of `expression`` | `(*` | `initializer E` | `*)`
`|` | `Pcf_attribute of `attribute`` | `(*` | `[@@@id]` | `*)`
`|` | `Pcf_extension of `extension`` | `(*` | `[%%id]` | `*)`

    type class_field_kind =

`|` | `Cfk_virtual of `core_type``
`|` | `Cfk_concrete of `Asttypes.override_flag * expression``

    type class_declaration = class_expr class_infos

## Module language

### Type expressions for the module language

    type module_type = {

`` | `pmty_desc : `module_type_desc`;`
`` | `pmty_loc : `Location.t`;`
`` | `pmty_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type module_type_desc =

`|` | `Pmty_ident of `Longident.t Asttypes.loc`` | `(*` | `Pmty_ident(S)` represents `S` | `*)`
`|` | `Pmty_signature of `signature`` | `(*` | `sig ... end` | `*)`
`|` | `Pmty_functor of `functor_parameter * module_type`` | `(*` | `functor(X : MT1) -> MT2` | `*)`
`|` | `Pmty_with of `module_type * with_constraint list`` | `(*` | `MT with ...` | `*)`
`|` | `Pmty_typeof of `module_expr`` | `(*` | `module type of ME` | `*)`
`|` | `Pmty_extension of `extension`` | `(*` | `[%id]` | `*)`
`|` | `Pmty_alias of `Longident.t Asttypes.loc`` | `(*` | `(module M)` | `*)`

    type functor_parameter =

`|` | `Unit` | `(*` | `()` | `*)`
`|` | `Named of `string option Asttypes.loc * module_type`` | `(*` | `Named(name, MT)` represents: `(X : MT)` when `name` is `Some X`, `(_ : MT)` when `name` is `None` | `*)`

    type signature = signature_item list

    type signature_item = {

`` | `psig_desc : `signature_item_desc`;`
`` | `psig_loc : `Location.t`;`

`}`

    type signature_item_desc =

`|` | `Psig_value of `value_description`` | `(*` | - `val x: T` `external x: T = "s1" ... "sn"` | `*)`
`|` | `Psig_type of `Asttypes.rec_flag * type_declaration list`` | `(*` | `type t1 = ... and ... and tn = ...` | `*)`
`|` | `Psig_typesubst of `type_declaration list`` | `(*` | `type t1 := ... and ... and tn := ...` | `*)`
`|` | `Psig_typext of `type_extension`` | `(*` | `type t1 += ...` | `*)`
`|` | `Psig_exception of `type_exception`` | `(*` | `exception C of T` | `*)`
`|` | `Psig_module of `module_declaration`` | `(*` | `module X = M` and `module X : MT` | `*)`
`|` | `Psig_modsubst of `module_substitution`` | `(*` | `module X := M` | `*)`
`|` | `Psig_recmodule of `module_declaration list`` | `(*` | `module rec X1 : MT1 and ... and Xn : MTn` | `*)`
`|` | `Psig_modtype of `module_type_declaration`` | `(*` | `module type S = MT` and `module type S` | `*)`
`|` | `Psig_modtypesubst of `module_type_declaration`` | `(*` | `module type S := ...` | `*)`
`|` | `Psig_open of `open_description`` | `(*` | `open X` | `*)`
`|` | `Psig_include of `include_description`` | `(*` | `include MT` | `*)`
`|` | `Psig_class of `class_description list`` | `(*` | `class c1 : ... and ... and cn : ...` | `*)`
`|` | `Psig_class_type of `class_type_declaration list`` | `(*` | `class type ct1 = ... and ... and ctn = ...` | `*)`
`|` | `Psig_attribute of `attribute`` | `(*` | `[@@@id]` | `*)`
`|` | `Psig_extension of `extension * attributes`` | `(*` | `[%%id]` | `*)`

    type module_declaration = {

`` | `pmd_name : `string option Asttypes.loc`;`
`` | `pmd_type : `module_type`;`
`` | `pmd_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`
`` | `pmd_loc : `Location.t`;`

`}`

Values of type `module_declaration` represents `S : MT`

    type module_substitution = {

`` | `pms_name : `string Asttypes.loc`;`
`` | `pms_manifest : `Longident.t Asttypes.loc`;`
`` | `pms_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`
`` | `pms_loc : `Location.t`;`

`}`

Values of type `module_substitution` represents `S := M`

    type module_type_declaration = {

`` | `pmtd_name : `string Asttypes.loc`;`
`` | `pmtd_type : `module_type option`;`
`` | `pmtd_attributes : `attributes`;` | `(*` | `... [@@id1] [@@id2]` | `*)`
`` | `pmtd_loc : `Location.t`;`

`}`

Values of type `module_type_declaration` represents:

- `S = MT`,
- `S` for abstract module type declaration, when `pmtd_type` is `None`.

    type 'a open_infos = {

`` | `popen_expr : `'a`;`
`` | `popen_override : `Asttypes.override_flag`;`
`` | `popen_loc : `Location.t`;`
`` | `popen_attributes : `attributes`;`

`}`

Values of type `'a open_infos` represents:

- `open! X` when `popen_override` is `Override` (silences the "used identifier shadowing" warning)
- `open X` when `popen_override` is `Fresh`

    type open_description = Longident.t Asttypes.loc open_infos

Values of type `open_description` represents:

- `open M.N`
- `open M(N).O`

    type open_declaration = module_expr open_infos

Values of type `open_declaration` represents:

- `open M.N`
- `open M(N).O`
- `open struct ... end`

    type 'a include_infos = {

`` | `pincl_mod : `'a`;`
`` | `pincl_loc : `Location.t`;`
`` | `pincl_attributes : `attributes`;`

`}`

    type include_description = module_type include_infos

Values of type `include_description` represents `include MT`

    type include_declaration = module_expr include_infos

Values of type `include_declaration` represents `include ME`

    type with_constraint =

`|` | `Pwith_type of `Longident.t Asttypes.loc * type_declaration`` | `(*` | `with type X.t = ...` Note: the last component of the longident must match the name of the type_declaration. | `*)`
`|` | `Pwith_module of `Longident.t Asttypes.loc * Longident.t Asttypes.loc`` | `(*` | `with module X.Y = Z` | `*)`
`|` | `Pwith_modtype of `Longident.t Asttypes.loc * module_type`` | `(*` | `with module type X.Y = Z` | `*)`
`|` | `Pwith_modtypesubst of `Longident.t Asttypes.loc * module_type`` | `(*` | `with module type X.Y := sig end` | `*)`
`|` | `Pwith_typesubst of `Longident.t Asttypes.loc * type_declaration`` | `(*` | `with type X.t := ..., same format as [Pwith_type]` | `*)`
`|` | `Pwith_modsubst of `Longident.t Asttypes.loc * Longident.t Asttypes.loc`` | `(*` | `with module X.Y := Z` | `*)`

### Value expressions for the module language

    type module_expr = {

`` | `pmod_desc : `module_expr_desc`;`
`` | `pmod_loc : `Location.t`;`
`` | `pmod_attributes : `attributes`;` | `(*` | `... [@id1] [@id2]` | `*)`

`}`

    type module_expr_desc =

`|` | `Pmod_ident of `Longident.t Asttypes.loc`` | `(*` | `X` | `*)`
`|` | `Pmod_structure of `structure`` | `(*` | `struct ... end` | `*)`
`|` | `Pmod_functor of `functor_parameter * module_expr`` | `(*` | `functor(X : MT1) -> ME` | `*)`
`|` | `Pmod_apply of `module_expr * module_expr`` | `(*` | `ME1(ME2)` | `*)`
`|` | `Pmod_apply_unit of `module_expr`` | `(*` | `ME1()` | `*)`
`|` | `Pmod_constraint of `module_expr * module_type`` | `(*` | `(ME : MT)` | `*)`
`|` | `Pmod_unpack of `expression`` | `(*` | `(val E)` | `*)`
`|` | `Pmod_extension of `extension`` | `(*` | `[%id]` | `*)`

    type structure = structure_item list

    type structure_item = {

`` | `pstr_desc : `structure_item_desc`;`
`` | `pstr_loc : `Location.t`;`

`}`

    type structure_item_desc =

`|` | `Pstr_eval of `expression * attributes`` | `(*` | `E` | `*)`
`|` | `Pstr_value of `Asttypes.rec_flag * value_binding list`` | `(*` | `Pstr_value(rec, [(P1, E1 ; ... ; (Pn, En))])` represents: `let P1 = E1 and ... and Pn = EN` when `rec` is `Nonrecursive`, `let rec P1 = E1 and ... and Pn = EN` when `rec` is `Recursive`. | `*)`
`|` | `Pstr_primitive of `value_description`` | `(*` | - `val x: T` `external x: T = "s1" ... "sn"` | `*)`
`|` | `Pstr_type of `Asttypes.rec_flag * type_declaration list`` | `(*` | `type t1 = ... and ... and tn = ...` | `*)`
`|` | `Pstr_typext of `type_extension`` | `(*` | `type t1 += ...` | `*)`
`|` | `Pstr_exception of `type_exception`` | `(*` | - `exception C of T` `exception C = M.X` | `*)`
`|` | `Pstr_module of `module_binding`` | `(*` | `module X = ME` | `*)`
`|` | `Pstr_recmodule of `module_binding list`` | `(*` | `module rec X1 = ME1 and ... and Xn = MEn` | `*)`
`|` | `Pstr_modtype of `module_type_declaration`` | `(*` | `module type S = MT` | `*)`
`|` | `Pstr_open of `open_declaration`` | `(*` | `open X` | `*)`
`|` | `Pstr_class of `class_declaration list`` | `(*` | `class c1 = ... and ... and cn = ...` | `*)`
`|` | `Pstr_class_type of `class_type_declaration list`` | `(*` | `class type ct1 = ... and ... and ctn = ...` | `*)`
`|` | `Pstr_include of `include_declaration`` | `(*` | `include ME` | `*)`
`|` | `Pstr_attribute of `attribute`` | `(*` | `[@@@id]` | `*)`
`|` | `Pstr_extension of `extension * attributes`` | `(*` | `[%%id]` | `*)`

    type value_constraint =

`|` | `Pvc_constraint of `{`
`` | `locally_abstract_univars : `string Asttypes.loc list`;`
`` | `typ : `core_type`;`
`}``
`|` | `Pvc_coercion of `{`
`` | `ground : `core_type option`;`
`` | `coercion : `core_type`;`
`}`` | `(*` | - `Pvc_constraint { locally_abstract_univars=[]; typ}` is a simple type constraint on a value binding: `let x : typ` More generally, in `Pvc_constraint { locally_abstract_univars; typ}` `locally_abstract_univars` is the list of locally abstract type variables in `let x: type a ... . typ` `Pvc_coercion { ground=None; coercion }` represents `let x :> typ` `Pvc_coercion { ground=Some g; coercion }` represents `let x : g :> typ` | `*)`

    type value_binding = {

`` | `pvb_pat : `pattern`;`
`` | `pvb_expr : `expression`;`
`` | `pvb_constraint : `value_constraint option`;`
`` | `pvb_attributes : `attributes`;`
`` | `pvb_loc : `Location.t`;`

`}`

`let pat : type_constraint = exp`

    type module_binding = {

`` | `pmb_name : `string option Asttypes.loc`;`
`` | `pmb_expr : `module_expr`;`
`` | `pmb_attributes : `attributes`;`
`` | `pmb_loc : `Location.t`;`

`}`

Values of type `module_binding` represents `module X = ME`

## Toplevel

### Toplevel phrases

    type toplevel_phrase =

`|` | `Ptop_def of `structure``
`|` | `Ptop_dir of `toplevel_directive`` | `(*` | `#use`, `#load` ... | `*)`

    type toplevel_directive = {

`` | `pdir_name : `string Asttypes.loc`;`
`` | `pdir_arg : `directive_argument option`;`
`` | `pdir_loc : `Location.t`;`

`}`

    type directive_argument = {

`` | `pdira_desc : `directive_argument_desc`;`
`` | `pdira_loc : `Location.t`;`

`}`

    type directive_argument_desc =

`|` | `Pdir_string of `string``
`|` | `Pdir_int of `string * char option``
`|` | `Pdir_ident of `Longident.t``
`|` | `Pdir_bool of `bool``