syntax.mli 6.59 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
(* The type [partial_grammar] describes the abstract syntax that is produced
   by the parsers (yacc-parser and fancy-parser).

   The type [grammar] describes the abstract syntax that is obtained after one
   or more partial grammars are joined (see [PartialGrammar]). It differs in
   that declarations are organized in a more useful way and a number of
   well-formedness checks have been performed. *)

(* ------------------------------------------------------------------------ *)

11 12 13 14 15 16 17 18
(* Terminals and nonterminal symbols are strings. Identifiers
   (which are used to refer to a symbol's semantic value) are
   strings. A file name is a string. *)

type terminal =
    string

type nonterminal =
POTTIER Francois's avatar
POTTIER Francois committed
19
    string
20 21

type symbol =
POTTIER Francois's avatar
POTTIER Francois committed
22
    string
23

POTTIER Francois's avatar
POTTIER Francois committed
24 25
type identifier =
    string
26

POTTIER Francois's avatar
POTTIER Francois committed
27
type filename =
28 29
    string

30 31
(* ------------------------------------------------------------------------ *)

32
(* A trailer is a source file fragment. *)
33 34

type trailer =
35
    Stretch.t
36

37 38
(* ------------------------------------------------------------------------ *)

39
(* OCaml semantic actions are represented as stretches. *)
40 41 42 43

type action =
    Action.t

44 45
(* ------------------------------------------------------------------------ *)

POTTIER Francois's avatar
POTTIER Francois committed
46
(* Information about tokens. (Only after joining.) *)
47

POTTIER Francois's avatar
POTTIER Francois committed
48 49
type token_associativity =
    LeftAssoc
50 51 52 53
  | RightAssoc
  | NonAssoc
  | UndefinedAssoc

POTTIER Francois's avatar
POTTIER Francois committed
54 55
type precedence_level =
    UndefinedPrecedence
56 57 58 59 60 61

  (* Items are incomparable when they originate in different files. A
     brand of type [Mark.t] is used to record an item's origin. The
     positions allow locating certain warnings. *)

  | PrecedenceLevel of Mark.t * int * Lexing.position * Lexing.position
POTTIER Francois's avatar
POTTIER Francois committed
62

63 64
type token_properties =
    {
65 66 67
               tk_filename      : filename;
               tk_ocamltype     : Stretch.ocamltype option;
               tk_position      : Positions.t;
68
      mutable  tk_associativity : token_associativity;
69
      mutable  tk_precedence    : precedence_level;
POTTIER Francois's avatar
POTTIER Francois committed
70
      mutable  tk_is_declared   : bool;
71 72
    }

73 74
(* ------------------------------------------------------------------------ *)

75
(* A [%prec] annotation is optional. A production can carry at most one.
76
   If there is one, it is a symbol name. See [ParserAux]. *)
77 78

type branch_prec_annotation =
79 80
    symbol Positions.located option

POTTIER Francois's avatar
POTTIER Francois committed
81 82
(* ------------------------------------------------------------------------ *)

83 84 85 86
(* A "production level" is used to solve reduce/reduce conflicts. It reflects
   which production appears first in the grammar. See [ParserAux]. *)

type branch_production_level =
87
  | ProductionLevel of Mark.t * int
88

POTTIER Francois's avatar
POTTIER Francois committed
89 90
(* ------------------------------------------------------------------------ *)

91 92 93 94 95 96 97 98 99
(* A level is attached to every [%on_error_reduce] declaration. It is used
   to decide what to do when several such declarations are applicable in a
   single state. *)

type on_error_reduce_level =
  branch_production_level (* we re-use the above type, to save code *)

(* ------------------------------------------------------------------------ *)

100 101 102 103 104 105 106 107 108 109 110 111 112 113
(* A parameter is either just a symbol or an application of a symbol to a
   nonempty tuple of parameters. Before anonymous rules have been eliminated,
   it can also be an anonymous rule, represented as a list of branches. *)

type parameter =
  | ParameterVar of symbol Positions.located
  | ParameterApp of symbol Positions.located * parameters
  | ParameterAnonymous of parameterized_branch list Positions.located

and parameters =
    parameter list

(* ------------------------------------------------------------------------ *)

POTTIER Francois's avatar
POTTIER Francois committed
114 115 116
(* A producer is a pair of identifier and a parameter. In concrete syntax,
   it could be [e = expr], for instance. *)

117
and producer =
118
    identifier Positions.located * parameter
119

POTTIER Francois's avatar
POTTIER Francois committed
120 121 122 123
(* ------------------------------------------------------------------------ *)

(* A branch contains a series of producers and a semantic action. *)

124
and parameterized_branch =
POTTIER Francois's avatar
POTTIER Francois committed
125
    {
126 127
      pr_branch_position           : Positions.t;
      pr_producers                 : producer list;
POTTIER Francois's avatar
POTTIER Francois committed
128
      pr_action                    : action;
129
      pr_branch_prec_annotation    : branch_prec_annotation;
130
      pr_branch_production_level   : branch_production_level
131 132
    }

POTTIER Francois's avatar
POTTIER Francois committed
133 134 135 136
(* ------------------------------------------------------------------------ *)

(* A rule has a header and several branches. *)

137 138
type parameterized_rule =
    {
139 140 141 142 143 144
      pr_public_flag       : bool;
      pr_inline_flag       : bool;
      pr_nt                : nonterminal;
      pr_positions         : Positions.t list;
      pr_parameters        : symbol list;
      pr_branches          : parameterized_branch list;
145 146
    }

POTTIER Francois's avatar
POTTIER Francois committed
147 148
(* ------------------------------------------------------------------------ *)

149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
(* A declaration. (Only before joining.) *)

type declaration =

    (* Raw OCaml code. *)

  | DCode of Stretch.t

    (* Raw OCaml functor parameter. *)

  | DParameter of Stretch.ocamltype (* really a stretch *)

    (* Terminal symbol (token) declaration. *)

  | DToken of Stretch.ocamltype option * terminal

    (* Start symbol declaration. *)

  | DStart of nonterminal

    (* Priority and associativity declaration. *)

  | DTokenProperties of terminal * token_associativity * precedence_level

    (* Type declaration. *)

  | DType of Stretch.ocamltype * parameter

    (* On-error-reduce declaration. *)

179
  | DOnErrorReduce of parameter * on_error_reduce_level
180 181 182

(* ------------------------------------------------------------------------ *)

POTTIER Francois's avatar
POTTIER Francois committed
183 184
(* A partial grammar. (Only before joining.) *)

185
type partial_grammar =
186 187
    {
      pg_filename          : filename;
POTTIER Francois's avatar
POTTIER Francois committed
188
      pg_trailer           : trailer option;
189 190 191
      pg_declarations      : declaration Positions.located list;
      pg_rules             : parameterized_rule list;
    }
192

POTTIER Francois's avatar
POTTIER Francois committed
193 194 195 196 197 198 199 200 201 202 203 204
(* ------------------------------------------------------------------------ *)

(* A grammar. (Only after joining.) *)

(* The differences with partial grammars (above) are as follows:
   1. the file name is gone (there could be several file names, anyway).
   2. there can be several trailers, now known as postludes.
   3. declarations are organized by kind: preludes, functor %parameters,
      %start symbols, %types, %tokens, %on_error_reduce.
   4. rules are stored in a map, indexed by symbol names, instead of a list.
 *)

205 206 207 208 209 210 211 212
type grammar =
    {
      p_preludes           : Stretch.t list;
      p_postludes          : trailer list;
      p_parameters         : Stretch.t list;
      p_start_symbols      : Positions.t StringMap.t;
      p_types              : (parameter * Stretch.ocamltype Positions.located) list;
      p_tokens             : token_properties StringMap.t;
213
      p_on_error_reduce    : (parameter * on_error_reduce_level) list;
POTTIER Francois's avatar
POTTIER Francois committed
214
      p_rules              : parameterized_rule StringMap.t;
215
    }