-
Notifications
You must be signed in to change notification settings - Fork 125
/
parser_utils.mli
501 lines (444 loc) · 19.9 KB
/
parser_utils.mli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
(*
Copyright © 2011 MLstate
This file is part of OPA.
OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.
OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.
You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)
(**
Functions used by the parser to generate code
Index:
- General functions
- Error functions
- Hints utils
- Generating fresh stuff
- Dealing with labels
- Tuples and records
- Identifier
- Constants
- Lambda, application
- Re tuple and records, for generating code while duplicating labels
- Generating datastructures
- Generating other AST nodes
- Call to OPA functions, that are supposed to be defined in the stdlib
- Utilities on patterns
- Utils on type constants
- Utils on type vars
- General buiders for types
- Various typenames
- Type utils for directives
- Utils for building directives
- Utils for parser_xml
- Utils for CSS
- Utils for inlined CSS
- Utils for trx parser
- Utils to duplicate a tree while regenerating all the annotations
*)
open QmlLoc
open SurfaceAst
(* mli and variants are a nightmare *)
type ('a,'b) coerced_expr = ('a, [> `coerce ] as 'b) expr
type ('a,'b) coerced_expr_node = ('a, [> `coerce ] as 'b) expr_node
(** General functions *)
val cur2 : ('a * 'b -> 'c) -> 'a -> 'b -> 'c
val unc2 : ('a -> 'b -> 'c) -> 'a * 'b -> 'c
(** Error functions *)
exception Specific_parse_error of (FilePos.pos * string)
val const_ty_to_string : string ty_node -> string
val isolate : string -> string
val warning1 : string -> annot -> unit
val error1 : string -> annot -> 'a
val error_comment : annot -> 'a
val error_string : annot -> 'a
val error_char_escape : char -> annot -> 'a
val error_fun_space : annot -> 'a
val error_directive_not_good_arguments : string * annot -> 'a
val error_static_record : string * annot -> 'a
val error_static_string : string * annot -> 'a
val error_not_a_directive : string * annot -> 'a
val error_directive_number_argument : int -> ?max:int -> int -> string * annot -> 'a
val error_directive_wrong_arguments_type : string * annot -> 'a
val error_char_overflow : annot -> 'a
val error_int_overflow : annot -> 'a
val error_neither_ident_nor_call : annot -> 'a
val error_redefinition_basic_type : string ty -> 'a
val error_bad_compare : annot -> 'a
val error_static_xml : annot -> 'a
val error_consecutive_arrow : annot -> 'a
val error_sliced_expr : annot -> 'a
val error_db_file_without_slash : string * annot -> 'a
val error_conflicting_type_def_visibility :
(SurfaceAst.type_def_visibility * SurfaceAst.type_def_visibility * annot) ->
'a
(** Hints utils *)
(* used to warn of possible mistakes *)
type hint = [ `function_call of annot | `declaration of annot | `same_indent of (annot * annot) | `same_indents of annot list ]
val push_hint : hint -> unit
val clear_hints : unit -> unit
val print_hints : unit -> unit
(* a reference to the name of the file currently being parsed (needed as id for FilePos) *)
val filename : string ref
(** Generating fresh stuff *)
val fresh_id : unit -> int
val fresh_variable : unit -> string
val fresh_name : ?name:string -> unit -> string
(** Dealing with labels *)
val annot : FilePos.pos -> annot
val builtin: unit -> annot
(* [pos_only filename offset_start offset_stop] *)
val pos_only : string -> int -> int -> annot
val decorate : string -> 'a -> int -> int -> 'a label
val undecorate : 'a * annot -> 'a
val label : 'a * annot -> annot
val copy_label : annot -> annot
(* unlike [label], the label here is copied *)
val nlabel : 'a * annot -> annot
val union_annot : annot -> annot -> annot
val union_annot2 : 'a * annot -> 'b * annot -> annot
val union_annot_list : ('a * annot) list -> annot
val union_annot_list_snd : ('a * ('b * annot)) list -> annot
val wrap : (annot -> 'a) -> annot -> 'a * annot
val wrap_e : ('a * annot -> 'b) -> 'a * annot -> 'b * annot
val map_annot : ('a -> 'b) -> 'a * annot -> 'b * annot
(** Tuples and records *)
(* return a record/pat record/type record*)
val encode_tuple_as_record : (string option * 'a) list -> (string * 'a) list
val encode_tuple : 'a list -> (string * 'a) list
val encode_record : (string * 'a) list -> (string * 'a) list
val encode_tuple_pos : ('a * annot) list -> (string * ('a * annot)) list * annot
val encode_record_pos : (string * ('a * annot)) list -> (string * ('a * annot)) list label
val encode_args_as_record : 'a list -> (string * 'a) list
val encode_args_as_record_pos : ('a * annot) list -> (string * ('a * annot)) list * annot
(** Identifier *)
val var_to_patvar : 'a * annot -> 'a pat
val var_to_exprvar : 'a * annot -> ('a, 'c) expr
val patident : 'a -> annot -> 'a pat
val patvar : 'a -> annot -> 'a pat
val ident : 'a -> annot -> ('a, 'c) expr
val fresh_ident_pat : annot -> (string, 'a) expr * string pat
(** Constants *)
val void_pat : annot -> 'a pat
val void : annot -> ('a,'b) coerced_expr
val true_pat : annot -> 'a pat
val true_ : annot -> ('a,'b) coerced_expr
val false_pat : annot -> 'a pat
val false_ : annot -> ('a,'b) coerced_expr
val string : string -> annot -> ('a, 'b) expr
val string2 : string * annot -> ('a, 'b) expr
val float2 : float * annot -> ('a, 'b) expr
val float : float -> annot -> ('a, 'b) expr
val int2 : int * annot -> ('a, 'b) expr
val int : int -> annot -> ('a, 'b) expr
val floatint2 : int * annot -> ('a, 'b) expr
val intfloat2 : float * annot -> ('a, 'b) expr
val bool : bool -> annot -> ('a, 'b) coerced_expr
val char : char -> annot -> ('a, 'b) expr
(** Lambda, application *)
val args_expr_to_lambda : ?zero_ary:annot -> 'a pat list -> ('a, 'b) expr -> ('a, 'b) expr
val ( & ) : ('a, 'b) expr -> ('a, 'b) expr list -> ('a, 'b) expr
val ( &. ) : ('a, 'b) expr -> ('a, 'b) expr list -> ('a, 'b) expr_node
val apply_f_with_holes : (string, 'a) expr -> [< `expr of (string, 'a) expr | `hole of annot ] list -> (string, 'a) expr
val function_ : (string pat * (string, 'a) expr) list -> annot -> (string, 'a) expr_node
val lambda_to_lambda : ((string, 'a) expr -> (string, 'b) expr) -> annot -> (string, 'b) expr
val lambda : string -> (string, 'a) expr -> (string, 'a) expr_node
val make_function2 :
((string * (string, 'a) expr) list ->
(string, 'a) expr -> 'b * 'c) ->
((string, 'a) expr ->
'd -> (string, 'a) expr_node * 'e) ->
[< `expr of (string, 'a) expr | `hole of annot ] ->
([< `dot of string
| `double_dot of 'd
| `function_call of
[< `expr of (string, 'a) expr | `hole of annot ]
list &
[< `expr of (string, 'a) expr | `hole of 'f ] list ] *
annot)
list -> 'b
val apply_operators :
[< `left | `nonassoc | `right ] ->
[ `expr of (string, 'a) expr | `hole of annot ] *
((string, 'a) expr *
[ `expr of (string, 'a) expr | `hole of annot ])
list -> (string, 'a) expr
(** Re tuple and records, for generating code while duplicating labels *)
val tuple_nocons : ('a,'b) expr list -> ('a,'b) record
val tuple : ('a, 'b) expr list -> ('a, 'b) expr
val record_nocons : (string * ('a,'b) expr) list -> ('a,'b) record
val record : (string * ('a,'b) expr) list -> ('a,'b) expr
val tuple_pat_nocons : 'a pat list -> 'a pat_record_node * annot
val tuple_pat : 'a pat list -> 'a pat
val record_pat_nocons : (string * 'a pat) list -> 'a pat_record_node * annot
val record_pat :'a pat_record_node -> 'a pat
val simple_record : string -> annot -> ('a, 'b) coerced_expr_node
val record1 : string -> ('a, 'b) expr -> ('a, 'b) expr
val simple_record_expr : string -> annot -> ('a, 'b) coerced_expr
val simple_record_expr2 : string * annot -> ('a, 'b) coerced_expr
val default_value_in_expr_record : bool ->
[< `binding of 'a * (string, [> `coerce ] as 'c) SurfaceAst.expr
| `noassign of 'a *
[< `novalue of string * QmlLoc.annot
| `value of (string, 'c) SurfaceAst.expr ] *
string SurfaceAst.ty option ] list ->
('a * (string, 'c) SurfaceAst.expr) list
val default_value_in_pat_record : bool ->
(string * [< `novalue of string * QmlLoc.annot
| `value of string SurfaceAst.pat ] * string SurfaceAst.ty option) list ->
(string * string SurfaceAst.pat) list
val default_value_in_type_record : bool ->
(string * [< `novalue of string * QmlLoc.annot
| `value of string SurfaceAst.ty ]) list ->
(string * string SurfaceAst.ty) list
(** Generating datastructures *)
val list_nil : annot -> (string, 'b) coerced_expr
val list_nil_pat : annot -> string pat
val list_cons : (string, [> `coerce ] as 'b) expr -> (string, 'b) expr -> (string, 'b) expr
val list_cons_pat : string pat -> string pat -> string pat
val some : (string, 'b) expr -> (string, 'b) coerced_expr
val none : annot -> (string, 'b) coerced_expr
val option_expr_of_expr_option : (string, 'b) expr option -> annot -> (string, 'b) coerced_expr
val list_pat_of_pat_list :
?tl:(string pat) -> string pat list -> annot -> string pat
val list_expr_of_expr_list :
?tl:(string,'a) expr -> (string, [> `coerce ] as 'a) expr list -> annot -> (string, 'a) expr
val list_expr_of_expr_list_unsafe : (string, [> `coerce ] as 'a) expr list -> (string, 'a) expr(**Fails if the list is empty*)
val list_constructors_of_string_list: (string * annot) list -> annot -> (string, [> `coerce ]) expr
(** Generating other AST nodes *)
val letins : ('a * ('a, 'b) expr) list -> ('a, 'b) expr -> ('a, 'b) expr
val letin : 'a -> ('a, 'b) expr -> ('a, 'b) expr -> ('a, 'b) expr
val dot : ('a, 'b) expr -> string -> ('a, 'b) expr
val dot_path : ('a,'b) expr -> string list -> ('a,'b) expr
val dots : string list -> annot -> (string, 'a) expr
val dots2 : (string * annot) list -> (string, 'a) expr
val applys : ('a, 'b) expr -> ('a, 'b) expr list -> ('a, 'b) expr
val apply : ('a, 'b) expr -> ('a, 'b) expr -> ('a, 'b) expr
(** Call to OPA functions, that are supposed to be defined in the stdlib *)
val append : (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr
val stringmap_empty : annot -> (string, 'a) expr
val cssentrymap_empty : annot -> (string, 'a) expr
val stringmap_add : annot -> (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr
val cssentrymap_add : annot -> (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr
val map_add_merge : annot -> (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr -> (string, 'a) expr
(** Utilities on patterns *)
val if_then_else : ('a, 'b) coerced_expr -> ('a, 'b) expr -> ('a, 'b) expr option -> ('a, 'b) expr_node
(* transform [let pat = expr in expr] into [match expr with pat -> expr] *)
val bind_in_to_expr_in : string pat * (string, [< all_directives > `coerce ] as 'a) expr -> (string, 'a) expr -> (string, 'a) expr_node
val pat_in_to_simple_bindings : (string pat * ((string, [< all_directives > `coerce `recval ]) expr as 'expr)) -> (string * 'expr) list
(** Utils on type definitions *)
val merge_type_def_visibility:
SurfaceAst.type_def_visibility list -> QmlLoc.annot ->
SurfaceAst.type_def_visibility
(**
Merge options (directives) of typedefs.
The global is the options read before the 'type' keyword,
which is global to all type defs, in case of a type ... and
construction.
The local is the options just given to 1 type defs.
{[
@global type toto = ...
and @local tata = ...
]}
This function merge the options, or raise an error in case
of incompatible options.
*)
val merge_type_def_options :
global:QmlAst.ty_def_options ->
local:QmlAst.ty_def_options ->
QmlAst.ty_def_options
(** Utils on type constants *)
val type_const : const_ty_node -> annot -> 'a ty
val tyint : annot -> 'a ty
val tyfloat : annot -> 'a ty
val tystring : annot -> 'a ty
val tychar : annot -> 'a ty
val tyvoid_ : 'a ty_node
val tyvoid : annot -> 'a ty
(** Utils on type vars *)
val tyvar : 'a -> annot -> 'a ty
val fresh_tyvar : annot -> string ty
val colvar : 'a -> annot -> 'a sum_t
val alpha : annot -> string ty
val beta : annot -> string ty
(** General buiders for types *)
val row_t_tuple : ?rowvar:'a rowvar -> 'a ty list -> 'a row_t
val row_t_record : ?rowvar:'a rowvar -> 'a fields_t_node -> 'a row_t
val row_t : 'a ty list -> annot -> 'a row_t
val arrow_t_node : 'a ty list -> 'a ty -> annot -> 'a arrow_t_node
val arrow_t : 'a ty list -> 'a ty -> annot -> 'a arrow_t
val arrow : 'a ty list -> 'a ty -> annot -> 'a ty_node
val arrow2 : 'a ty -> 'a ty -> annot -> 'a ty_node
val typenamed : 'a -> 'a ty list -> annot -> 'a ty
val row_label : string ty -> annot -> string row_t
val row : string ty -> _ * annot -> string row_t
val tuple_type : ?rowvar:'a rowvar -> 'a ty list -> 'a ty
val record_type : ?rowvar:'a rowvar -> 'a fields_t_node -> 'a ty
val tuple_string : 'a list -> string
val tuple_name : 'a list -> annot -> string ty
(** Various typenames *)
val tyxhtml : annot -> string ty
val tyxml : annot -> string ty
val tytext : annot -> string ty
val tybool : annot -> string ty
val tylist : string ty -> annot -> string ty
val tyaction : annot -> string ty
val tyopaty: annot -> string ty
(** Utils for building directives *)
val coerce : ('b, [> `coerce ] as 'a) expr -> 'b ty -> ('b, 'a) expr_node
val coerce_expr : ('b, [> `coerce ] as 'a) expr -> 'b ty -> ('b, 'a) expr
val may_coerce_expr : (string, [> `coerce ] as 'a) expr -> string ty option -> (string, 'a) expr
val may_coerce_pat : string pat -> string ty option -> string pat
val coerce_name : (string, [> `coerce ] as 'a) expr -> string -> (string, 'a) expr_node
val coerce_name_expr : (string, [> `coerce ] as 'a) expr -> string -> (string, 'a) expr
val coerce_name_pat : string pat -> string -> string pat
val directive0 : 'a -> unit -> ('b, 'a) expr_node
val directive1 : 'a -> ('b, 'a) expr -> ('b, 'a) expr_node
val directive1' : (('c,'b) expr -> 'b) -> ('c, 'b) expr -> ('c, 'b) expr_node
val directive2 : 'a -> ('b, 'a) expr * ('b, 'a) expr -> ('b, 'a) expr_node
val directive2' : ('a -> 'b) -> 'a * ('c, 'b) expr -> ('c, 'b) expr_node
val parser_ : 'b -> ('a,[> `parser_ of 'b]) expr_node
val module_ : ('a,[> `module_] as 'b) expr -> ('a,'b) expr_node
val open_ : ('a, [> `open_ ] as 'b) expr list -> ('a, 'b) expr -> ('a, 'b) expr
val xml_parser : 'a -> ('b, [> `xml_parser of 'a ]) SurfaceAst.expr_node
val magic_to_string : (string, [> `magic_to_string ] as 'a) expr -> (string, 'a) expr_node
val magic_to_xml : (string, [> `magic_to_xml ] as 'a) expr -> (string, 'a) expr_node
val magic_to_text : (string, [> `magic_to_text ] as 'a) expr -> (string, 'a) expr_node
val magic_do : (string, [> `magic_do] as 'a) expr -> (string, 'a) expr
val toplevel_opens : ('a, [> `toplevel_open ] as 'b) expr list -> ('a, 'b) code_elt_node list
val bypass : string -> ('a, 'b) expr_node
val double_dot : (string, 'a) expr -> string -> (string, 'a) expr
val declaration_directive :
(parsing_directive * (string, parsing_directive) expr list * string ty list) label list ->
((_ * (string, parsing_directive) expr) list as 'a) -> 'a
(** Utils for parser_xml *)
type 'b dom_tag_args = {
args : (string * string * (string, 'b) expr) list;
class_ : (string, 'b) expr option;
style : (string, 'b) expr option;
xmlns_declaration: (string * (string, 'b) expr) list;
events : ((string, 'b) expr) list;
events_expr : (string, 'b) expr option;
events_options: ((string, 'b) expr) list;
href: (string, 'b) expr option
} constraint 'b = [> `coerce ]
val action :
string ->
(string, [> `coerce | `magic_to_string | `magic_to_xml ] as 'a)
expr ->
(string * [< `identity | `magicToString | `magicToXml ] * (string * (string, 'a) expr) list option) * annot ->
string * annot ->
(string, 'a) expr -> (string, 'a) expr_node
val appendlo : (string, 'a) expr -> (string, 'a) expr option -> (string, 'a) expr
val css_build : string * annot -> (string, 'a) expr list -> (string, 'a) expr
val css_build_unsafe : string -> (string, 'a) expr list -> (string, 'a) expr
val css_build1 : string -> annot -> (string, 'a) expr
val css_build1' : string -> 'a * annot -> (string, 'b) expr
val map_tuple4 : ('a -> 'b) -> 'a * 'a * 'a * 'a -> 'b * 'b * 'b * 'b
val empty_args : annot -> _ dom_tag_args
val arg_default : 'a dom_tag_args option * annot -> 'a dom_tag_args
val create_fragment : (string, [> `coerce ] as 'a) expr list -> annot -> (string, 'a) expr
val create_textnode : string * annot -> (string, [> `coerce ]) expr
val create_fragment_with_spaces : ((string * annot) option * (string, [> `coerce ] as 'a) expr) list * annot -> (string, 'a) expr
val create_empty_fragment : annot -> (string, [> `coerce ]) expr
val create_element :
(string * annot) * (string * annot) ->
'a dom_tag_args ->
(string, 'a) expr list ->
(string, 'a) expr
val tag_mismatch : (string * annot) * (string * annot) -> (string * annot) * (string * annot) -> unit
val add_arg :
'a dom_tag_args option * annot ->
(string * annot) * (string * annot) ->
(string, 'a) expr option -> 'a dom_tag_args
val to_handle : string * annot -> (string, [> `coerce ]) expr
val add_event :
'a dom_tag_args option * annot ->
string * annot ->
(string, 'a) expr -> 'a dom_tag_args
(**Set the options for an event (e.g. [stop_propagation], etc.)*)
val add_event_option:
'a dom_tag_args option * annot ->
string * annot ->
(string, 'a) expr -> 'a dom_tag_args
val add_events : 'b dom_tag_args option * annot -> (string, 'b) expr -> 'b dom_tag_args
val action_xml : (string, [> `coerce | `fun_action ] as 'a) expr -> (string, 'a) expr
(**
Concatenate a sequence of xml characters (represented as strings of length 1),
removing any meaningless whitespace
*)
val concat_xml_text: string list -> string
(**
Define the variables which may be necessary for xhtml.
*)
val around_xhtml: (string, 'a) expr -> (string, 'a) expr
val around_xmlns: (string, 'a) expr -> (string, 'a) expr
type xml_or_xhtml = Xml | Xhtml
val push_xml : xml_or_xhtml -> unit
val pop_xml : unit -> unit
val xhtml_mode : unit -> bool
val push_tag: string -> unit
val pop_tag: unit -> unit
val get_tag: unit -> string
(** Utils for CSS *)
val hexa2 : char * annot -> char * 'a -> ('b, 'c) expr
val rgba : ('a, 'b) expr -> ('a, 'b) expr -> ('a, 'b) expr -> ('a, 'b) expr -> ('a, 'b) expr
val color_hexa :
char * annot ->
char * annot ->
char * annot ->
char * annot ->
char * annot ->
char * annot ->
char * annot ->
char * annot -> ('e, 'f) expr
val rgb :
('a, 'b) expr ->
('a, 'b) expr ->
('a, 'b) expr -> ('a, 'b) expr
(** Utils for inlined CSS *)
val conv :
[< `bottom
| `center
| `left
| `right
| `size of ('a, 'b) coerced_expr
| `top ] *
annot -> ('a, 'b) expr
val background_position :
[< `bottom
| `center
| `left
| `right
| `size of ('a, 'b) coerced_expr & 'c
| `top
> `left `right ] *
annot ->
([< `bottom
| `center
| `left
| `right
| `size of ('a, 'b) coerced_expr
| `top
> `bottom `size `top ] *
annot) option -> ('a, 'b) expr * ('a, 'b) expr
val hyphen_to_underscore : string -> string
val css_build_with_prefix : string -> string * annot -> (string, 'a) expr
val simple_record_hyphen2 : string * annot -> ('a, 'b) coerced_expr
val css_simple_record_hyphen2 : string * annot -> ('a, 'b) coerced_expr
val list_style_def : string * annot -> ('a, 'b) coerced_expr
(** Utils for trx parser *)
val coerce_record1 : string -> (string, [> `coerce ] as 'a) expr -> string -> (string, 'a) expr
val coerce_simple_record : string -> annot -> string -> (string, [> `coerce ]) expr
(* re-groups ranges to properly take care of UTF8 characters *)
val convert_range : [`RANGE of char * char | `ONE of char] list ->
[`RANGE of int * int | `ONE of int ] list
(** utils for rewriting deep record syntactic sugar *)
val rewrite_long_extend_record :
((string * annot) list * (string, SurfaceAst.parsing_directive) SurfaceAst.expr) list ->
(string, SurfaceAst.parsing_directive) SurfaceAst.expr ->
(string, SurfaceAst.parsing_directive) SurfaceAst.expr