/* Generated by re2c */
#include "re2c/base.h"

namespace re2c_submatch_33__rep_alt_5_3_2 {



static const char *print(long& count, const char *tok, const taglist_t *t) {
    if (!t) return tok;

    const char *s = print(count, tok, t->pred);
    const char *e = tok + t->dist;
    OUTS(s, e);
    OUTC('.');
    return e;
}



#define YYMAXFILL 2


struct input_t {
    FILE* file;
    char *buf;
    char *lim;
    char *cur;
    char *mar;
    char *tok;
    
    taglist_t *yytm1;
taglist_t *yytm2;
taglist_t *yytm3;

    taglistpool_t tlp;
    int eof;
};

static inline void free_input(input_t *in) {
    free(in->buf);
    taglistpool_free(&in->tlp);
    if (in->file) fclose(in->file);
}

static inline int fill_buffered_eof(input_t *in) {
    size_t free;
    if (in->eof) return 1;

    free = in->tok - in->buf;
    assert(free > 0);

    memmove(in->buf, in->tok, in->lim - in->tok);
    in->lim -= free;
    in->cur -= free;
    in->mar -= free;
    in->tok -= free;
    

    in->lim += fread(in->lim, 1, free, in->file);
    in->lim[0] = 0;

    if (in->lim < in->buf + SIZE) {
        in->eof = 1;
    }

    return 0;
}

static inline int fill_buffered_scc(input_t *in, size_t need) {
    size_t free;
    if (in->eof) return 1;

    free = in->tok - in->buf;
    assert(free >= need);

    memmove(in->buf, in->tok, in->lim - in->tok);
    in->lim -= free;
    in->cur -= free;
    in->mar -= free;
    in->tok -= free;
    

    in->lim += fread(in->lim, 1, free, in->file);

    if (in->lim < in->buf + SIZE) {
        in->eof = 1;
        memset(in->lim, 0, YYMAXFILL);
        in->lim += YYMAXFILL;
    }

    return 0;
}

static inline void init_input_simple(input_t *in, const char* fname) {
    FILE* f = fopen(fname, "rb");

    fseek(f, 0, SEEK_END);
    size_t flen = (size_t) ftell(f);
    fseek(f, 0, SEEK_SET);

    in->file = nullptr; // unused
    in->buf = (char*) malloc(flen + 1);
    in->lim = nullptr; // unused
    in->cur = in->mar = in->tok = in->buf;
    
    in->yytm1 = 0;
in->yytm2 = 0;
in->yytm3 = 0;

    taglistpool_init(&in->tlp);
    in->eof = 0; // unused

    fread(in->buf, 1, flen, f);
    in->buf[flen] = 0;

    fclose(f);
}

static inline void init_input_buffered_eof(input_t *in, const char* fname) {
    in->file = fopen(fname, "rb");
    in->buf = (char*) malloc(SIZE + 1);
    in->lim = in->buf + SIZE;
    in->cur = in->lim;
    in->mar = in->lim;
    in->tok = in->lim;
    
    in->yytm1 = 0;
in->yytm2 = 0;
in->yytm3 = 0;

    taglistpool_init(&in->tlp);
    in->eof = 0;
    fill_buffered_eof(in);
}

static inline void init_input_buffered_scc(input_t *in, const char* fname) {
    in->file = fopen(fname, "rb");
    in->buf = (char*) malloc(SIZE + YYMAXFILL);
    in->lim = in->buf + SIZE;
    in->cur = in->lim;
    in->mar = in->lim;
    in->tok = in->lim;
    
    in->yytm1 = 0;
in->yytm2 = 0;
in->yytm3 = 0;

    taglistpool_init(&in->tlp);
    in->eof = 0;
}

#define YYCURSOR cur
#define YYMARKER mar
#define YYTOKEN tok
#define TLP_CLEAR() do { \
    in->tlp.next = in->tlp.head; \
    yytm1 = 0;yytm2 = 0;yytm3 = 0; \
} while (0)

