Commits

james woodyatt  committed f201dc8

Add the seqx and seqx1 composers to Cf_llscan.

  • Participants
  • Parent commits 4442b52
  • Branches sideline

Comments (0)

Files changed (2)

File cf/cf_llscan.ml

 let seq1 p =
     bind p (fun hd -> bind (seq p) (fun tl -> ret (hd, tl)))
 
+let seqx =
+    let rec loop u f g i s =
+        match f i s with
+        | None ->
+            let d = i, List.rev u in
+            Some (d, s)
+        | Some (b, s) ->
+            let i, c = g b in
+            loop (c :: u) f g i s
+    in
+    let enter f g i s = loop [] f g i s in
+    enter
+
+let seqx1 =
+    let ( >>= ) = bind in
+    let enter f g i =
+        f i >>= fun b ->
+        let i, c = g b in
+        seqx f g i >>= fun (i, cs) ->
+        ret (i, c, cs)
+    in
+    enter
+
 let rec alt ps s =
     match ps with
     | [] -> None

File cf/cf_llscan.mli

 *)
 val seq1: ('s, 'r) t -> ('s, 'r * 'r list) t
 
+(** The indexed list scanner composer.  Use [seqx inp unp i] to compose a
+    scanner that recognizes and returns an unbounded list of the phrases that
+    would be recognized by folding [i] alternately through [inp] and [unp].
+*)
+val seqx: ('a -> ('s, 'b) t) -> ('b -> 'a * 'c) -> 'a -> ('s, 'a * 'c list) t
+
+(** The non-empty indexed list scanner composer.  Use [seqx1 inp unp i] to
+    compose a scanner that recognizes and returns a non-empty unbounded list of
+    the phrases that would be recognized by folding [i] alternately through
+    [inp] and [unp].
+*)
+val seqx1:
+    ('a -> ('s, 'b) t) -> ('b -> 'a * 'c) -> 'a -> ('s, 'a * 'c * 'c list) t
+
 (** Use [alt ps] to create a scanner that produces the output from the first
     scanner in the list [ps] that recognizes a pattern in the input.  If no
     scanner in the list recognizes a pattern, then the scanner constructed by