File: extfold.ml

package info (click to toggle)
camlp5 8.04.00-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,968 kB
  • sloc: ml: 137,918; makefile: 2,055; perl: 1,729; sh: 1,653; python: 38
file content (92 lines) | stat: -rw-r--r-- 2,358 bytes parent folder | download | duplicates (5)
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 ]
;