int lex_simple(input_t *in) {
    char *cur = in->buf, *mar, *tok;
    (void) mar; // maybe unused
    (void) tok; // maybe unused
    
    taglist_t *yytm1 = nullptr;
taglist_t *yytm2 = nullptr;
taglist_t *yytm3 = nullptr;

    
    taglist_t* t;
    long count = 0;
loop:
    tok = cur;
    
{
	char yych;
	yych = *YYCURSOR;
	switch (yych) {
		case 0x00: goto yy1;
		case '\n':
			taglist(&yytm1, YYTOKEN, YYTOKEN - 1, &in->tlp);
			goto yy4;
		case 'a': goto yy5;
		default: goto yy2;
	}
yy1:
	++YYCURSOR;
	{ return count; }
yy2:
	++YYCURSOR;
yy3:
	{ return -1; }
yy4:
	++YYCURSOR;
	t = yytm1;
	{
        print(count, YYTOKEN, t);
        OUTC('\n');
        TLP_CLEAR();
        goto loop;
    }
yy5:
	yych = *(YYMARKER = ++YYCURSOR);
	switch (yych) {
		case 'a': goto yy6;
		default: goto yy3;
	}
yy6:
	yych = *++YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy4;
		case 'a':
			yytm2 = yytm1;
			taglist(&yytm2, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy8;
		default: goto yy7;
	}
yy7:
	YYCURSOR = YYMARKER;
	goto yy3;
yy8:
	yych = *++YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy4;
		case 'a':
			yytm3 = yytm1;
			taglist(&yytm3, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy9;
		default: goto yy7;
	}
yy9:
	yych = *++YYCURSOR;
	switch (yych) {
		case '\n':
			yytm1 = yytm2;
			taglist(&yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy4;
		case 'a': goto yy10;
		default: goto yy7;
	}
yy10:
	yych = *++YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy4;
		case 'a':
			taglist(&yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy11;
		default: goto yy7;
	}
yy11:
	yych = *++YYCURSOR;
	switch (yych) {
		case '\n':
			yytm1 = yytm3;
			taglist(&yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy4;
		case 'a': goto yy6;
		default: goto yy7;
	}
}

}

#undef YYCURSOR
#undef YYMARKER
#undef YYTOKEN
#undef TLP_CLEAR

#define YYCURSOR in->cur
#define YYMARKER in->mar
#define YYLIMIT in->lim
#define YYTOKEN in->tok
#define TLP_CLEAR() do { \
    in->tlp.next = in->tlp.head; \
    in->yytm1 = 0;in->yytm2 = 0;in->yytm3 = 0; \
} while (0)

int lex_buffered_eof(input_t *in) {
    
    taglist_t* t;
    long count = 0;
loop:
    in->tok = in->cur;
    
{
	char yych;
yyFillLabel0:
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYTOKEN - 1, &in->tlp);
			goto yy15;
		case 'a': goto yy16;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel0;
				goto yy23;
			}
			goto yy13;
	}
yy13:
	++YYCURSOR;
yy14:
	{ return -1; }
yy15:
	++YYCURSOR;
	t = in->yytm1;
	{
        print(count, YYTOKEN, t);
        OUTC('\n');
        TLP_CLEAR();
        goto loop;
    }
yy16:
	YYMARKER = ++YYCURSOR;
yyFillLabel1:
	yych = *YYCURSOR;
	switch (yych) {
		case 'a': goto yy17;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel1;
			}
			goto yy14;
	}
yy17:
	++YYCURSOR;
yyFillLabel2:
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy15;
		case 'a':
			in->yytm2 = in->yytm1;
			taglist(&in->yytm2, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy19;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel2;
			}
			goto yy18;
	}
yy18:
	YYCURSOR = YYMARKER;
	goto yy14;
yy19:
	++YYCURSOR;
yyFillLabel3:
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy15;
		case 'a':
			in->yytm3 = in->yytm1;
			taglist(&in->yytm3, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy20;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel3;
			}
			goto yy18;
	}
yy20:
	++YYCURSOR;
yyFillLabel4:
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			in->yytm1 = in->yytm2;
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy15;
		case 'a': goto yy21;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel4;
			}
			goto yy18;
	}
yy21:
	++YYCURSOR;
yyFillLabel5:
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy15;
		case 'a':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy22;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel5;
			}
			goto yy18;
	}
yy22:
	++YYCURSOR;
