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

const std = @import("std");



fn lex_tags(str: [:0]const u8) isize {
    var cur: isize = 0;
    var mar: isize = 0;
    var yyt1: isize = -1;

    var x: isize = 0;
    var y: isize = 0;

    
    var yych: u8 = 0;
    yystate: switch (@as(enum {
        yy0,
        yy1,
        yy2,
        yy3,
        yy4,
    }, .yy0)) {
        .yy0 => {
            mar = cur;
            yych = str[@intCast(cur)];
            switch (yych) {
                0x62 => {
                    cur += 1;
                    continue :yystate .yy2;
                },
                else => {
                    yyt1 = -1;
                    continue :yystate .yy1;
                },
            }
        },
        .yy1 => {
            y = yyt1;
            x = yyt1;
            yyt1 = -1;
            if (x != yyt1) x += -1;
            return if (x == -1) -1 else y - x;
        },
        .yy2 => {
            yych = str[@intCast(cur)];
            switch (yych) {
                0x61 => {
                    cur += 1;
                    continue :yystate .yy4;
                },
                else => {
                    continue :yystate .yy3;
                },
            }
        },
        .yy3 => {
            cur = mar;
            yyt1 = -1;
            continue :yystate .yy1;
        },
        .yy4 => {
            yyt1 = cur;
            continue :yystate .yy1;
        },
    }

}

const yymaxnmatch = 3;


fn lex_captures(str: [:0]const u8) isize {
    var cur: isize = 0;
    var yyt1: isize = -1;
var yyt2: isize = -1;

    var yypmatch: [yymaxnmatch * 2]isize = undefined;
    var yynmatch: usize = 0;

    
    var yych: u8 = 0;
    yystate: switch (@as(enum {
        yy0,
        yy1,
        yy2,
    }, .yy0)) {
        .yy0 => {
            yych = str[@intCast(cur)];
            switch (yych) {
                0x61 => {
                    yyt1 = cur;
                    cur += 1;
                    continue :yystate .yy2;
                },
                else => {
                    yyt1 = cur;
                    yyt2 = -1;
                    continue :yystate .yy1;
                },
            }
        },
        .yy1 => {
            yynmatch = 3;
            yypmatch[0] = yyt1;
            yypmatch[3] = yyt2;
            yypmatch[5] = yyt2;
            yypmatch[1] = cur;
            yypmatch[2] = yyt2;
            yyt2 = -1;
            if (yypmatch[2] != yyt2) yypmatch[2] += -1;
            yypmatch[4] = yypmatch[2];
            
            std.debug.assert(yynmatch == 3);
            return yypmatch[4];

        },
        .yy2 => {
            yyt2 = cur;
            continue :yystate .yy1;
        },
    }

}

test "computed-continue tags and captures" {
    const Case = struct { input: [:0]const u8, tag: isize, capture: isize };
    const cases = [_]Case{
        .{ .input = "", .tag = -1, .capture = -1 },
        .{ .input = "a", .tag = -1, .capture = 0 },
        .{ .input = "ba", .tag = 1, .capture = -1 },
    };

    for (cases) |case| {
        try std.testing.expectEqual(case.tag, lex_tags(case.input));
        try std.testing.expectEqual(case.capture, lex_captures(case.input));
    }
}
