let repeat_l n f stream =
repeat (Int32.to_int n) f stream
-let string str stream =
- let cs =
- ExtString.String.explode str in
- let n =
- List.length cs in
- match Stream.npeek n stream with
- ys when cs = ys ->
- times (fun ()->Stream.junk stream) n;
- ys
- | _ ->
- fail ()
-
-let char c stream =
- match Stream.peek stream with
- Some x when x = c ->
- Stream.junk stream;
- x
- | _ ->
- fail ()
-
let rec until c stream =
match Stream.peek stream with
Some x when x != c ->
| _ ->
[]
-let one_of str stream =
- match Stream.peek stream with
- Some c when String.contains str c ->
- Stream.next stream
- | _ ->
- fail ()
-
let option f stream =
try
Some (f stream)
parse stream in
x::many parse stream
-let alpha stream =
- match Stream.peek stream with
- Some ('a'..'z') | Some ('A'..'Z') ->
- Stream.next stream
- | _ ->
- fail ()
-
-let digit stream =
+let char c stream =
match Stream.peek stream with
- Some ('0'..'9') ->
+ Some x when x = c ->
Stream.next stream
| _ ->
fail ()
Obj.set_field t 1 data;
fail ()
-module N = Node
-module Node = struct
- let string str stream =
- let n =
- String.length str in
- let xs =
- ExtString.String.implode @@
- List.map N.value @@
- Stream.npeek n stream in
- if xs = str then
- (times (fun ()->Stream.junk stream) n;
- xs)
- else
- fail ()
+module type STREAM = sig
+ type t
+ type s
+
+ val npeek : int -> t Stream.t -> char list
+ val peek : t Stream.t -> char option
+ val junk : t Stream.t -> unit
+ val next : t Stream.t -> t
+ val shrink : t list -> s
+end
+
+module Parser(S : STREAM) = struct
+ let string str stream =
+ let cs =
+ ExtString.String.explode str in
+ let n =
+ List.length cs in
+ match S.npeek n stream with
+ ys when cs = ys ->
+ S.shrink @@ repeat n S.next stream
+ | _ ->
+ fail ()
+
+ let one_of str stream =
+ match S.peek stream with
+ Some c when String.contains str c ->
+ S.next stream
+ | _ ->
+ fail ()
+
+ let alpha stream =
+ match S.peek stream with
+ Some ('a'..'z') | Some ('A'..'Z') ->
+ S.next stream
+ | _ ->
+ fail ()
+
+ let digit stream =
+ match S.peek stream with
+ Some ('0'..'9') ->
+ S.next stream
+ | _ ->
+ fail ()
end
+
+module Char = Parser(
+ struct
+ type t = char
+ type s = char list
+ let npeek = Stream.npeek
+ let peek = Stream.peek
+ let junk = Stream.junk
+ let next = Stream.next
+ let shrink = id
+ end)
+
+module N = Node
+module Node = Parser(
+ struct
+ type t = char N.t
+ type s = char list N.t
+
+ let npeek n stream =
+ List.map N.value @@ Stream.npeek n stream
+
+ let peek stream =
+ sure N.value @@ Stream.peek stream
+ let junk =
+ Stream.junk
+ let next =
+ Stream.next
+
+ let shrink =
+ function
+ (x::_) as xs ->
+ {x with N.value = List.map N.value xs}
+ | [] ->
+ fail ()
+ end)
+
+(* obsolute *)
+let string =
+ Char.string
+
+let one_of =
+ Char.one_of
+
+let alpha =
+ Char.alpha
+
+let digit =
+ Char.digit
+
+
+
+
val many : ('a Stream.t -> 'b) -> 'a Stream.t -> 'b list
val many1 : ('a Stream.t -> 'b) -> 'a Stream.t -> 'b list
val until : 'a -> 'a Stream.t -> 'a list
+val char : 'a -> 'a Stream.t -> 'a
val string : string -> char Stream.t -> char list
-val char : 'a -> 'a Stream.t -> 'a
val one_of : string -> char Stream.t -> char
val alpha : char Stream.t -> char
val digit : char Stream.t -> char