xref: /netbsd-src/usr.bin/m4/tokenizer.l (revision d34c2845b874ea4ec9cbafb52393b636b607ecbb)
171dafaa1Schristos %{
2*d34c2845Smatt /* $NetBSD: tokenizer.l,v 1.6 2012/03/20 20:34:58 matt Exp $ */
371dafaa1Schristos /* $OpenBSD: tokenizer.l,v 1.6 2008/08/21 21:00:14 espie Exp $ */
471dafaa1Schristos /*
571dafaa1Schristos  * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org>
671dafaa1Schristos  *
771dafaa1Schristos  * Permission to use, copy, modify, and distribute this software for any
871dafaa1Schristos  * purpose with or without fee is hereby granted, provided that the above
971dafaa1Schristos  * copyright notice and this permission notice appear in all copies.
1071dafaa1Schristos  *
1171dafaa1Schristos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1271dafaa1Schristos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1371dafaa1Schristos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1471dafaa1Schristos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1571dafaa1Schristos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1671dafaa1Schristos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1771dafaa1Schristos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1871dafaa1Schristos  */
19f3efdb75Schristos #if HAVE_NBTOOL_CONFIG_H
20f3efdb75Schristos #include "nbtool_config.h"
21f3efdb75Schristos #endif
2271dafaa1Schristos #include "parser.h"
23*d34c2845Smatt __RCSID("$NetBSD: tokenizer.l,v 1.6 2012/03/20 20:34:58 matt Exp $");
2471dafaa1Schristos #include <stdlib.h>
2571dafaa1Schristos #include <errno.h>
2671dafaa1Schristos #include <stdint.h>
2771dafaa1Schristos #include <limits.h>
2871dafaa1Schristos 
2971dafaa1Schristos extern int mimic_gnu;
3071dafaa1Schristos extern int32_t yylval;
31f3efdb75Schristos extern int yylex(void);
32f3efdb75Schristos extern int yywrap(void);
3371dafaa1Schristos 
3471dafaa1Schristos int32_t number(void);
3571dafaa1Schristos int32_t parse_radix(void);
36cbf0b9daSchristos 
3771dafaa1Schristos %}
3871dafaa1Schristos 
392853bbf4Schristos %option nounput
40de7d5b13Sjoerg %option noinput
412853bbf4Schristos 
4271dafaa1Schristos delim 	[ \t\n]
4371dafaa1Schristos ws	{delim}+
4471dafaa1Schristos hex	0[xX][0-9a-fA-F]+
4571dafaa1Schristos oct	0[0-7]*
4671dafaa1Schristos dec	[1-9][0-9]*
4771dafaa1Schristos radix	0[rR][0-9]+:[0-9a-zA-Z]+
4871dafaa1Schristos 
4971dafaa1Schristos %%
5071dafaa1Schristos {ws}			{/* just skip it */}
5171dafaa1Schristos {hex}|{oct}|{dec}	{ yylval = number(); return(NUMBER); }
5271dafaa1Schristos {radix}			{ if (mimic_gnu) {
5371dafaa1Schristos 				yylval = parse_radix(); return(NUMBER);
5471dafaa1Schristos 			  } else {
5571dafaa1Schristos 			  	return(ERROR);
5671dafaa1Schristos 			  }
5771dafaa1Schristos 			}
5871dafaa1Schristos "<="			{ return(LE); }
5971dafaa1Schristos ">="			{ return(GE); }
6071dafaa1Schristos "<<"			{ return(LSHIFT); }
6171dafaa1Schristos ">>"			{ return(RSHIFT); }
6271dafaa1Schristos "=="			{ return(EQ); }
6371dafaa1Schristos "!="			{ return(NE); }
6471dafaa1Schristos "&&"			{ return(LAND); }
6571dafaa1Schristos "||"			{ return(LOR); }
6671dafaa1Schristos .			{ return yytext[0]; }
6771dafaa1Schristos %%
6871dafaa1Schristos 
6971dafaa1Schristos int32_t
70*d34c2845Smatt number(void)
7171dafaa1Schristos {
7271dafaa1Schristos 	long l;
7371dafaa1Schristos 
7471dafaa1Schristos 	errno = 0;
7571dafaa1Schristos 	l = strtol(yytext, NULL, 0);
7671dafaa1Schristos 	if (((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) ||
7771dafaa1Schristos 	    l > INT32_MAX || l < INT32_MIN) {
7871dafaa1Schristos 		fprintf(stderr, "m4: numeric overflow in expr: %s\n", yytext);
7971dafaa1Schristos 	}
8071dafaa1Schristos 	return l;
8171dafaa1Schristos }
8271dafaa1Schristos 
8371dafaa1Schristos int32_t
parse_radix(void)84*d34c2845Smatt parse_radix(void)
8571dafaa1Schristos {
8671dafaa1Schristos 	long base;
8771dafaa1Schristos 	char *next;
8871dafaa1Schristos 	long l;
8971dafaa1Schristos 
9071dafaa1Schristos 	l = 0;
9171dafaa1Schristos 	base = strtol(yytext+2, &next, 0);
9271dafaa1Schristos 	if (base > 36 || next == NULL) {
9371dafaa1Schristos 		fprintf(stderr, "m4: error in number %s\n", yytext);
9471dafaa1Schristos 	} else {
9571dafaa1Schristos 		next++;
9671dafaa1Schristos 		while (*next != 0) {
9771dafaa1Schristos 			if (*next >= '0' && *next <= '9')
9871dafaa1Schristos 				l = base * l + *next - '0';
9971dafaa1Schristos 			else if (*next >= 'a' && *next <= 'z')
10071dafaa1Schristos 				l = base * l + *next - 'a' + 10;
10171dafaa1Schristos 			else if (*next >= 'A' && *next <= 'Z')
10271dafaa1Schristos 				l = base * l + *next - 'A' + 10;
10371dafaa1Schristos 			next++;
10471dafaa1Schristos 		}
10571dafaa1Schristos 	}
10671dafaa1Schristos 	return l;
10771dafaa1Schristos }
10871dafaa1Schristos 
109