// Generated by re2js
// re2js $INPUT -o $OUTPUT

const assert = require('assert');
const fs = require('fs')

const BUFSIZE = 4096
const OK = 0
const EOF = 1
const LONG_LEXEME = 2

function fill(st) {
    if (st.eof) return EOF

    // Error: lexeme too long. In real life could reallocate a larger buffer.
    if (st.token < 1) return LONG_LEXEME

    // Shift buffer contents (discard everything up to the current token).
    st.yyinput.copy(st.yyinput, 0, st.token, st.yylimit)
    st.yycursor -= st.token;
    st.yymarker -= st.token;
    st.yylimit -= st.token;
    if (st.yyt1 != -1) st.yyt1 -= st.token
if (st.yyt2 != -1) st.yyt2 -= st.token
if (st.yyt3 != -1) st.yyt3 -= st.token

    st.token = 0;

    // Read a new chunk of data from file and append it to `yyinput`.
    let want = BUFSIZE - st.yylimit - 1 // -1 for sentinel
    let nread = fs.readSync(st.file, st.yyinput, st.yylimit, want)
    st.eof = nread < want // end of file?
    st.yylimit += nread
    st.yyinput.writeUInt8(0, st.yylimit) // sentinel

    return OK
}

function lex(st) {
    let vers = []
    loop: while (true) {
        st.token = st.yycursor

        // Final tag variables available in semantic action.
        let t1
let t2
let t3
let t4


        
{
    let yych = 0
    let yystate = 0
    yyl: while (true) {
        switch (yystate) {
            case 0:
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yycursor += 1;
                        yystate = 3
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 0
                                continue yyl
                            }
                            yystate = 11
                            continue yyl
                        }
                        st.yycursor += 1;
                        yystate = 1
                        continue yyl
                }
            case 1:
                yystate = 2
                continue yyl
            case 2:
                { return null }
            case 3:
                st.yymarker = st.yycursor;
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x2E:
                        st.yycursor += 1;
                        yystate = 4
                        continue yyl
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yycursor += 1;
                        yystate = 6
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 3
                                continue yyl
                            }
                        }
                        yystate = 2
                        continue yyl
                }
            case 4:
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yyt1 = st.yycursor;
                        st.yycursor += 1;
                        yystate = 7
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 4
                                continue yyl
                            }
                        }
                        yystate = 5
                        continue yyl
                }
            case 5:
                st.yycursor = st.yymarker;
                yystate = 2
                continue yyl
            case 6:
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x2E:
                        st.yycursor += 1;
                        yystate = 4
                        continue yyl
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yycursor += 1;
                        yystate = 6
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 6
                                continue yyl
                            }
                        }
                        yystate = 5
                        continue yyl
                }
            case 7:
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x0A:
                        st.yyt2 = st.yycursor;
                        st.yyt3 = -1;
                        st.yycursor += 1;
                        yystate = 8
                        continue yyl
                    case 0x2E:
                        st.yyt2 = st.yycursor;
                        st.yycursor += 1;
                        yystate = 9
                        continue yyl
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yycursor += 1;
                        yystate = 7
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 7
                                continue yyl
                            }
                        }
                        yystate = 5
                        continue yyl
                }
            case 8:
                t2 = st.yyt1;
                t3 = st.yyt2;
                t4 = st.yyt3;
                t1 = st.yyt1;
                t1 -= 1;
                {
                vers.push({
                    major: Number(st.yyinput.subarray(st.token, t1)),
                    minor: Number(st.yyinput.subarray(t2, t3)),
                    patch: t4 == -1 ? 0 : Number(st.yyinput.subarray(t4, st.yycursor - 1))
                })
                continue loop
            }
            case 9:
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yyt3 = st.yycursor;
                        st.yycursor += 1;
                        yystate = 10
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 9
                                continue yyl
                            }
                        }
                        yystate = 5
                        continue yyl
                }
            case 10:
                yych = st.yyinput.readUInt8(st.yycursor)
                switch (yych) {
                    case 0x0A:
                        st.yycursor += 1;
                        yystate = 8
                        continue yyl
                    case 0x30:
                    case 0x31:
                    case 0x32:
                    case 0x33:
                    case 0x34:
                    case 0x35:
                    case 0x36:
                    case 0x37:
                    case 0x38:
                    case 0x39:
                        st.yycursor += 1;
                        yystate = 10
                        continue yyl
                    default:
                        if (st.yylimit <= st.yycursor) {
                            if (fill(st) == OK) {
                                yystate = 10
                                continue yyl
                            }
                        }
                        yystate = 5
                        continue yyl
                }
            case 11:
                { return vers }
            default:
                throw "internal lexer error"
        }
    }
}

    }
}

function main() {
    let fname = "input"

    // Create input file.
    let content = "1.22.333\n".repeat(BUFSIZE)
    fs.writeFileSync(fname, content, function(err) { if (err) throw err; })

    // Init lexer state.
    let limit = BUFSIZE - 1 // exclude terminating null
    let st = {
        file: fs.openSync(fname, 'r'),
        yyinput: Buffer.alloc(BUFSIZE),
        yylimit: limit,
        yycursor: limit,
        yymarker: limit,
        token: limit,
        // Intermediate tag variables used by the lexer (must be autogenerated).
        yyt1: -1,
yyt2: -1,
yyt3: -1,

        eof: false
    }

    // Run lexer on the prepared file.
    assert.deepEqual(lex(st), Array(BUFSIZE).fill({major: 1, minor: 22, patch: 333}))

    // Cleanup.
    fs.unlink(fname, function(err){ if (err) throw err; })
}

main()
