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
|
type t =
{ str : string
; mutable pos : int
}
exception Parse_error
let create str = { str; pos = 0 }
let unget t = t.pos <- t.pos - 1
let junk t = t.pos <- t.pos + 1
let eos t = t.pos = String.length t.str
let test t c = (not (eos t)) && t.str.[t.pos] = c
let test2 t c c' =
t.pos + 1 < String.length t.str && t.str.[t.pos] = c && t.str.[t.pos + 1] = c'
;;
let accept t c =
let r = test t c in
if r then t.pos <- t.pos + 1;
r
;;
let get t =
let r = t.str.[t.pos] in
t.pos <- t.pos + 1;
r
;;
let accept_s t s' =
let len = String.length s' in
try
for j = 0 to len - 1 do
(* CR-someday rgrinberg: stop relying on bound checks *)
try if s'.[j] <> t.str.[t.pos + j] then raise_notrace Exit with
| _ -> raise_notrace Exit
done;
t.pos <- t.pos + len;
true
with
| Exit -> false
;;
let rec integer' t i =
if eos t
then Some i
else (
match get t with
| '0' .. '9' as d ->
let i' = (10 * i) + (Char.code d - Char.code '0') in
if i' < i then raise Parse_error;
integer' t i'
| _ ->
unget t;
Some i)
;;
let integer t =
if eos t
then None
else (
match get t with
| '0' .. '9' as d -> integer' t (Char.code d - Char.code '0')
| _ ->
unget t;
None)
;;
|