syntax.mli 6 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
(* ------------------------------------------------------------------------ *)

POTTIER Francois's avatar
POTTIER Francois committed
75 76 77
(* A parameter is either just a symbol, or an application of a symbol to
   a tuple of parameters. *)

POTTIER Francois's avatar
POTTIER Francois committed
78
type parameter =
79 80 81
  | ParameterVar of symbol Positions.located
  | ParameterApp of symbol Positions.located * parameters

POTTIER Francois's avatar
POTTIER Francois committed
82
and parameters =
83 84
    parameter list

POTTIER Francois's avatar
POTTIER Francois committed
85 86 87 88
(* ------------------------------------------------------------------------ *)

(* A declaration. (Only before joining.) *)

89 90
type declaration =

91
    (* Raw OCaml code. *)
92 93 94

  | DCode of Stretch.t

95
    (* Raw OCaml functor parameter. *)
96 97 98 99 100 101 102 103 104

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

    (* Terminal symbol (token) declaration. *)

  | DToken of Stretch.ocamltype option * terminal

    (* Start symbol declaration. *)

POTTIER Francois's avatar
POTTIER Francois committed
105
  | DStart of nonterminal
106 107 108 109 110 111 112 113 114

    (* Priority and associativity declaration. *)

  | DTokenProperties of terminal * token_associativity * precedence_level

    (* Type declaration. *)

  | DType of Stretch.ocamltype * parameter

115 116 117 118
    (* On-error-reduce declaration. *)

  | DOnErrorReduce of parameter

POTTIER Francois's avatar
POTTIER Francois committed
119 120
(* ------------------------------------------------------------------------ *)

121
(* A [%prec] annotation is optional. A production can carry at most one.
122
   If there is one, it is a symbol name. See [ParserAux]. *)
123 124

type branch_prec_annotation =
125 126
    symbol Positions.located option

POTTIER Francois's avatar
POTTIER Francois committed
127 128
(* ------------------------------------------------------------------------ *)

129 130 131 132
(* 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 =
133
  | ProductionLevel of Mark.t * int
134

POTTIER Francois's avatar
POTTIER Francois committed
135 136 137 138 139
(* ------------------------------------------------------------------------ *)

(* A producer is a pair of identifier and a parameter. In concrete syntax,
   it could be [e = expr], for instance. *)

140
type producer =
141
    identifier Positions.located * parameter
142

POTTIER Francois's avatar
POTTIER Francois committed
143 144 145 146
(* ------------------------------------------------------------------------ *)

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

147
type parameterized_branch =
POTTIER Francois's avatar
POTTIER Francois committed
148
    {
149 150
      pr_branch_position           : Positions.t;
      pr_producers                 : producer list;
POTTIER Francois's avatar
POTTIER Francois committed
151
      pr_action                    : action;
152
      pr_branch_prec_annotation    : branch_prec_annotation;
153
      pr_branch_production_level   : branch_production_level
154 155
    }

POTTIER Francois's avatar
POTTIER Francois committed
156 157 158 159
(* ------------------------------------------------------------------------ *)

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

160 161
type parameterized_rule =
    {
162 163 164 165 166 167
      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;
168 169
    }

POTTIER Francois's avatar
POTTIER Francois committed
170 171 172 173
(* ------------------------------------------------------------------------ *)

(* A partial grammar. (Only before joining.) *)

174
type partial_grammar =
175 176
    {
      pg_filename          : filename;
POTTIER Francois's avatar
POTTIER Francois committed
177
      pg_trailer           : trailer option;
178 179 180
      pg_declarations      : declaration Positions.located list;
      pg_rules             : parameterized_rule list;
    }
181

POTTIER Francois's avatar
POTTIER Francois committed
182 183 184 185 186 187 188 189 190 191 192 193
(* ------------------------------------------------------------------------ *)

(* 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.
 *)

194 195 196 197 198 199 200 201 202
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;
      p_on_error_reduce    : parameter list;
POTTIER Francois's avatar
POTTIER Francois committed
203
      p_rules              : parameterized_rule StringMap.t;
204
    }