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