1 %{ 2 /* $OpenBSD: tokenizer.l,v 1.8 2012/04/12 17:00:11 espie 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 int mimic_gnu; 26 extern int32_t yylval; 27 28 int32_t number(void); 29 int32_t parse_radix(void); 30 %} 31 32 delim [ \t\n] 33 ws {delim}+ 34 hex 0[xX][0-9a-fA-F]+ 35 oct 0[0-7]* 36 dec [1-9][0-9]* 37 radix 0[rR][0-9]+:[0-9a-zA-Z]+ 38 39 %% 40 {ws} {/* just skip it */} 41 {hex}|{oct}|{dec} { yylval = number(); return(NUMBER); } 42 {radix} { if (mimic_gnu) { 43 yylval = parse_radix(); return(NUMBER); 44 } else { 45 return(ERROR); 46 } 47 } 48 "<=" { return(LE); } 49 ">=" { return(GE); } 50 "<<" { return(LSHIFT); } 51 ">>" { return(RSHIFT); } 52 "==" { return(EQ); } 53 "!=" { return(NE); } 54 "&&" { return(LAND); } 55 "||" { return(LOR); } 56 "**" { if (mimic_gnu) { return (EXPONENT); } } 57 . { return yytext[0]; } 58 %% 59 60 int32_t 61 number() 62 { 63 long l; 64 65 errno = 0; 66 l = strtol(yytext, NULL, 0); 67 if (((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) || 68 l > INT32_MAX || l < INT32_MIN) { 69 fprintf(stderr, "m4: numeric overflow in expr: %s\n", yytext); 70 } 71 return l; 72 } 73 74 int32_t 75 parse_radix() 76 { 77 long base; 78 char *next; 79 long l; 80 int d; 81 82 l = 0; 83 base = strtol(yytext+2, &next, 0); 84 if (base > 36 || next == NULL) { 85 fprintf(stderr, "m4: error in number %s\n", yytext); 86 } else { 87 next++; 88 while (*next != 0) { 89 if (*next >= '0' && *next <= '9') 90 d = *next - '0'; 91 else if (*next >= 'a' && *next <= 'z') 92 d = *next - 'a' + 10; 93 else { 94 assert(*next >= 'A' && *next <= 'Z'); 95 d = *next - 'A' + 10; 96 } 97 if (d >= base) { 98 fprintf(stderr, 99 "m4: error in number %s\n", yytext); 100 return 0; 101 } 102 l = base * l + d; 103 next++; 104 } 105 } 106 return l; 107 } 108 109