summaryrefslogtreecommitdiff
path: root/lex-pattern.l
blob: d091c744b8768cdd43a4a8ace2e5937989fe8c02 (plain)
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
%{

#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); }

%%