// Generated by re2zig
// re2zig $INPUT -o $OUTPUT --loop-switch --computed-continue --no-generation-date --no-version

const std = @import("std");



fn lex_simple(yyinput: [:0]const u8) i32 {
    var yycursor: usize = 0;
    var yymarker: usize = 0;
    const yylimit: usize = yyinput.len;

    
    var yych: u8 = 0;
    yystate: switch (@as(enum {
        yy0,
        yy1,
        yy2,
        yy3,
        yy4,
        yy5,
        yy6,
        yy7,
        yy8,
        yy9,
        yy10,
    }, .yy0)) {
        .yy0 => {
            if (yylimit <= yycursor) {
                continue :yystate .yy8;
            }
            yych = yyinput[yycursor];
            yycursor += 1;
            switch (yych) {
                0x61 => {
                    continue :yystate .yy3;
                },
                0x62 => {
                    continue :yystate .yy4;
                },
                0x63 => {
                    continue :yystate .yy5;
                },
                else => {
                    continue :yystate .yy1;
                },
            }
        },
        .yy1 => {
            continue :yystate .yy2;
        },
        .yy2 => {
            return 1;
        },
        .yy3 => {
            if (yylimit <= yycursor) {
                continue :yystate .yy9;
            }
            return 3;
        },
        .yy4 => {
            return 4;
        },
        .yy5 => {
            yymarker = yycursor;
            if (yylimit <= yycursor) {
                continue :yystate .yy10;
            }
            yych = yyinput[yycursor];
            switch (yych) {
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy6;
                },
                else => {
                    continue :yystate .yy2;
                },
            }
        },
        .yy6 => {
            if (yylimit <= yycursor) {
                continue :yystate .yy10;
            }
            yych = yyinput[yycursor];
            switch (yych) {
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy6;
                },
                else => {
                    continue :yystate .yy7;
                },
            }
        },
        .yy7 => {
            yycursor = yymarker;
            continue :yystate .yy2;
        },
        .yy8 => {
            return 0;
        },
        .yy9 => {
            return 2;
        },
        .yy10 => {
            return 5;
        },
    }

}

fn lex_eof(yyinput: [:0]const u8) i32 {
    var yycursor: usize = 0;
    var yymarker: usize = 0;
    const yylimit: usize = yyinput.len;

    
    var yych: u8 = 0;
    yystate: switch (@as(enum {
        yy0,
        yy1,
        yy2,
        yy3,
        yy4,
        yy5,
        yy6,
        yy7,
        yy8,
        yy9,
        yy10,
    }, .yy0)) {
        .yy0 => {
            yych = yyinput[yycursor];
            switch (yych) {
                0x61 => {
                    yycursor += 1;
                    continue :yystate .yy3;
                },
                0x62 => {
                    yycursor += 1;
                    continue :yystate .yy4;
                },
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy5;
                },
                else => {
                    if (yylimit <= yycursor) {
                        if (false) {
                            continue :yystate .yy0;
                        }
                        continue :yystate .yy8;
                    }
                    yycursor += 1;
                    continue :yystate .yy1;
                },
            }
        },
        .yy1 => {
            continue :yystate .yy2;
        },
        .yy2 => {
            return 1;
        },
        .yy3 => {
            if (yycursor == yylimit) {
                continue :yystate .yy9;
            }
            return 3;
        },
        .yy4 => {
            return 4;
        },
        .yy5 => {
            yymarker = yycursor;
            yych = yyinput[yycursor];
            switch (yych) {
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy6;
                },
                else => {
                    if (yylimit <= yycursor) {
                        if (false) {
                            continue :yystate .yy5;
                        }
                        continue :yystate .yy10;
                    }
                    continue :yystate .yy2;
                },
            }
        },
        .yy6 => {
            yych = yyinput[yycursor];
            switch (yych) {
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy6;
                },
                else => {
                    if (yylimit <= yycursor) {
                        if (false) {
                            continue :yystate .yy6;
                        }
                        continue :yystate .yy10;
                    }
                    continue :yystate .yy7;
                },
            }
        },
        .yy7 => {
            yycursor = yymarker;
            continue :yystate .yy2;
        },
        .yy8 => {
            return 0;
        },
        .yy9 => {
            return 2;
        },
        .yy10 => {
            return 5;
        },
    }

}

const yymaxfill = 2;


fn lex_scc(str: [:0]const u8) !i32 {
    var yycursor: usize = 0;
    var yymarker: usize = 0;
    const end: usize = str.len;
    const yylimit: usize = end + yymaxfill;

    var yyinput = try std.testing.allocator.alloc(u8, yylimit);
    defer std.testing.allocator.free(yyinput);
    std.mem.copyForwards(u8, yyinput[0..], str);
    std.mem.copyForwards(u8, yyinput[end..], &[_]u8{0} ** yymaxfill);

    
    var yych: u8 = 0;
    yystate: switch (@as(enum {
        yy0,
        yy1,
        yy2,
        yy3,
        yy4,
        yy5,
        yy6,
        yy7,
        yy8,
        yy9,
        yy10,
    }, .yy0)) {
        .yy0 => {
            if (yycursor == end) {
                continue :yystate .yy8;
            }
            if ((yylimit - yycursor) < 2) { return -1; }
            yych = yyinput[yycursor];
            yycursor += 1;
            switch (yych) {
                0x61 => {
                    continue :yystate .yy3;
                },
                0x62 => {
                    continue :yystate .yy4;
                },
                0x63 => {
                    continue :yystate .yy5;
                },
                else => {
                    continue :yystate .yy1;
                },
            }
        },
        .yy1 => {
            continue :yystate .yy2;
        },
        .yy2 => {
            return 1;
        },
        .yy3 => {
            if (yycursor == end) {
                continue :yystate .yy9;
            }
            return 3;
        },
        .yy4 => {
            return 4;
        },
        .yy5 => {
            yymarker = yycursor;
            if (yycursor == end) {
                continue :yystate .yy10;
            }
            yych = yyinput[yycursor];
            switch (yych) {
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy6;
                },
                else => {
                    continue :yystate .yy2;
                },
            }
        },
        .yy6 => {
            if (yycursor == end) {
                continue :yystate .yy10;
            }
            if (yylimit <= yycursor) { return -1; }
            yych = yyinput[yycursor];
            switch (yych) {
                0x63 => {
                    yycursor += 1;
                    continue :yystate .yy6;
                },
                else => {
                    continue :yystate .yy7;
                },
            }
        },
        .yy7 => {
            yycursor = yymarker;
            continue :yystate .yy2;
        },
        .yy8 => {
            return 0;
        },
        .yy9 => {
            return 2;
        },
        .yy10 => {
            return 5;
        },
    }

}

test "computed-continue fill and EOF transitions" {
    const Case = struct { input: [:0]const u8, expected: i32 };
    const cases = [_]Case{
        .{ .input = "", .expected = 0 },
        .{ .input = "a", .expected = 2 },
        .{ .input = "ax", .expected = 3 },
        .{ .input = "b", .expected = 4 },
        .{ .input = "bx", .expected = 4 },
        .{ .input = "ccc", .expected = 5 },
    };

    for (cases) |case| {
        try std.testing.expectEqual(case.expected, lex_simple(case.input));
        try std.testing.expectEqual(case.expected, lex_eof(case.input));
        try std.testing.expectEqual(case.expected, try lex_scc(case.input));
    }
}
