diff options
Diffstat (limited to 'lex-pattern.l')
-rw-r--r-- | lex-pattern.l | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lex-pattern.l b/lex-pattern.l new file mode 100644 index 0000000..d091c74 --- /dev/null +++ b/lex-pattern.l @@ -0,0 +1,58 @@ +%{ + +#include <errno.h> +#include <stdlib.h> + +#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); } + +%% |