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