1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
// re2c $INPUT -o $OUTPUT -i --recursive-functions
#include <stdint.h>
#include <limits.h>
#include <assert.h>
static const uint64_t ERROR = ~0lu;
struct State
{
const char* cur;
const char* mar;
uint64_t num;
};
template<int BASE> static void adddgt(uint64_t &u, unsigned int d)
{
u = u * BASE + d;
if (u > UINT32_MAX) u = ERROR;
}
/*!re2c
re2c:yyfill:enable = 0;
re2c:define:YYCTYPE = char;
re2c:define:YYCURSOR = st.cur;
re2c:define:YYMARKER = st.mar;
end = "\x00";
*/
/*!local:re2c
re2c:define:YYFN = ["lex_bin;uint64_t", "st;State&"];
end { return st.num; }
[01] { adddgt<2>(st.num, st.cur[-1] - '0'); return lex_bin(st); }
* { return ERROR; }
*/
/*!local:re2c
re2c:define:YYFN = ["lex_oct;uint64_t", "st;State&"];
end { return st.num; }
[0-7] { adddgt<8>(st.num, st.cur[-1] - '0'); return lex_oct(st); }
* { return ERROR; }
*/
/*!local:re2c
re2c:define:YYFN = ["lex_dec;uint64_t", "st;State&"];
end { return st.num; }
[0-9] { adddgt<10>(st.num, st.cur[-1] - '0'); return lex_dec(st); }
* { return ERROR; }
*/
/*!local:re2c
re2c:define:YYFN = ["lex_hex;uint64_t", "st;State&"];
end { return st.num; }
[0-9] { adddgt<16>(st.num, st.cur[-1] - '0'); return lex_hex(st); }
[a-f] { adddgt<16>(st.num, st.cur[-1] - 'a' + 10); return lex_hex(st); }
[A-F] { adddgt<16>(st.num, st.cur[-1] - 'A' + 10); return lex_hex(st); }
* { return ERROR; }
*/
/*!local:re2c
re2c:define:YYFN = ["lex_main;uint64_t", "st;State&"];
'0b' / [01] { return lex_bin(st); }
"0" { return lex_oct(st); }
"" / [1-9] { return lex_dec(st); }
'0x' / [0-9a-fA-F] { return lex_hex(st); }
* { return ERROR; }
*/
static uint64_t parse_u32(const char *s)
{
State st = {s, nullptr, 0};
return lex_main(st);
}
int main()
{
assert(parse_u32("1234567890") == 1234567890);
assert(parse_u32("0b1101") == 13);
assert(parse_u32("0x7Fe") == 2046);
assert(parse_u32("0644") == 420);
assert(parse_u32("9999999999") == ERROR);
assert(parse_u32("") == ERROR);
return 0;
}
|