yyFillLabel6:
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			in->yytm1 = in->yytm3;
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy15;
		case 'a': goto yy17;
		default:
			if (YYLIMIT <= YYCURSOR) {
				if (fill_buffered_eof(in) == 0) goto yyFillLabel6;
			}
			goto yy18;
	}
yy23:
	{ return count; }
}

}

int lex_buffered_scc(input_t *in) {
    
    taglist_t* t;
    long count = 0;
loop:
    in->tok = in->cur;
    
{
	char yych;
	if ((YYLIMIT - YYCURSOR) < 2) if (fill_buffered_scc(in, 2) != 0) return -2;
	yych = *YYCURSOR;
	switch (yych) {
		case 0x00: goto yy25;
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYTOKEN - 1, &in->tlp);
			goto yy28;
		case 'a': goto yy29;
		default: goto yy26;
	}
yy25:
	++YYCURSOR;
	{ return count; }
yy26:
	++YYCURSOR;
yy27:
	{ return -1; }
yy28:
	++YYCURSOR;
	t = in->yytm1;
	{
        print(count, YYTOKEN, t);
        OUTC('\n');
        TLP_CLEAR();
        goto loop;
    }
yy29:
	yych = *(YYMARKER = ++YYCURSOR);
	switch (yych) {
		case 'a': goto yy30;
		default: goto yy27;
	}
yy30:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) if (fill_buffered_scc(in, 1) != 0) return -2;
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy28;
		case 'a':
			in->yytm2 = in->yytm1;
			taglist(&in->yytm2, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy32;
		default: goto yy31;
	}
yy31:
	YYCURSOR = YYMARKER;
	goto yy27;
yy32:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) if (fill_buffered_scc(in, 1) != 0) return -2;
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy28;
		case 'a':
			in->yytm3 = in->yytm1;
			taglist(&in->yytm3, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy33;
		default: goto yy31;
	}
yy33:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) if (fill_buffered_scc(in, 1) != 0) return -2;
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			in->yytm1 = in->yytm2;
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy28;
		case 'a': goto yy34;
		default: goto yy31;
	}
yy34:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) if (fill_buffered_scc(in, 1) != 0) return -2;
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy28;
		case 'a':
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy35;
		default: goto yy31;
	}
yy35:
	++YYCURSOR;
	if (YYLIMIT <= YYCURSOR) if (fill_buffered_scc(in, 1) != 0) return -2;
	yych = *YYCURSOR;
	switch (yych) {
		case '\n':
			in->yytm1 = in->yytm3;
			taglist(&in->yytm1, YYTOKEN, YYCURSOR, &in->tlp);
			goto yy28;
		case 'a': goto yy30;
		default: goto yy31;
	}
}

}

#undef YYCURSOR
#undef YYMARKER
#undef YYLIMIT
#undef YYTOKEN
#undef TLP_CLEAR

#define FN_BENCH(suffix) \
void bench_##suffix::operator()( \
        benchmark::State &state, const char* input, long expected) const { \
    long count = 0; \
    for (auto _ : state) { \
        input_t in; \
        init_input_##suffix(&in, input); \
        count = lex_##suffix(&in); \
        free_input(&in); \
    } \
    if (count != expected) state.SkipWithError("re2c: error"); \
}
FN_BENCH(simple)
FN_BENCH(buffered_eof)
FN_BENCH(buffered_scc)
#undef FN_BENCH

#define FN_TEST(suffix) \
bool test_##suffix(const char* input, long expected) { \
    input_t in; \
    init_input_##suffix(&in, input); \
    long count = lex_##suffix(&in); \
    switch (count) { \
    default: \
        if (count != expected) { \
            fprintf(stderr, "re2c: wrong count, expected %ld, got %ld\n", expected, count); \
        } \
        break; \
    case -1: \
        fprintf(stderr, "re2c: syntax error\n"); \
        break; \
    case -2: \
        fprintf(stderr, "re2c: yyfill error\n"); \
        break; \
    } \
    free_input(&in); \
    return count == expected; \
}
FN_TEST(simple)
FN_TEST(buffered_eof)
FN_TEST(buffered_scc)
#undef FN_TEST


} // namespace re2c_submatch_33__rep_alt_5_3_2
