1 %{
2 /* $OpenBSD: tokenizer.l,v 1.10 2017/06/17 01:55:16 bcallah Exp $ */
3 /*
4 * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 #include "parser.h"
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <stdint.h>
23 #include <limits.h>
24
25 extern void m4_warnx(const char *, ...);
26 extern int mimic_gnu;
27 extern int32_t yylval;
28
29 int32_t number(void);
30 int32_t parse_radix(void);
31 %}
32
33 delim [ \t\n]
34 ws {delim}+
35 hex 0[xX][0-9a-fA-F]+
36 oct 0[0-7]*
37 dec [1-9][0-9]*
38 radix 0[rR][0-9]+:[0-9a-zA-Z]+
39
40 %option noyywrap
41
42 %%
43 {ws} {/* just skip it */}
44 {hex}|{oct}|{dec} { yylval = number(); return(NUMBER); }
45 {radix} { if (mimic_gnu) {
46 yylval = parse_radix(); return(NUMBER);
47 } else {
48 return(ERROR);
49 }
50 }
51 "<=" { return(LE); }
52 ">=" { return(GE); }
53 "<<" { return(LSHIFT); }
54 ">>" { return(RSHIFT); }
55 "==" { return(EQ); }
56 "!=" { return(NE); }
57 "&&" { return(LAND); }
58 "||" { return(LOR); }
59 "**" { if (mimic_gnu) { return (EXPONENT); } }
60 . { return yytext[0]; }
61 %%
62
63 int32_t
64 number()
65 {
66 long l;
67
68 errno = 0;
69 l = strtol(yytext, NULL, 0);
70 if (((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) ||
71 l > INT32_MAX || l < INT32_MIN)
72 m4_warnx("numeric overflow in expr: %s", yytext);
73 return l;
74 }
75
76 int32_t
parse_radix()77 parse_radix()
78 {
79 long base;
80 char *next;
81 long l;
82 int d;
83
84 l = 0;
85 base = strtol(yytext+2, &next, 0);
86 if (base > 36 || next == NULL) {
87 m4_warnx("error in number %s", yytext);
88 } else {
89 next++;
90 while (*next != 0) {
91 if (*next >= '0' && *next <= '9')
92 d = *next - '0';
93 else if (*next >= 'a' && *next <= 'z')
94 d = *next - 'a' + 10;
95 else {
96 assert(*next >= 'A' && *next <= 'Z');
97 d = *next - 'A' + 10;
98 }
99 if (d >= base) {
100 m4_warnx("error in number %s", yytext);
101 return 0;
102 }
103 l = base * l + d;
104 next++;
105 }
106 }
107 return l;
108 }
109
110