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