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