// Code generated by re2v, DO NOT EDIT.
//line "v/submatch/01_stags.re":1
// re2v $INPUT -o $OUTPUT

struct SemVer {
    major int
    minor int
    patch int
}

fn s2n(s string) int { // convert pre-parsed string to number
    mut n := 0
    for c in s { n = n * 10 + int(c - 48) }
    return n
}

fn parse(yyinput string) ?SemVer {
    mut yycursor, mut yymarker := 0, 0

    // Final tag variables available in semantic action.
    
//line "v/submatch/01_stags.v":23
mut t1 := 0
mut t2 := 0
mut t3 := 0
mut t4 := 0
mut t5 := 0
//line "v/submatch/01_stags.re":19


    // Intermediate tag variables used by the lexer (must be autogenerated).
    
//line "v/submatch/01_stags.v":34
mut yyt1 := -1
mut yyt2 := -1
mut yyt3 := -1
mut yyt4 := -1
//line "v/submatch/01_stags.re":22


    
//line "v/submatch/01_stags.v":43
    mut yych := u8(0)
    yych = yyinput[yycursor]
    match yych {
        0x30...0x39 {
            yyt1 = yycursor
            unsafe { goto yy3 }
        }
        else { unsafe { goto yy1 } }
    }
yy1:
    yycursor += 1
yy2:
//line "v/submatch/01_stags.re":37
    return none
//line "v/submatch/01_stags.v":58
yy3:
    yycursor += 1
    yymarker = yycursor
    yych = yyinput[yycursor]
    match yych {
        0x2E { unsafe { goto yy4 } }
        0x30...0x39 { unsafe { goto yy6 } }
        else { unsafe { goto yy2 } }
    }
yy4:
    yycursor += 1
    yych = yyinput[yycursor]
    match yych {
        0x30...0x39 {
            yyt2 = yycursor
            unsafe { goto yy7 }
        }
        else { unsafe { goto yy5 } }
    }
yy5:
    yycursor = yymarker
    unsafe { goto yy2 }
yy6:
    yycursor += 1
    yych = yyinput[yycursor]
    match yych {
        0x2E { unsafe { goto yy4 } }
        0x30...0x39 { unsafe { goto yy6 } }
        else { unsafe { goto yy5 } }
    }
yy7:
    yycursor += 1
    yych = yyinput[yycursor]
    match yych {
        0x00 {
            yyt3 = yycursor
            yyt4 = -1
            unsafe { goto yy8 }
        }
        0x2E {
            yyt3 = yycursor
            unsafe { goto yy9 }
        }
        0x30...0x39 { unsafe { goto yy7 } }
        else { unsafe { goto yy5 } }
    }
yy8:
    yycursor += 1
    t1 = yyt1
    t3 = yyt2
    t4 = yyt3
    t5 = yyt4
    t2 = yyt2
    t2-= 1
//line "v/submatch/01_stags.re":30
    
            return SemVer{
                major: s2n(yyinput[t1..t2]),
                minor: s2n(yyinput[t3..t4]),
                patch: if t5 == -1 { 0 } else { s2n(yyinput[t5..yycursor - 1]) }
            }

//line "v/submatch/01_stags.v":121
yy9:
    yycursor += 1
    yych = yyinput[yycursor]
    match yych {
        0x30...0x39 {
            yyt4 = yycursor
            unsafe { goto yy10 }
        }
        else { unsafe { goto yy5 } }
    }
yy10:
    yycursor += 1
    yych = yyinput[yycursor]
    match yych {
        0x00 { unsafe { goto yy8 } }
        0x30...0x39 { unsafe { goto yy10 } }
        else { unsafe { goto yy5 } }
    }
//line "v/submatch/01_stags.re":38

}

fn main() {
    test := fn (result ?SemVer, expect ?SemVer) {
        if r := result {
            if e := expect { if r != e { panic("expected $e, got $r") } }
        } else {
            if _ := result { panic("expected none") }
        }
    }
    test(parse("23.34\0"), SemVer{23, 34, 0})
    test(parse("1.2.9999\0"), SemVer{1, 2, 9999})
    test(parse("1.a\0"), none)
}
