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
|
(* camlp5r *)
(* extfold.ml,v *)
(* Copyright (c) INRIA 2007-2017 *)
type t 'te 'a 'b =
Gramext.g_entry 'te -> list (Gramext.g_symbol 'te) ->
(Stream.t 'te -> 'a) -> Stream.t 'te -> 'b
;
type tsep 'te 'a 'b =
Gramext.g_entry 'te -> list (Gramext.g_symbol 'te) ->
(Stream.t 'te -> 'a) -> (Stream.t 'te -> unit) -> Stream.t 'te -> 'b
;
value gen_fold0 final f e entry symbl psymb =
let rec fold accu =
parser
[ [: a = psymb; a = fold (f a accu) ! :] -> a
| [: :] -> accu ]
in
parser [: a = fold e :] -> final a
;
value gen_fold1 final f e entry symbl psymb =
let rec fold accu =
parser
[ [: a = psymb; a = fold (f a accu) ! :] -> a
| [: :] -> accu ]
in
parser [: a = psymb; a = fold (f a e) :] -> final a
;
value gen_fold0sep final f e entry symbl psymb psep =
let failed =
fun
[ [symb; sep] -> Grammar.symb_failed_txt entry sep symb
| _ -> "failed" ]
in
let rec kont accu =
parser
[ [: v = psep; a = psymb ? failed symbl; a = kont (f a accu) ! :] -> a
| [: :] -> accu ]
in
parser
[ [: a = psymb; a = kont (f a e) ! :] -> final a
| [: :] -> e ]
;
value gen_fold1sep final f e entry symbl psymb psep =
let failed =
fun
[ [symb; sep] -> Grammar.symb_failed_txt entry sep symb
| _ -> "failed" ]
in
let parse_top =
fun
[ [symb; _] -> Grammar.parse_top_symb entry symb
| _ -> raise Stream.Failure ]
in
let rec kont accu =
parser
[ [: v = psep;
a =
parser
[ [: a = psymb :] -> a
| [: a = parse_top symbl :] -> Obj.magic a
| [: :] -> raise (Stream.Error (failed symbl)) ];
a = kont (f a accu) ! :] ->
a
| [: :] -> accu ]
in
parser [: a = psymb; a = kont (f a e) ! :] -> final a
;
value sfold0 f e = gen_fold0 (fun x -> x) f e;
value sfold1 f e = gen_fold1 (fun x -> x) f e;
value sfold0sep f e = gen_fold0sep (fun x -> x) f e;
value sfold1sep f e = gen_fold1sep (fun x -> x) f e;
value cons x y = [x :: y];
value nil = [];
value slist0 entry = gen_fold0 List.rev cons nil entry;
value slist1 entry = gen_fold1 List.rev cons nil entry;
value slist0sep entry = gen_fold0sep List.rev cons nil entry;
value slist1sep entry = gen_fold1sep List.rev cons nil entry;
value sopt entry symbl psymb =
parser
[ [: a = psymb :] -> Some a
| [: :] -> None ]
;
|