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