1228697Sbapt%option nounput noinput 2228697Sbapt%{ 3259262Stijl/* $OpenBSD: tokenizer.l,v 1.8 2012/04/12 17:00:11 espie Exp $ */ 4228697Sbapt/* 5228697Sbapt * Copyright (c) 2004 Marc Espie <espie@cvs.openbsd.org> 6228697Sbapt * 7228697Sbapt * Permission to use, copy, modify, and distribute this software for any 8228697Sbapt * purpose with or without fee is hereby granted, provided that the above 9228697Sbapt * copyright notice and this permission notice appear in all copies. 10228697Sbapt * 11228697Sbapt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12228697Sbapt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13228697Sbapt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14228697Sbapt * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15228697Sbapt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16228697Sbapt * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17228697Sbapt * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18228697Sbapt * 19228697Sbapt * $FreeBSD$ 20228697Sbapt */ 21228697Sbapt#include "parser.h" 22228697Sbapt#include <assert.h> 23228697Sbapt#include <stdlib.h> 24228697Sbapt#include <errno.h> 25228697Sbapt#include <stdint.h> 26228697Sbapt#include <limits.h> 27228697Sbapt 28228697Sbaptextern int mimic_gnu; 29228697Sbaptextern int32_t yylval; 30228697Sbapt 31228697Sbaptint32_t number(void); 32228697Sbaptint32_t parse_radix(void); 33228697Sbaptextern int yylex(void); 34259262Stijl 35259262Stijl#define YY_DECL int yylex(void) 36228697Sbapt%} 37228697Sbapt 38228697Sbaptdelim [ \t\n] 39228697Sbaptws {delim}+ 40228697Sbapthex 0[xX][0-9a-fA-F]+ 41228697Sbaptoct 0[0-7]* 42228697Sbaptdec [1-9][0-9]* 43228697Sbaptradix 0[rR][0-9]+:[0-9a-zA-Z]+ 44228697Sbapt 45228697Sbapt%% 46228697Sbapt{ws} {/* just skip it */} 47228697Sbapt{hex}|{oct}|{dec} { yylval = number(); return(NUMBER); } 48228697Sbapt{radix} { if (mimic_gnu) { 49228697Sbapt yylval = parse_radix(); return(NUMBER); 50228697Sbapt } else { 51228697Sbapt return(ERROR); 52228697Sbapt } 53228697Sbapt } 54228697Sbapt"<=" { return(LE); } 55228697Sbapt">=" { return(GE); } 56228697Sbapt"<<" { return(LSHIFT); } 57228697Sbapt">>" { return(RSHIFT); } 58228697Sbapt"==" { return(EQ); } 59228697Sbapt"!=" { return(NE); } 60228697Sbapt"&&" { return(LAND); } 61228697Sbapt"||" { return(LOR); } 62228697Sbapt"**" { if (mimic_gnu) { return (EXPONENT); } } 63228697Sbapt. { return yytext[0]; } 64228697Sbapt%% 65228697Sbapt 66228697Sbaptint32_t 67228697Sbaptnumber(void) 68228697Sbapt{ 69228697Sbapt long l; 70228697Sbapt 71228697Sbapt errno = 0; 72228697Sbapt l = strtol(yytext, NULL, 0); 73228697Sbapt if (((l == LONG_MAX || l == LONG_MIN) && errno == ERANGE) || 74228697Sbapt l > INT32_MAX || l < INT32_MIN) { 75228697Sbapt fprintf(stderr, "m4: numeric overflow in expr: %s\n", yytext); 76228697Sbapt } 77228697Sbapt return l; 78228697Sbapt} 79228697Sbapt 80228697Sbaptint32_t 81228697Sbaptparse_radix(void) 82228697Sbapt{ 83228697Sbapt long base; 84228697Sbapt char *next; 85228697Sbapt long l; 86228697Sbapt int d; 87228697Sbapt 88228697Sbapt l = 0; 89228697Sbapt base = strtol(yytext+2, &next, 0); 90228697Sbapt if (base > 36 || next == NULL) { 91228697Sbapt fprintf(stderr, "m4: error in number %s\n", yytext); 92228697Sbapt } else { 93228697Sbapt next++; 94228697Sbapt while (*next != 0) { 95228697Sbapt if (*next >= '0' && *next <= '9') 96228697Sbapt d = *next - '0'; 97228697Sbapt else if (*next >= 'a' && *next <= 'z') 98228697Sbapt d = *next - 'a' + 10; 99228697Sbapt else { 100228697Sbapt assert(*next >= 'A' && *next <= 'Z'); 101228697Sbapt d = *next - 'A' + 10; 102228697Sbapt } 103228697Sbapt if (d >= base) { 104228697Sbapt fprintf(stderr, 105228697Sbapt "m4: error in number %s\n", yytext); 106228697Sbapt return 0; 107228697Sbapt } 108228697Sbapt l = base * l + d; 109228697Sbapt next++; 110228697Sbapt } 111228697Sbapt } 112228697Sbapt return l; 113228697Sbapt} 114228697Sbapt 115