/* Generated by re2c 2.2 */ #line 1 "espurna\\ir_parse_raw.re" /* Part of the IR MODULE For more info: - https://re2c.org/ - https://re2c.org/manual/manual_c.html */ #pragma once // ref. // - https://github.com/skvadrik/re2c/blob/423c56ca556de944598f29b59abc43f89b616fb6/examples/c/submatch/02_mtags.re // - https://github.com/skvadrik/re2c/blob/b4efac3cc09abcab6cd063df80b23d0da70acc70/examples/c/submatch/http_rfc7230.re // - https://github.com/skvadrik/re2c/blob/423c56ca556de944598f29b59abc43f89b616fb6/examples/go/submatch/02_mtags.re // - https://github.com/skvadrik/re2c/blob/b4efac3cc09abcab6cd063df80b23d0da70acc70/test/golang/005_mtags.re // // Example code MTAG updates are stored in a tree-like structure (in the submatch example, a flat vector of TAG and YYCURSOR) // Using the observed parser behaviour, instead try to parse things inline right when the MTAG function is called, // by comparing the last TAG value with the current one, noticing the increment that will only happen when the match actually happens. // May be problematic, but at least there is some safety in the fact that the previous values are only updated when the match block is executed. // TODO: same as the 'simple' variant, does not really notify about any errors struct TimeRange { int tag; const char* start; }; ParseResult parse(StringView view) { const char* YYCURSOR { view.begin() }; const char* YYLIMIT { view.end() }; const char* YYMARKER; const char *d0, *d1; const char *s0, *s1; const char *f0, *f1; static constexpr int Root { -1 }; TimeRange range { Root, nullptr }; int t0 { Root }; int t1 { Root }; decltype(Payload::time) time; ParseResult out; auto update_range = [&](const char* ptr, int tag) { if (ptr && !range.start) { time.reserve(std::count(view.begin(), view.end(), ',')); range.start = ptr; } if (ptr && range.start) { if (range.tag != tag) { range.start = ptr; range.tag = tag; } if (ptr - range.start) { time.push_back(payload::time(StringView{range.start, ptr})); } } }; #line 70 "espurna\\ir_parse_raw.re.ipp" const char *yyt1; const char *yyt2; const char *yyt3; const char *yyt4; #line 66 "espurna\\ir_parse_raw.re" #line 78 "espurna\\ir_parse_raw.re.ipp" int yyt5 { Root }; int yyt6 { Root }; #line 67 "espurna\\ir_parse_raw.re" #line 85 "espurna\\ir_parse_raw.re.ipp" { char yych; yych = *YYCURSOR; switch (yych) { case '0' ... '9': yyt1 = YYCURSOR; goto yy4; default: if (YYLIMIT <= YYCURSOR) goto yy19; goto yy2; } yy2: ++YYCURSOR; yy3: #line 90 "espurna\\ir_parse_raw.re" { goto return_out; } #line 102 "espurna\\ir_parse_raw.re.ipp" yy4: yych = *(YYMARKER = ++YYCURSOR); switch (yych) { case '0' ... ':': goto yy6; default: goto yy3; } yy5: yych = *++YYCURSOR; yy6: switch (yych) { case '0' ... '9': goto yy5; case ':': goto yy8; default: goto yy7; } yy7: YYCURSOR = YYMARKER; goto yy3; yy8: yych = *++YYCURSOR; switch (yych) { case '0' ... '9': yyt2 = YYCURSOR; goto yy9; default: goto yy7; } yy9: yych = *++YYCURSOR; switch (yych) { case '0' ... '9': goto yy9; case ':': goto yy11; default: goto yy7; } yy11: yych = *++YYCURSOR; switch (yych) { case '0' ... '9': yyt3 = YYCURSOR; goto yy12; default: goto yy7; } yy12: yych = *++YYCURSOR; switch (yych) { case '0' ... '9': goto yy12; case ':': yyt4 = YYCURSOR; goto yy14; default: goto yy7; } yy14: yych = *++YYCURSOR; switch (yych) { case '0' ... '9': update_range(YYCURSOR, yyt5++); goto yy15; default: goto yy7; } yy15: yych = *++YYCURSOR; switch (yych) { case ',': update_range(YYCURSOR, yyt6++); goto yy18; case '0' ... '9': goto yy15; default: update_range(YYCURSOR, yyt6++); goto yy17; } yy17: f0 = yyt1; s0 = yyt2; d0 = yyt3; d1 = yyt4; t0 = yyt5; t1 = yyt6; f1 = yyt2 - 1; s1 = yyt3 - 1; #line 83 "espurna\\ir_parse_raw.re" { if ((t0 != Root) && (t1 != Root)) { goto update_out; } goto return_out; } #line 187 "espurna\\ir_parse_raw.re.ipp" yy18: yych = *++YYCURSOR; switch (yych) { case '0' ... '9': update_range(YYCURSOR, yyt5++); goto yy15; default: goto yy17; } yy19: #line 91 "espurna\\ir_parse_raw.re" { goto return_out; } #line 199 "espurna\\ir_parse_raw.re.ipp" } #line 92 "espurna\\ir_parse_raw.re" update_out: { out = prepare( StringView{f0, f1}, StringView{s0, s1}, StringView{d0, d1}, std::move(time)); } return_out: return out; }