scan.l revision 18950
1%x string name charmap defn nchar subs 2%{ 3/*- 4 * Copyright (c) 1995 Alex Tatmanjants <alex@elvisti.kiev.ua> 5 * at Electronni Visti IA, Kiev, Ukraine. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $Id: scan.l,v 1.3 1996/06/02 17:18:18 phk Exp $ 30 */ 31 32#include <ctype.h> 33#include <err.h> 34#include <unistd.h> 35#include <string.h> 36#include <sysexits.h> 37#include "collate.h" 38#include "y.tab.h" 39 40int line_no = 1, save_no; 41u_char buf[STR_LEN], *ptr; 42FILE *map_fp; 43extern char map_name[]; 44YY_BUFFER_STATE main_buf, map_buf; 45#ifdef FLEX_DEBUG 46YYSTYPE yylval; 47#endif /* FLEX_DEBUG */ 48%} 49%% 50<INITIAL,charmap,nchar,subs>[ \t]+ ; 51<subs>\" { ptr = buf; BEGIN(string); } 52<INITIAL>\< { ptr = buf; BEGIN(name); } 53^#.*\n line_no++; 54^\n line_no++; 55<INITIAL>\\\n line_no++; 56<INITIAL,nchar>\\t { yylval.ch = '\t'; return CHAR; } 57<INITIAL,nchar>\\n { yylval.ch = '\n'; return CHAR; } 58<INITIAL,nchar>\\b { yylval.ch = '\b'; return CHAR; } 59<INITIAL,nchar>\\f { yylval.ch = '\f'; return CHAR; } 60<INITIAL,nchar>\\v { yylval.ch = '\v'; return CHAR; } 61<INITIAL,nchar>\\r { yylval.ch = '\r'; return CHAR; } 62<INITIAL,nchar>\\a { yylval.ch = '\a'; return CHAR; } 63<INITIAL,nchar>\\. { yylval.ch = yytext[1]; return CHAR; } 64<subs>\n { 65 line_no++; 66 BEGIN(INITIAL); 67 return '\n'; 68} 69<INITIAL,nchar>\n { 70 line_no++; 71 if (map_fp != NULL) { 72 ptr = buf; 73 BEGIN(defn); 74 } 75 return '\n'; 76} 77<INITIAL>[;,{}()] return *yytext; 78<INITIAL>substitute { BEGIN(subs); return SUBSTITUTE; } 79<subs>with return WITH; 80<INITIAL>order return ORDER; 81<INITIAL>charmap BEGIN(charmap); 82<INITIAL>;[ \t]*\.\.\.[ \t]*; return RANGE; 83<INITIAL,nchar>\\[0-7]{3} { 84 u_int v; 85 86 sscanf(&yytext[1], "%o", &v); 87 yylval.ch = (u_char)v; 88 return CHAR; 89} 90<INITIAL,nchar>\\x[0-9a-z]{2} { 91 u_int v; 92 93 sscanf(&yytext[2], "%x", &v); 94 yylval.ch = (u_char)v; 95 return CHAR; 96} 97<INITIAL>[^;,{}() \t\n"<]+ { 98 if(yyleng == 1) { 99 yylval.ch = *yytext; 100 return CHAR; 101 } 102 if(yyleng > STR_LEN - 1) 103 errx(EX_UNAVAILABLE, "chain buffer overflaw near line %u", 104 line_no); 105 strcpy(yylval.str, yytext); 106 return CHAIN; 107} 108<nchar>. { 109 yylval.ch = *yytext; 110 return CHAR; 111} 112<defn>[ \t]+ { 113 if (ptr == buf) 114 errx(EX_UNAVAILABLE, "map expected near line %u of %s", 115 line_no, map_name); 116 *ptr = '\0'; 117 strcpy(yylval.str, buf); 118 BEGIN(nchar); 119 return DEFN; 120} 121<name>\/\/ { 122 if(ptr >= buf + sizeof(buf) - 1) 123 errx(EX_UNAVAILABLE, "name buffer overflaw near line %u, character '/'", 124 line_no); 125 *ptr++ = '/'; 126} 127<name>\/\> { 128 if(ptr >= buf + sizeof(buf) - 1) 129 errx(EX_UNAVAILABLE, "name buffer overflaw near line %u, character '>'", 130 line_no); 131 *ptr++ = '>'; 132} 133<string>\\\" { 134 if(ptr >= buf + sizeof(buf) - 1) 135 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\"'", 136 line_no); 137 *ptr++ = '"'; 138} 139<name>\> { 140 if (ptr == buf) 141 errx(EX_UNAVAILABLE, "name expected near line %u", 142 line_no); 143 *ptr = '\0'; 144 strcpy(yylval.str, buf); 145 BEGIN(INITIAL); 146 return NAME; 147} 148<string>\" { 149 *ptr = '\0'; 150 strcpy(yylval.str, buf); 151 BEGIN(subs); 152 return STRING; 153} 154<name,defn>. { 155 char *s = (map_fp != NULL) ? map_name : "input"; 156 157 if (!isascii(*yytext) || !isprint(*yytext)) 158 errx(EX_UNAVAILABLE, "non-ASCII or non-printable character 0x%02x not allowed in the map/name near line %u of %s", 159 *yytext, line_no, s); 160 if(ptr >= buf + sizeof(buf) - 1) 161 errx(EX_UNAVAILABLE, "map/name buffer overflaw near line %u of %s, character '%c'", 162 line_no, s, *yytext); 163 *ptr++ = *yytext; 164} 165<string>\\t { 166 if(ptr >= buf + sizeof(buf) - 1) 167 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\t'", 168 line_no); 169 *ptr++ = '\t'; 170} 171<string>\\b { 172 if(ptr >= buf + sizeof(buf) - 1) 173 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\b'", 174 line_no); 175 *ptr++ = '\b'; 176} 177<string>\\f { 178 if(ptr >= buf + sizeof(buf) - 1) 179 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\f'", 180 line_no); 181 *ptr++ = '\f'; 182} 183<string>\\v { 184 if(ptr >= buf + sizeof(buf) - 1) 185 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\v'", 186 line_no); 187 *ptr++ = '\v'; 188} 189<string>\\n { 190 if(ptr >= buf + sizeof(buf) - 1) 191 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\n'", 192 line_no); 193 *ptr++ = '\n'; 194} 195<string>\\r { 196 if(ptr >= buf + sizeof(buf) - 1) 197 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\r'", 198 line_no); 199 *ptr++ = '\r'; 200} 201<string>\\a { 202 if(ptr >= buf + sizeof(buf) - 1) 203 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '\\a'", 204 line_no); 205 *ptr++ = '\a'; 206} 207<name,string,defn>\n { 208 char *s = (map_fp != NULL) ? map_name : "input"; 209 210 errx(EX_UNAVAILABLE, "unterminated map/name/string near line %u of %s", line_no, s); 211} 212<name,string,nchar><<EOF>> { 213 char *s = (map_fp != NULL) ? map_name : "input"; 214 215 errx(EX_UNAVAILABLE, "premature EOF in the name/string/char near line %u of %s", line_no, s); 216} 217<string>\\x[0-9a-f]{2} { 218 u_int v; 219 220 sscanf(&yytext[2], "%x", &v); 221 *ptr++ = (u_char)v; 222} 223<string>\\[0-7]{3} { 224 u_int v; 225 226 sscanf(&yytext[1], "%o", &v); 227 *ptr++ = (u_char)v; 228} 229<string>\\. { 230 if(ptr >= buf + sizeof(buf) - 1) 231 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '%c'", 232 line_no, yytext[1]); 233 *ptr++ = yytext[1]; 234} 235<string>. { 236 if(ptr >= buf + sizeof(buf) - 1) 237 errx(EX_UNAVAILABLE, "string buffer overflaw near line %u, character '%c'", 238 line_no, *yytext); 239 *ptr++ = *yytext; 240} 241<charmap>[^ \t\n]+ { 242 strcat(map_name, "/"); 243 strcat(map_name, yytext); 244 if((map_fp = fopen(map_name, "r")) == NULL) 245 err(EX_UNAVAILABLE, "can't open 'charmap' file %s", 246 map_name); 247 save_no = line_no; 248 line_no = 1; 249 map_buf = yy_new_buffer(map_fp, YY_BUF_SIZE); 250 main_buf = YY_CURRENT_BUFFER; 251 yy_switch_to_buffer(map_buf); 252 ptr = buf; 253 BEGIN(defn); 254} 255<charmap>\n { 256 errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 257 line_no); 258} 259<charmap><<EOF>> { 260 errx(EX_UNAVAILABLE, "'charmap' file name expected near line %u", 261 line_no); 262} 263<INITIAL,defn><<EOF>> { 264 if(map_fp != NULL) { 265 if (ptr != buf) 266 errx(EX_UNAVAILABLE, "premature EOF in the map near line %u of %s", line_no, map_name); 267 yy_switch_to_buffer(main_buf); 268 yy_delete_buffer(map_buf); 269 fclose(map_fp); 270 map_fp = NULL; 271 line_no = save_no; 272 BEGIN(INITIAL); 273 } else 274 yyterminate(); 275} 276%% 277#ifdef FLEX_DEBUG 278main() 279{ 280 while(yylex()) 281 ; 282 return 0; 283} 284#endif /* FLEX_DEBUG */ 285