Commits

camlspotter committed 0cda396

longest match

Comments (0)

Files changed (4)

   val mark : mark t
   val string_from_mark : mark -> string t
   val substr : 'a t -> string t
+  val (</>) : 'a t -> 'a t -> 'a t
+    (** longest match *)
 end = struct
   include Planck.String(Sbuffer)
 
     mark >>= fun mark ->
     t >>= fun _ ->
     string_from_mark mark
+
+  (* longest match *)
+  let (</>) : 'a t -> 'a t -> 'a t = fun t1 t2 ->
+    fun st ->
+      match t1 st, t2 st with
+      | (Result.Ok _ as r), Result.Error _ -> r
+      | Result.Error _, (Result.Ok _ as r) -> r
+      | Result.Error e1, Result.Error e2 -> Result.Error (e1 ^ " or " ^ e2)
+      | (Result.Ok (_, st1) as r1), (Result.Ok (_, st2) as r2) ->
+	  if Sbuffer.bytes st1 >= Sbuffer.bytes st2 then r1 else r2
 end
 
 include P
   include Stream.S with type elem = char
                    and  type gen  = string Stream.simple_gen
   val pos : t -> Position.t
+  val bytes : t -> int
   val substr : t -> int -> int -> string
   val from_string : string -> t
 end
 
   let pos t = t.abs_pos
 
+  let bytes t = t.abs_pos.Position.byte
+
   let from_string str = create (fun () -> `Some (str, fun () -> `None))
 end
 
 include Make(M)
 let substr = M.substr
 let pos = M.pos
+let bytes = M.bytes
 let from_string = M.from_string
   val pos : t -> Position.t
     (** get the current position of the stream *)
 
+  val bytes : t -> int
+    (** get the abs byte position *)
+
   val substr : t -> int -> int -> string
     (** [substr t pos len] gets the substring of the stream from the
 	position byte [pos] with length [len] bytes *)
   assert (test Literal.nat_int "0x10" = Some 16);
   assert (test Identifier.lowercase "hello42World_\'*" = Some "hello42World_\'");
   assert (test Identifier.uppercase "Hello42World_\'*" = Some "Hello42World_\'");
+  assert (test (Literal.Num.digit </> Literal.Num.hex) "0x10" = Some { Literal.Num.base = 16; rev_nums = [0; 1] });
   prerr_endline "test done"