(* Generated by re2ocaml *)
#1 "ocaml/eof/04_fake_sentinel.re"
(* re2ocaml $INPUT -o $OUTPUT *)

type state = {
    str: string;
    mutable cur: int;
    lim: int;
}

(* expect a string without terminating null *)

#14 "ocaml/eof/04_fake_sentinel.ml"
let rec yy0 (st : state) (count : int) : int =
    let yych = if st.cur < st.lim then st.str.[st.cur] else '\x00' in
    st.cur <- st.cur + 1;
    match yych with
        | '\x00' -> (yy1 [@tailcall]) st count
        | ' ' -> (yy3 [@tailcall]) st count
        | 'a'..'z' -> (yy5 [@tailcall]) st count
        | _ -> (yy2 [@tailcall]) st count

and yy1 (st : state) (count : int) : int =
#18 "ocaml/eof/04_fake_sentinel.re"
    count
#27 "ocaml/eof/04_fake_sentinel.ml"

and yy2 (st : state) (count : int) : int =
#17 "ocaml/eof/04_fake_sentinel.re"
    -1
#32 "ocaml/eof/04_fake_sentinel.ml"

and yy3 (st : state) (count : int) : int =
    let yych = if st.cur < st.lim then st.str.[st.cur] else '\x00' in
    match yych with
        | ' ' ->
            st.cur <- st.cur + 1;
            (yy3 [@tailcall]) st count
        | _ -> (yy4 [@tailcall]) st count

and yy4 (st : state) (count : int) : int =
#20 "ocaml/eof/04_fake_sentinel.re"
    lex st count
#45 "ocaml/eof/04_fake_sentinel.ml"

and yy5 (st : state) (count : int) : int =
    let yych = if st.cur < st.lim then st.str.[st.cur] else '\x00' in
    match yych with
        | 'a'..'z' ->
            st.cur <- st.cur + 1;
            (yy5 [@tailcall]) st count
        | _ -> (yy6 [@tailcall]) st count

and yy6 (st : state) (count : int) : int =
#19 "ocaml/eof/04_fake_sentinel.re"
    lex st (count + 1)
#58 "ocaml/eof/04_fake_sentinel.ml"

and lex (st : state) (count : int) : int =
    (yy0 [@tailcall]) st count

#21 "ocaml/eof/04_fake_sentinel.re"


let test(str, count) =
    let st = {str = str; cur = 0; lim = String.length str}
    in if not (lex st 0 = count) then raise (Failure "error")

let main () =
    test("", 0);
    test("one two three", 3);
    test("f0ur", -1)

let _ = main ()
