%{ #include #include #include "ast.h" #include "parse-pattern.h" static int intlit(long *out, const char *in) { errno = 0; *out = strtol(in, NULL, 10); return errno == ERANGE ? T_BADLIT : T_INTEGER; } static int strlit(char **out, const char *in, size_t inlen) { in += 1; inlen -= 2; size_t len = 0; for (const char *c = in; c < in + inlen; c++, len++) { if (*c == '\"') c++; } char *str; if (!(*out = str = malloc(len + 1))) return T_NOMEM; for (const char *c = in; c < in + inlen; *str++ = *c++) { if (*c == '\"') c++; } *str = 0; return T_STRING; } %} %option outfile="lex-pattern.c" header-file="lex-pattern.h" %option noyywrap never-interactive %% \( { return T_LPAREN; } \) { return T_RPAREN; } , { return T_COMMA; } \. { return T_PERIOD; } A { return T_ALPHABETIC; } N { return T_NUMERIC; } U { return T_UPPERCASE; } L { return T_LOWERCASE; } C { return T_CONTROL; } P { return T_PUNCTUATION; } E { return T_EVERYTHING; } [0-9]+ { return intlit(&yylval.lval, yytext); } \"(\"\"|[^"])*\" { return strlit(&yylval.sval, yytext, yyleng); } %%