/* Generated by re2c */
#line 1 "tags/captvars_with_lookahead.re"
// re2c $INPUT -o $OUTPUT
#include <assert.h>
#include <stddef.h>

typedef struct { int major, minor, patch; } SemVer;

static int s2n(const char *s, const char *e) { // pre-parsed string to number
    int n = 0;
    for (; s < e; ++s) n = n * 10 + (*s - '0');
    return n;
}

static int lex(const char *str, SemVer *ver) {
    const char *YYCURSOR = str, *YYMARKER;

    // Final tag variables available in semantic action.
    
#line 21 "tags/captvars_with_lookahead.c"
const char *yytl0;
const char *yytl1;
const char *yytl2;
const char *yytl3;
const char *yytr0;
const char *yytr1;
const char *yytr2;
const char *yytr3;
#line 17 "tags/captvars_with_lookahead.re"


    // Intermediate tag variables used by the lexer (must be autogenerated).
    
#line 35 "tags/captvars_with_lookahead.c"
const char *yyt1;
const char *yyt2;
const char *yyt3;
const char *yyt4;
const char *yyt5;
const char *yyt6;
#line 20 "tags/captvars_with_lookahead.re"


    
#line 46 "tags/captvars_with_lookahead.c"
{
	char yych;
	unsigned int yyaccept = 0;
	yych = *YYCURSOR;
	switch (yych) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			yyt1 = YYCURSOR;
			goto yy3;
		default: goto yy1;
	}
yy1:
	++YYCURSOR;
yy2:
#line 36 "tags/captvars_with_lookahead.re"
	{ return 1; }
#line 71 "tags/captvars_with_lookahead.c"
yy3:
	yyaccept = 0;
	yych = *(YYMARKER = ++YYCURSOR);
	switch (yych) {
		case '.': goto yy4;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9': goto yy6;
		default: goto yy2;
	}
yy4:
	yych = *++YYCURSOR;
	switch (yych) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			yyt2 = YYCURSOR;
			goto yy7;
		default: goto yy5;
	}
yy5:
	YYCURSOR = YYMARKER;
	if (yyaccept == 0) {
		goto yy2;
	} else {
		yyt3 = YYCURSOR;
		yyt4 = NULL;
		yyt5 = YYCURSOR;
		yyt6 = NULL;
		goto yy8;
	}
yy6:
	yych = *++YYCURSOR;
	switch (yych) {
		case '.': goto yy4;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9': goto yy6;
		default: goto yy5;
	}
yy7:
	yyaccept = 1;
	yych = *(YYMARKER = ++YYCURSOR);
	switch (yych) {
		case '.':
			yyt3 = YYCURSOR;
			yyt6 = YYCURSOR;
			goto yy9;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9': goto yy7;
		case 'L':
		case 'U':
		case 'l':
		case 'u':
			yyt3 = YYCURSOR;
			yyt4 = NULL;
			yyt5 = YYCURSOR;
			yyt6 = NULL;
			goto yy10;
		default:
			yyt3 = YYCURSOR;
			yyt4 = NULL;
			yyt5 = YYCURSOR;
			yyt6 = NULL;
			goto yy8;
	}
yy8:
	yytl1 = yyt1;
	yytl2 = yyt2;
	yytr2 = yyt3;
	yytl3 = yyt6;
	yytr3 = yyt4;
	yytl0 = yyt1;
	yytr0 = yyt5;
	yytr1 = yyt2;
	yytr1 -= 1;
	YYCURSOR = yyt5;
#line 29 "tags/captvars_with_lookahead.re"
	{
            (void) yytl0; (void) yytr0; // some variables are unused
            ver->major = s2n(yytl1, yytr1);
            ver->minor = s2n(yytl2, yytr2);
            ver->patch = yytl3 ? s2n(yytl3 + 1, yytr3) : 0;
            return 0;
        }
#line 186 "tags/captvars_with_lookahead.c"
yy9:
	yych = *++YYCURSOR;
	switch (yych) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9': goto yy11;
		default: goto yy5;
	}
yy10:
	yych = *++YYCURSOR;
	switch (yych) {
		case 'L':
		case 'U':
		case 'l':
		case 'u': goto yy10;
		default: goto yy8;
	}
yy11:
	yych = *++YYCURSOR;
	switch (yych) {
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9': goto yy11;
		case 'L':
		case 'U':
		case 'l':
		case 'u':
			yyt4 = YYCURSOR;
			yyt5 = YYCURSOR;
			goto yy10;
		default:
			yyt4 = YYCURSOR;
			yyt5 = YYCURSOR;
			goto yy8;
	}
}
#line 37 "tags/captvars_with_lookahead.re"

}

int main() {
    SemVer v;
    assert(lex("23.34ull", &v) == 0 && v.major == 23 && v.minor == 34 && v.patch == 0);
    assert(lex("1.2.999", &v) == 0 && v.major == 1 && v.minor == 2 && v.patch == 999);
    assert(lex("1.a", &v) == 1);
    return 0;
}