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