diff --git a/src/interpret.c.re b/src/interpret.c.re index 015cc31..477a55c 100644 --- a/src/interpret.c.re +++ b/src/interpret.c.re @@ -23,26 +23,37 @@ static int parse_uint(const char *s, const char *e, unsigned *u) { return 1; } +static int parse_double(const char *s0, const char *s1, double *d) { + char *finish; + assert(d && s0 && s0 < s1); + *d = strtod(s0, &finish); + return !errno && ((finish == s1) || (errno = EDOM, 0)); +} + static int lex_line(const char *YYCURSOR, unsigned *const u) { const char *YYMARKER, *o1, *o2, *o3, *o4; + double d; /*!stags:re2c format = 'const char *@@;\n'; */ - /*!re2c re2c:yyfill:enable = 0; re2c:flags:tags = 1; re2c:define:YYCTYPE = char; + keyword = [a-z][a-z0-9_-]{0,64}; // uppercase is lame octet = [0-9] | [1-9][0-9] | [1][0-9][0-9] | [2][0-4][0-9] | [2][5][0-5]; dot = [.]; end = [\x00]; eol = [\n]; w = [ \t]*; - - glider = "{" "glider" ":"; - flight = "{" "}"; - - + double = [0-9]* "." [0-9]+ | [0-9]+; + */ + errno = 0; /* For accuracy detecting errors. */ +text: + /*!re2c + "\\[" | "\\![" { goto text; } + "[" { goto custom; } + "![" { goto image; } @o1 octet dot @o2 octet dot @o3 octet dot @o4 octet end { unsigned u1, u2, u3, u4; if(!parse_uint(o1, o2 - 1, &u1) @@ -52,16 +63,36 @@ static int lex_line(const char *YYCURSOR, unsigned *const u) { *u = u4 + (u3 << 8) + (u2 << 16) + (u1 << 24); return 1; } - * { return 0; } + * { return errno = EILSEQ, 0; } + */ +image: + /*!re2c + "osm" "](" @o1 double @o2 "," @o3 double @o4 ")" { + printf("Got a map.\n"); + if(!parse_double(o1, o2, &d)) return 0; + printf("Latitude %f.\n", d); + if(!parse_double(o3, o4, &d)) return 0; + printf("Longitude %f.\n", d); + goto text; + } + * { return errno = EILSEQ, 0; } + */ +custom: + /*!re2c + glider = "glider" ":" ; + flight = "flight" ":" ; + * { return errno = EILSEQ, 0; } */ } int main(int argc, char **argv) { unsigned u; - int success; - success = lex_line("1.2.3.4", &u); - assert(success); - printf("%x\n", u); + if(!lex_line("1.2.3.4", &u)) goto catch; + printf("0x%x\n", u); + if(!lex_line("1.2.3.49999999999999999", &u)) goto catch; return EXIT_SUCCESS; +catch: + perror("interpret"); + return EXIT_FAILURE; }