(* Generated by re2ocaml *)
#1 "ocaml/submatch/03_captures.re"
(* re2ocaml $INPUT -o $OUTPUT *)

open String

type state = {
    yyinput: string;
    mutable yycursor: int;
    mutable yymarker: int;
    (* Final tag variables available in semantic action. *)
    
#14 "ocaml/submatch/03_captures.ml"

	mutable yytl0: int;
	mutable yytl1: int;
	mutable yytl2: int;
	mutable yytl3: int;
	mutable yytr0: int;
	mutable yytr1: int;
	mutable yytr2: int;
	mutable yytr3: int;
#10 "ocaml/submatch/03_captures.re"

    (* Intermediate tag variables used by the lexer (must be autogenerated). *)
    
#28 "ocaml/submatch/03_captures.ml"

	mutable yyt1: int;
	mutable yyt2: int;
	mutable yyt3: int;
	mutable yyt4: int;
	mutable yyt5: int;
#12 "ocaml/submatch/03_captures.re"

}

type semver = {
    major: int;
    minor: int;
    patch: int;
}

let s2n (str: string) (i1: int) (i2: int) : int =
    let rec f s i j n =
        if i >= j then n else f s (i + 1) j (n * 10 + Char.code s.[i] - 48)
    in f str i1 i2 0


#51 "ocaml/submatch/03_captures.ml"
let rec yy0 (st : state) : semver option =
    let yych = unsafe_get st.yyinput st.yycursor in
    match yych with
        | '0'..'9' ->
            st.yyt1 <- st.yycursor;
            st.yycursor <- st.yycursor + 1;
            (yy3 [@tailcall]) st
        | _ ->
            st.yycursor <- st.yycursor + 1;
            (yy1 [@tailcall]) st

and yy1 (st : state) : semver option =
    (yy2 [@tailcall]) st

and yy2 (st : state) : semver option =
#41 "ocaml/submatch/03_captures.re"
    None
#69 "ocaml/submatch/03_captures.ml"

and yy3 (st : state) : semver option =
    st.yymarker <- st.yycursor;
    let yych = unsafe_get st.yyinput st.yycursor in
    match yych with
        | '.' ->
            st.yycursor <- st.yycursor + 1;
            (yy4 [@tailcall]) st
        | '0'..'9' ->
            st.yycursor <- st.yycursor + 1;
            (yy6 [@tailcall]) st
        | _ -> (yy2 [@tailcall]) st

and yy4 (st : state) : semver option =
    let yych = unsafe_get st.yyinput st.yycursor in
    match yych with
        | '0'..'9' ->
            st.yyt2 <- st.yycursor;
            st.yycursor <- st.yycursor + 1;
            (yy7 [@tailcall]) st
        | _ -> (yy5 [@tailcall]) st

and yy5 (st : state) : semver option =
    st.yycursor <- st.yymarker;
    (yy2 [@tailcall]) st

and yy6 (st : state) : semver option =
    let yych = unsafe_get st.yyinput st.yycursor in
    match yych with
        | '.' ->
            st.yycursor <- st.yycursor + 1;
            (yy4 [@tailcall]) st
        | '0'..'9' ->
            st.yycursor <- st.yycursor + 1;
            (yy6 [@tailcall]) st
        | _ -> (yy5 [@tailcall]) st

and yy7 (st : state) : semver option =
    let yych = unsafe_get st.yyinput st.yycursor in
    match yych with
        | '\x00' ->
            st.yyt3 <- st.yycursor;
            st.yyt4 <- -1;
            st.yyt5 <- -1;
            st.yycursor <- st.yycursor + 1;
            (yy8 [@tailcall]) st
        | '.' ->
            st.yyt3 <- st.yycursor;
            st.yyt5 <- st.yycursor;
            st.yycursor <- st.yycursor + 1;
            (yy9 [@tailcall]) st
        | '0'..'9' ->
            st.yycursor <- st.yycursor + 1;
            (yy7 [@tailcall]) st
        | _ -> (yy5 [@tailcall]) st

and yy8 (st : state) : semver option =
    st.yytl1 <- st.yyt1;
    st.yytl2 <- st.yyt2;
    st.yytr2 <- st.yyt3;
    st.yytl3 <- st.yyt5;
    st.yytr3 <- st.yyt4;
    st.yytl0 <- st.yyt1;
    st.yytr0 <- st.yycursor;
    st.yytr1 <- st.yyt2;
    st.yytr1 <- st.yytr1 - 1;
#34 "ocaml/submatch/03_captures.re"
    
        Some {
            major = s2n st.yyinput st.yytl1 st.yytr1;
            minor = s2n st.yyinput st.yytl2 st.yytr2;
            patch = if st.yytl3 = -1 then 0 else s2n st.yyinput (st.yytl3 + 1) st.yytr3
        }

#144 "ocaml/submatch/03_captures.ml"

and yy9 (st : state) : semver option =
    let yych = unsafe_get st.yyinput st.yycursor in
    if (yych <= '\x00') then (yy5 [@tailcall]) st
    else (yy11 [@tailcall]) st yych

and yy10 (st : state) : semver option =
    let yych = unsafe_get st.yyinput st.yycursor in
    (yy11 [@tailcall]) st yych

and yy11 (st : state) (yych : char) : semver option =
    match yych with
        | '\x00' ->
            st.yyt4 <- st.yycursor;
            st.yycursor <- st.yycursor + 1;
            (yy8 [@tailcall]) st
        | '0'..'9' ->
            st.yycursor <- st.yycursor + 1;
            (yy10 [@tailcall]) st
        | _ -> (yy5 [@tailcall]) st

and parse (st : state) : semver option =
    (yy0 [@tailcall]) st

#42 "ocaml/submatch/03_captures.re"


let test (str: string) (result: semver option) =
    let st = {
        yyinput = str;
        yycursor = 0;
        yymarker = 0;
        
#178 "ocaml/submatch/03_captures.ml"

		yytl0 = -1;
		yytl1 = -1;
		yytl2 = -1;
		yytl3 = -1;
		yytr0 = -1;
		yytr1 = -1;
		yytr2 = -1;
		yytr3 = -1;
#49 "ocaml/submatch/03_captures.re"

        
#191 "ocaml/submatch/03_captures.ml"

		yyt1 = -1;
		yyt2 = -1;
		yyt3 = -1;
		yyt4 = -1;
		yyt5 = -1;
#50 "ocaml/submatch/03_captures.re"

    }
    in if not (parse st = result) then raise (Failure "error")

let main () =
    test "23.34" (Some {major = 23; minor = 34; patch = 0});
    test "1.2.99999" (Some {major = 1; minor = 2; patch = 99999});
    test "1.a" None

let _ = main ()
