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