1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)yylex.c 5.1 (Berkeley) 06/05/85"; 9 #endif not lint 10 11 #include "whoami.h" 12 #include "0.h" 13 #include "tree_ty.h" /* must be included for yy.h */ 14 #include "yy.h" 15 16 /* 17 * Scanner 18 */ 19 int yylacnt; 20 21 #define YYLASIZ 10 22 23 struct yytok Yla[YYLASIZ]; 24 25 unyylex(y) 26 struct yytok *y; 27 { 28 29 if (yylacnt == YYLASIZ) 30 panic("unyylex"); 31 copy((char *) &Yla[yylacnt], (char *) y, sizeof Yla[0]); 32 yylacnt++; 33 34 } 35 36 yylex() 37 { 38 register c; 39 register int **ip; 40 register char *cp; 41 int f; 42 char delim; 43 44 if (yylacnt != 0) { 45 yylacnt--; 46 copy((char *) &Y, (char *) &Yla[yylacnt], sizeof Y); 47 return (yychar); 48 } 49 if (c = yysavc) 50 yysavc = 0; 51 else 52 c = readch(); 53 #ifdef PXP 54 yytokcnt++; 55 #endif 56 57 next: 58 /* 59 * skip white space 60 */ 61 #ifdef PXP 62 yywhcnt = 0; 63 #endif 64 while (c == ' ' || c == '\t') { 65 #ifdef PXP 66 if (c == '\t') 67 yywhcnt++; 68 yywhcnt++; 69 #endif 70 c = readch(); 71 } 72 yyecol = yycol; 73 yyeline = yyline; 74 yyefile = filename; 75 yyeseqid = yyseqid; 76 yyseekp = yylinpt; 77 cp = token; 78 yylval = yyline; 79 switch (c) { 80 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': 81 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': 82 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': 83 case 'v': case 'w': case 'x': case 'y': case 'z': 84 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': 85 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': 86 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': 87 case 'V': case 'W': case 'X': case 'Y': case 'Z': 88 do { 89 *cp++ = c; 90 c = readch(); 91 } while (alph(c) || digit(c)); 92 *cp = 0; 93 if (opt('s')) 94 for (cp = token; *cp; cp++) 95 if (*cp >= 'A' && *cp <= 'Z') { 96 *cp |= ' '; 97 } 98 yysavc = c; 99 ip = (int **) hash((char *) 0, 1); 100 if (*ip < (int *) yykey || *ip >= (int *) lastkey) { 101 yylval = (int) *ip; 102 return (YID); 103 } 104 yylval = yyline; 105 /* 106 * For keywords 107 * the lexical token 108 * is magically retrieved 109 * from the keyword table. 110 */ 111 return ((*ip)[1]); 112 case '0': case '1': case '2': case '3': case '4': 113 case '5': case '6': case '7': case '8': case '9': 114 f = 0; 115 do { 116 *cp++ = c; 117 c = readch(); 118 } while (digit(c)); 119 if (c == 'b' || c == 'B') { 120 /* 121 * nonstandard - octal constants 122 */ 123 if (opt('s')) { 124 standard(); 125 yerror("Octal constants are non-standard"); 126 } 127 *cp = 0; 128 yylval = copystr(token); 129 return (YBINT); 130 } 131 if (c == '.') { 132 c = readch(); 133 if (c == '.') { 134 *cp = 0; 135 yysavc = YDOTDOT; 136 yylval = copystr(token); 137 return (YINT); 138 } 139 infpnumb: 140 f++; 141 *cp++ = '.'; 142 if (!digit(c)) { 143 yyset(); 144 recovered(); 145 yerror("Digits required after decimal point"); 146 *cp++ = '0'; 147 } else 148 while (digit(c)) { 149 *cp++ = c; 150 c = readch(); 151 } 152 } 153 if (c == 'e' || c == 'E') { 154 f++; 155 *cp++ = c; 156 if ((c = yysavc) == 0) 157 c = readch(); 158 if (c == '+' || c == '-') { 159 *cp++ = c; 160 c = readch(); 161 } 162 if (!digit(c)) { 163 yyset(); 164 yerror("Digits required in exponent"); 165 *cp++ = '0'; 166 } else 167 while (digit(c)) { 168 *cp++ = c; 169 c = readch(); 170 } 171 } 172 *cp = 0; 173 yysavc = c; 174 yylval = copystr(token); 175 if (f) 176 return (YNUMB); 177 return (YINT); 178 case '"': 179 case '`': 180 case '#': 181 if (!any(bufp + 1, c)) 182 goto illch; 183 if (!dquote) { 184 recovered(); 185 dquote++; 186 yerror("Character/string delimiter is '"); 187 } 188 case '\'': 189 delim = c; 190 do { 191 do { 192 c = readch(); 193 if (c == '\n') { 194 yerror("Unmatched %c for string", (char *) delim); 195 if (cp == token) 196 *cp++ = ' ', cp++; 197 break; 198 } 199 *cp++ = c; 200 } while (c != delim); 201 c = readch(); 202 } while (c == delim); 203 *--cp = 0; 204 if (cp == token) { 205 yerror("Null string not allowed"); 206 *cp++ = ' '; 207 *cp++ = 0; 208 } 209 yysavc = c; 210 yylval = copystr(token); 211 return (YSTRING); 212 case '.': 213 c = readch(); 214 if (c == '.') 215 return (YDOTDOT); 216 if (digit(c)) { 217 recovered(); 218 yerror("Digits required before decimal point"); 219 *cp++ = '0'; 220 goto infpnumb; 221 } 222 yysavc = c; 223 return ('.'); 224 case '{': 225 /* 226 * { ... } comment 227 */ 228 #ifdef PXP 229 getcm(c); 230 #endif 231 #ifdef PI 232 c = options(); 233 while (c != '}') { 234 if (c <= 0) 235 goto nonterm; 236 if (c == '{') { 237 warning(); 238 yyset(); 239 yerror("{ in a { ... } comment"); 240 } 241 c = readch(); 242 } 243 #endif 244 c = readch(); 245 goto next; 246 case '(': 247 if ((c = readch()) == '*') { 248 /* 249 * (* ... *) comment 250 */ 251 #ifdef PXP 252 getcm(c); 253 c = readch(); 254 goto next; 255 #endif 256 #ifdef PI 257 c = options(); 258 for (;;) { 259 if (c < 0) { 260 nonterm: 261 yerror("Comment does not terminate - QUIT"); 262 pexit(ERRS); 263 } 264 if (c == '(' && (c = readch()) == '*') { 265 warning(); 266 yyset(); 267 yerror("(* in a (* ... *) comment"); 268 } 269 if (c == '*') { 270 if ((c = readch()) != ')') 271 continue; 272 c = readch(); 273 goto next; 274 } 275 c = readch(); 276 } 277 #endif 278 } 279 yysavc = c; 280 c = '('; 281 case ';': 282 case ',': 283 case ':': 284 case '=': 285 case '*': 286 case '+': 287 case '/': 288 case '-': 289 case ')': 290 case '[': 291 case ']': 292 case '<': 293 case '>': 294 case '^': 295 return (c); 296 case '~': 297 case '|': 298 case '&': 299 if ( opt('s') ) { 300 yyset(); 301 standard(); 302 yerror("%c is non-standard", (char *) c); 303 } 304 return c; 305 default: 306 switch (c) { 307 case YDOTDOT: 308 return (c); 309 case '\n': 310 c = readch(); 311 #ifdef PXP 312 yytokcnt++; 313 #endif 314 goto next; 315 case '\f': 316 c = readch(); 317 goto next; 318 } 319 if (c <= 0) 320 return (YEOF); 321 illch: 322 do 323 yysavc = readch(); 324 while (yysavc == c); 325 yylval = c; 326 return (YILLCH); 327 } 328 } 329 330 yyset() 331 { 332 333 yyecol = yycol; 334 yyeline = yyline; 335 yyefile = filename; 336 yyseekp = yylinpt; 337 } 338 339 /* 340 * Setuflg trims the current 341 * input line to at most 72 chars 342 * for the u option. 343 */ 344 setuflg() 345 { 346 347 if (charbuf[71] != '\n') { 348 charbuf[72] = '\n'; 349 charbuf[73] = 0; 350 } 351 } 352