|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982 Regents of the University of California ! 3: */ ! 4: #ifndef lint ! 5: static char sccsid[] = "@(#)asscan2.c 4.14 7/6/83"; ! 6: #endif not lint ! 7: ! 8: #include "asscanl.h" ! 9: ! 10: static inttoktype oval = NL; ! 11: #define ASINBUFSIZ 4096 ! 12: char inbufunget[8]; ! 13: char inbuffer[ASINBUFSIZ]; ! 14: char *Ginbufptr = inbuffer; ! 15: int Ginbufcnt = 0; ! 16: int scannerhadeof; ! 17: ! 18: fillinbuffer() ! 19: { ! 20: int nread; ! 21: int goal; ! 22: int got; ! 23: ! 24: nread = 0; ! 25: if (scannerhadeof == 0){ ! 26: goal = sizeof(inbuffer); ! 27: do { ! 28: got = read(stdin->_file, inbuffer + nread, goal); ! 29: if (got == 0) ! 30: scannerhadeof = 1; ! 31: if (got <= 0) ! 32: break; ! 33: nread += got; ! 34: goal -= got; ! 35: } while (goal); ! 36: } else { ! 37: scannerhadeof = 0; ! 38: } ! 39: /* ! 40: * getchar assumes that Ginbufcnt and Ginbufptr ! 41: * are adjusted as if one character has been removed ! 42: * from the input. ! 43: */ ! 44: if (nread == 0){ ! 45: inbuffer[0] = EOFCHAR; ! 46: nread = 1; ! 47: } ! 48: Ginbufcnt = nread - 1; ! 49: Ginbufptr = inbuffer + 1; ! 50: } ! 51: ! 52: scan_dot_s(bufferbox) ! 53: struct tokbufdesc *bufferbox; ! 54: { ! 55: reg char *inbufptr; ! 56: reg int inbufcnt; ! 57: reg int ryylval; /* local copy of lexical value */ ! 58: extern int yylval; /* global copy of lexical value */ ! 59: reg int val; /* the value returned */ ! 60: int i; /* simple counter */ ! 61: reg char *rcp; ! 62: int ch; /* treated as a character */ ! 63: int ch1; /* shadow value */ ! 64: struct symtab *op; ! 65: reg ptrall bufptr; /* where to stuff tokens */ ! 66: ptrall bufub; /* where not to stuff tokens */ ! 67: long intval; /* value of int */ ! 68: int linescrossed; /* when doing strings and comments */ ! 69: u_char opstruct; ! 70: reg int strlg; /* the length of a string */ ! 71: ! 72: (bytetoktype *)bufptr = (bytetoktype *) & (bufferbox->toks[0]); ! 73: (bytetoktype *)bufub = &(bufferbox->toks[AVAILTOKS]); ! 74: ! 75: MEMTOREGBUF; ! 76: if (newfflag){ ! 77: newfflag = 0; ! 78: ryylval = (int)savestr(newfname, strlen(newfname)+1, STR_BOTH); ! 79: ! 80: ptoken(bufptr, IFILE); ! 81: ptoken(bufptr, STRING); ! 82: pptr(bufptr, ryylval); ! 83: ! 84: ptoken(bufptr, ILINENO); ! 85: ptoken(bufptr, INT); ! 86: pint(bufptr, 1); ! 87: } ! 88: ! 89: while (bufptr < bufub){ ! 90: loop: ! 91: switch(ryylval = (type+1)[ch = getchar()]) { ! 92: case SCANEOF: ! 93: endoffile: ; ! 94: inbufptr = 0; ! 95: ptoken(bufptr, PARSEEOF); ! 96: goto done; ! 97: ! 98: case DIV: /*process C style comments*/ ! 99: if ( (ch = getchar()) == '*') { /*comment prelude*/ ! 100: int incomment; ! 101: linescrossed = 0; ! 102: incomment = 1; ! 103: ch = getchar(); /*skip over the * */ ! 104: while(incomment){ ! 105: switch(ch){ ! 106: case '*': ! 107: ch = getchar(); ! 108: incomment = (ch != '/'); ! 109: break; ! 110: case '\n': ! 111: scanlineno++; ! 112: linescrossed++; ! 113: ch = getchar(); ! 114: break; ! 115: case EOFCHAR: ! 116: goto endoffile; ! 117: default: ! 118: ch = getchar(); ! 119: break; ! 120: } ! 121: } ! 122: val = ILINESKIP; ! 123: ryylval = linescrossed; ! 124: goto ret; ! 125: } else { /*just an ordinary DIV*/ ! 126: ungetc(ch); ! 127: val = ryylval = DIV; ! 128: goto ret; ! 129: } ! 130: case SH: ! 131: if (oval == NL){ ! 132: /* ! 133: * Attempt to recognize a C preprocessor ! 134: * style comment '^#[ \t]*[0-9]*[ \t]*".*" ! 135: */ ! 136: ch = getchar(); /*bump the #*/ ! 137: while (INCHARSET(ch, SPACE)) ! 138: ch = getchar();/*bump white */ ! 139: if (INCHARSET(ch, DIGIT)){ ! 140: intval = 0; ! 141: while(INCHARSET(ch, DIGIT)){ ! 142: intval = intval*10 + ch - '0'; ! 143: ch = getchar(); ! 144: } ! 145: while (INCHARSET(ch, SPACE)) ! 146: ch = getchar(); ! 147: if (ch == '"' || ch == '\n'){ ! 148: ptoken(bufptr, ILINENO); ! 149: ptoken(bufptr, INT); ! 150: pint(bufptr, intval - 1); ! 151: if (ch == '"') ! 152: { ! 153: ptoken(bufptr, IFILE); ! 154: /* ! 155: * The '"' has already been ! 156: * munched ! 157: * ! 158: * eatstr will not eat ! 159: * the trailing \n, so ! 160: * it is given to the parser ! 161: * and counted. ! 162: */ ! 163: goto eatstr; ! 164: } ! 165: } ! 166: } ! 167: } ! 168: /* ! 169: * Well, its just an ordinary decadent comment ! 170: */ ! 171: while ((ch != '\n') && (ch != EOFCHAR)) ! 172: ch = getchar(); ! 173: if (ch == EOFCHAR) ! 174: goto endoffile; ! 175: val = ryylval = oval = NL; ! 176: scanlineno++; ! 177: goto ret; ! 178: ! 179: case NL: ! 180: scanlineno++; ! 181: val = ryylval; ! 182: goto ret; ! 183: ! 184: case SP: ! 185: oval = SP; /*invalidate ^# meta comments*/ ! 186: goto loop; ! 187: ! 188: case REGOP: /* % , could be used as modulo, or register*/ ! 189: ch = getchar(); ! 190: if (INCHARSET(ch, DIGIT)){ ! 191: ryylval = ch-'0'; ! 192: if (ch=='1') { ! 193: if (INCHARSET( (ch = getchar()), REGDIGIT)) ! 194: ryylval = 10+ch-'0'; ! 195: else ! 196: ungetc(ch); ! 197: } ! 198: /* ! 199: * God only knows what the original author ! 200: * wanted this undocumented feature to ! 201: * do. ! 202: * %5++ is really r7 ! 203: */ ! 204: while(INCHARSET( (ch = getchar()), SIGN)) { ! 205: if (ch=='+') ! 206: ryylval++; ! 207: else ! 208: ryylval--; ! 209: } ! 210: ungetc(ch); ! 211: val = REG; ! 212: } else { ! 213: ungetc(ch); ! 214: val = REGOP; ! 215: } ! 216: goto ret; ! 217: ! 218: case ALPH: ! 219: ch1 = ch; ! 220: if (INCHARSET(ch, SZSPECBEGIN)){ ! 221: if( (ch = getchar()) == '`' || ch == '^'){ ! 222: ch1 |= 0100; /*convert to lower*/ ! 223: switch(ch1){ ! 224: case 'b': ryylval = 1; break; ! 225: case 'w': ryylval = 2; break; ! 226: case 'l': ryylval = 4; break; ! 227: default: ryylval = d124; break; ! 228: } ! 229: val = SIZESPEC; ! 230: goto ret; ! 231: } else { ! 232: ungetc(ch); ! 233: ch = ch1; /*restore first character*/ ! 234: } ! 235: } ! 236: rcp = yytext; ! 237: do { ! 238: if (rcp < &yytext[NCPName]) ! 239: *rcp++ = ch; ! 240: } while (INCHARSET ( (ch = getchar()), ALPHA | DIGIT)); ! 241: *rcp = '\0'; ! 242: while (INCHARSET(ch, SPACE)) ! 243: ch = getchar(); ! 244: ungetc(ch); ! 245: ! 246: switch((op = *lookup(1))->s_tag){ ! 247: case 0: ! 248: case LABELID: ! 249: /* ! 250: * Its a name... (Labels are subsets of name) ! 251: */ ! 252: ryylval = (int)op; ! 253: val = NAME; ! 254: break; ! 255: case INST0: ! 256: case INSTn: ! 257: case IJXXX: ! 258: opstruct = ( (struct instab *)op)->i_opcode; ! 259: val = op->s_tag; ! 260: break; ! 261: default: ! 262: ryylval = ( (struct instab *)op)->i_opcode; ! 263: val = op->s_tag; ! 264: break; ! 265: } ! 266: goto ret; ! 267: ! 268: case DIG: ! 269: /* ! 270: * restore local inbufptr and inbufcnt ! 271: */ ! 272: REGTOMEMBUF; ! 273: val = number(ch); ! 274: MEMTOREGBUF; ! 275: /* ! 276: * yylval or yybignum has been stuffed as a side ! 277: * effect to number(); get the global yylval ! 278: * into our fast local copy in case it was an INT. ! 279: */ ! 280: ryylval = yylval; ! 281: goto ret; ! 282: ! 283: case LSH: ! 284: case RSH: ! 285: /* ! 286: * We allow the C style operators ! 287: * << and >>, as well as < and > ! 288: */ ! 289: if ( (ch1 = getchar()) != ch) ! 290: ungetc(ch1); ! 291: val = ryylval; ! 292: goto ret; ! 293: ! 294: case MINUS: ! 295: if ( (ch = getchar()) =='(') ! 296: ryylval=val=MP; ! 297: else { ! 298: ungetc(ch); ! 299: val=MINUS; ! 300: } ! 301: goto ret; ! 302: ! 303: case SQ: ! 304: if ((ryylval = getchar()) == '\n') ! 305: scanlineno++; /*not entirely correct*/ ! 306: val = INT; ! 307: goto ret; ! 308: ! 309: case DQ: ! 310: eatstr: ! 311: linescrossed = 0; ! 312: for (strlg = 0; /*VOID*/; strlg++){ ! 313: switch(ch = getchar()){ ! 314: case '"': ! 315: goto tailDQ; ! 316: default: ! 317: stuff: ! 318: putc(ch, strfile); ! 319: break; ! 320: case '\n': ! 321: yywarning("New line in a string constant"); ! 322: scanlineno++; ! 323: linescrossed++; ! 324: ch = getchar(); ! 325: switch(ch){ ! 326: case EOFCHAR: ! 327: putc('\n', strfile); ! 328: ungetc(EOFCHAR); ! 329: goto tailDQ; ! 330: default: ! 331: ungetc(ch); ! 332: ch = '\n'; ! 333: goto stuff; ! 334: } ! 335: break; ! 336: ! 337: case '\\': ! 338: ch = getchar(); /*skip the '\\'*/ ! 339: if ( INCHARSET(ch, BSESCAPE)){ ! 340: switch (ch){ ! 341: case 'b': ch = '\b'; goto stuff; ! 342: case 'f': ch = '\f'; goto stuff; ! 343: case 'n': ch = '\n'; goto stuff; ! 344: case 'r': ch = '\r'; goto stuff; ! 345: case 't': ch = '\t'; goto stuff; ! 346: } ! 347: } ! 348: if ( !(INCHARSET(ch, OCTDIGIT)) ) ! 349: goto stuff; ! 350: i = 0; ! 351: intval = 0; ! 352: while ( (i < 3) && (INCHARSET(ch, OCTDIGIT))){ ! 353: i++; ! 354: intval <<= 3; ! 355: intval += ch - '0'; ! 356: ch = getchar(); ! 357: } ! 358: ungetc(ch); ! 359: ch = (char)intval; ! 360: goto stuff; ! 361: } ! 362: } ! 363: tailDQ: ; ! 364: /* ! 365: * account for any lines that were crossed ! 366: */ ! 367: if (linescrossed){ ! 368: ptoken(bufptr, ILINESKIP); ! 369: pint(bufptr, linescrossed); ! 370: } ! 371: /* ! 372: * Cheat: append a trailing null to the string ! 373: * and then adjust the string length to ignore ! 374: * the trailing null. If any STRING client requires ! 375: * the trailing null, the client can just change STRLEN ! 376: */ ! 377: putc(0, strfile); ! 378: ryylval = (int)savestr((char *)0, strlg + 1, STR_FILE); ! 379: val = STRING; ! 380: ((struct strdesc *)ryylval)->sd_strlen -= 1; ! 381: goto ret; ! 382: ! 383: case BADCHAR: ! 384: linescrossed = lineno; ! 385: lineno = scanlineno; ! 386: yyerror("Illegal character mapped: %d, char read:(octal) %o", ! 387: ryylval, ch); ! 388: lineno = linescrossed; ! 389: val = BADCHAR; ! 390: goto ret; ! 391: ! 392: default: ! 393: val = ryylval; ! 394: goto ret; ! 395: } /*end of the switch*/ ! 396: /* ! 397: * here with one token, so stuff it ! 398: */ ! 399: ret: ! 400: oval = val; ! 401: ptoken(bufptr, val); ! 402: switch(val){ ! 403: case ILINESKIP: ! 404: pint(bufptr, ryylval); ! 405: break; ! 406: case SIZESPEC: ! 407: pchar(bufptr, ryylval); ! 408: break; ! 409: case BFINT: plong(bufptr, ryylval); ! 410: break; ! 411: case INT: plong(bufptr, ryylval); ! 412: break; ! 413: case BIGNUM: pnumber(bufptr, yybignum); ! 414: break; ! 415: case STRING: pptr(bufptr, (int)(char *)ryylval); ! 416: break; ! 417: case NAME: pptr(bufptr, (int)(struct symtab *)ryylval); ! 418: break; ! 419: case REG: pchar(bufptr, ryylval); ! 420: break; ! 421: case INST0: ! 422: case INSTn: ! 423: popcode(bufptr, opstruct); ! 424: break; ! 425: case IJXXX: ! 426: popcode(bufptr, opstruct); ! 427: pptr(bufptr, (int)(struct symtab *)symalloc()); ! 428: break; ! 429: case ISTAB: ! 430: case ISTABSTR: ! 431: case ISTABNONE: ! 432: case ISTABDOT: ! 433: case IALIGN: ! 434: pptr(bufptr, (int)(struct symtab *)symalloc()); ! 435: break; ! 436: /* ! 437: * default: ! 438: */ ! 439: } ! 440: builtval: ; ! 441: } /*end of the while to stuff the buffer*/ ! 442: done: ! 443: bufferbox->tok_count = (bytetoktype *)bufptr - &(bufferbox->toks[0]); ! 444: /* ! 445: * This is a real kludge: ! 446: * ! 447: * We put the last token in the buffer to be a MINUS ! 448: * symbol. This last token will never be picked up ! 449: * in the normal way, but can be looked at during ! 450: * a peekahead look that the short circuit expression ! 451: * evaluator uses to see if an expression is complicated. ! 452: * ! 453: * Consider the following situation: ! 454: * ! 455: * .word 45 + 47 ! 456: * buffer 1 | buffer 0 ! 457: * the peekahead would want to look across the buffer, ! 458: * but will look in the buffer end zone, see the minus, and ! 459: * fail. ! 460: */ ! 461: ptoken(bufptr, MINUS); ! 462: REGTOMEMBUF; ! 463: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.