|
|
1.1 ! root 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[] = "@(#)lex.c 5.4 (Berkeley) 5/10/89"; ! 9: #endif not lint ! 10: ! 11: /* ! 12: * lex.c ! 13: * ! 14: * Lexical scanner routines for the f77 compiler, pass 1, 4.2 BSD. ! 15: * ! 16: * University of Utah CS Dept modification history: ! 17: * ! 18: * $Log: lex.c,v $ ! 19: * Revision 5.4 86/01/07 14:01:13 donn ! 20: * Fix the scanning for character constants in gettok() so that it handles ! 21: * the case when an error has occurred and there is no closing quote. ! 22: * ! 23: * Revision 5.3 85/11/25 00:24:06 donn ! 24: * 4.3 beta ! 25: * ! 26: * Revision 5.2 85/08/10 04:45:41 donn ! 27: * Jerry Berkman's changes to ifdef 66 code and handle -r8/double flag. ! 28: * ! 29: * Revision 5.1 85/08/10 03:48:20 donn ! 30: * 4.3 alpha ! 31: * ! 32: * Revision 1.2 84/10/27 02:20:09 donn ! 33: * Fixed bug where the input file and the name field of the include file ! 34: * structure shared -- when the input file name was freed, the include file ! 35: * name got stomped on, leading to peculiar error messages. ! 36: * ! 37: */ ! 38: ! 39: #include "defs.h" ! 40: #include "tokdefs.h" ! 41: #include "pathnames.h" ! 42: ! 43: # define BLANK ' ' ! 44: # define MYQUOTE (2) ! 45: # define SEOF 0 ! 46: ! 47: /* card types */ ! 48: ! 49: # define STEOF 1 ! 50: # define STINITIAL 2 ! 51: # define STCONTINUE 3 ! 52: ! 53: /* lex states */ ! 54: ! 55: #define NEWSTMT 1 ! 56: #define FIRSTTOKEN 2 ! 57: #define OTHERTOKEN 3 ! 58: #define RETEOS 4 ! 59: ! 60: ! 61: LOCAL int stkey; ! 62: LOCAL int lastend = 1; ! 63: ftnint yystno; ! 64: flag intonly; ! 65: LOCAL long int stno; ! 66: LOCAL long int nxtstno; ! 67: LOCAL int parlev; ! 68: LOCAL int expcom; ! 69: LOCAL int expeql; ! 70: LOCAL char *nextch; ! 71: LOCAL char *lastch; ! 72: LOCAL char *nextcd = NULL; ! 73: LOCAL char *endcd; ! 74: LOCAL int prevlin; ! 75: LOCAL int thislin; ! 76: LOCAL int code; ! 77: LOCAL int lexstate = NEWSTMT; ! 78: LOCAL char s[1390]; ! 79: LOCAL char *send = s+20*66; ! 80: LOCAL int nincl = 0; ! 81: LOCAL char *newname = NULL; ! 82: ! 83: struct Inclfile ! 84: { ! 85: struct Inclfile *inclnext; ! 86: FILEP inclfp; ! 87: char *inclname; ! 88: int incllno; ! 89: char *incllinp; ! 90: int incllen; ! 91: int inclcode; ! 92: ftnint inclstno; ! 93: } ; ! 94: ! 95: LOCAL struct Inclfile *inclp = NULL; ! 96: LOCAL struct Keylist { char *keyname; int keyval; char notinf66; } ; ! 97: LOCAL struct Punctlist { char punchar; int punval; }; ! 98: LOCAL struct Fmtlist { char fmtchar; int fmtval; }; ! 99: LOCAL struct Dotlist { char *dotname; int dotval; }; ! 100: LOCAL struct Keylist *keystart[26], *keyend[26]; ! 101: ! 102: ! 103: ! 104: ! 105: inilex(name) ! 106: char *name; ! 107: { ! 108: nincl = 0; ! 109: inclp = NULL; ! 110: doinclude(name); ! 111: lexstate = NEWSTMT; ! 112: return(NO); ! 113: } ! 114: ! 115: ! 116: ! 117: /* throw away the rest of the current line */ ! 118: flline() ! 119: { ! 120: lexstate = RETEOS; ! 121: } ! 122: ! 123: ! 124: ! 125: char *lexline(n) ! 126: int *n; ! 127: { ! 128: *n = (lastch - nextch) + 1; ! 129: return(nextch); ! 130: } ! 131: ! 132: ! 133: ! 134: ! 135: ! 136: doinclude(name) ! 137: char *name; ! 138: { ! 139: FILEP fp; ! 140: struct Inclfile *t; ! 141: char temp[100]; ! 142: register char *lastslash, *s; ! 143: ! 144: if(inclp) ! 145: { ! 146: inclp->incllno = thislin; ! 147: inclp->inclcode = code; ! 148: inclp->inclstno = nxtstno; ! 149: if(nextcd) ! 150: inclp->incllinp = copyn(inclp->incllen = endcd-nextcd , nextcd); ! 151: else ! 152: inclp->incllinp = 0; ! 153: } ! 154: nextcd = NULL; ! 155: ! 156: if(++nincl >= MAXINCLUDES) ! 157: fatal("includes nested too deep"); ! 158: if(name[0] == '\0') ! 159: fp = stdin; ! 160: else if(name[0]=='/' || inclp==NULL) ! 161: fp = fopen(name, "r"); ! 162: else { ! 163: lastslash = NULL; ! 164: for(s = inclp->inclname ; *s ; ++s) ! 165: if(*s == '/') ! 166: lastslash = s; ! 167: if(lastslash) ! 168: { ! 169: *lastslash = '\0'; ! 170: sprintf(temp, "%s/%s", inclp->inclname, name); ! 171: *lastslash = '/'; ! 172: } ! 173: else ! 174: strcpy(temp, name); ! 175: ! 176: if( (fp = fopen(temp, "r")) == NULL ) ! 177: { ! 178: sprintf(temp, "%s/%s", _PATH_INCLUDES, name); ! 179: fp = fopen(temp, "r"); ! 180: } ! 181: if(fp) ! 182: name = copys(temp); ! 183: } ! 184: ! 185: if( fp ) ! 186: { ! 187: t = inclp; ! 188: inclp = ALLOC(Inclfile); ! 189: inclp->inclnext = t; ! 190: prevlin = thislin = 0; ! 191: inclp->inclname = name; ! 192: infname = copys(name); ! 193: infile = inclp->inclfp = fp; ! 194: } ! 195: else ! 196: { ! 197: fprintf(diagfile, "Cannot open file %s", name); ! 198: done(1); ! 199: } ! 200: } ! 201: ! 202: ! 203: ! 204: ! 205: LOCAL popinclude() ! 206: { ! 207: struct Inclfile *t; ! 208: register char *p; ! 209: register int k; ! 210: ! 211: if(infile != stdin) ! 212: clf(&infile); ! 213: free(infname); ! 214: ! 215: --nincl; ! 216: t = inclp->inclnext; ! 217: free(inclp->inclname); ! 218: free( (charptr) inclp); ! 219: inclp = t; ! 220: if(inclp == NULL) ! 221: return(NO); ! 222: ! 223: infile = inclp->inclfp; ! 224: infname = copys(inclp->inclname); ! 225: prevlin = thislin = inclp->incllno; ! 226: code = inclp->inclcode; ! 227: stno = nxtstno = inclp->inclstno; ! 228: if(inclp->incllinp) ! 229: { ! 230: endcd = nextcd = s; ! 231: k = inclp->incllen; ! 232: p = inclp->incllinp; ! 233: while(--k >= 0) ! 234: *endcd++ = *p++; ! 235: free( (charptr) (inclp->incllinp) ); ! 236: } ! 237: else ! 238: nextcd = NULL; ! 239: return(YES); ! 240: } ! 241: ! 242: ! 243: ! 244: ! 245: yylex() ! 246: { ! 247: static int tokno; ! 248: ! 249: switch(lexstate) ! 250: { ! 251: case NEWSTMT : /* need a new statement */ ! 252: if(getcds() == STEOF) ! 253: return(SEOF); ! 254: lastend = stkey == SEND; ! 255: crunch(); ! 256: tokno = 0; ! 257: lexstate = FIRSTTOKEN; ! 258: yystno = stno; ! 259: stno = nxtstno; ! 260: toklen = 0; ! 261: return(SLABEL); ! 262: ! 263: first: ! 264: case FIRSTTOKEN : /* first step on a statement */ ! 265: analyz(); ! 266: lexstate = OTHERTOKEN; ! 267: tokno = 1; ! 268: return(stkey); ! 269: ! 270: case OTHERTOKEN : /* return next token */ ! 271: if(nextch > lastch) ! 272: goto reteos; ! 273: ++tokno; ! 274: if( (stkey==SLOGIF || stkey==SELSEIF) && parlev==0 && tokno>3) ! 275: goto first; ! 276: ! 277: if(stkey==SASSIGN && tokno==3 && nextch<lastch && ! 278: nextch[0]=='t' && nextch[1]=='o') ! 279: { ! 280: nextch+=2; ! 281: return(STO); ! 282: } ! 283: return(gettok()); ! 284: ! 285: reteos: ! 286: case RETEOS: ! 287: lexstate = NEWSTMT; ! 288: return(SEOS); ! 289: } ! 290: fatali("impossible lexstate %d", lexstate); ! 291: /* NOTREACHED */ ! 292: } ! 293: ! 294: LOCAL getcds() ! 295: { ! 296: register char *p, *q; ! 297: ! 298: if (newname) ! 299: { ! 300: free(infname); ! 301: infname = newname; ! 302: newname = NULL; ! 303: } ! 304: ! 305: top: ! 306: if(nextcd == NULL) ! 307: { ! 308: code = getcd( nextcd = s ); ! 309: stno = nxtstno; ! 310: if (newname) ! 311: { ! 312: free(infname); ! 313: infname = newname; ! 314: newname = NULL; ! 315: } ! 316: prevlin = thislin; ! 317: } ! 318: if(code == STEOF) ! 319: if( popinclude() ) ! 320: goto top; ! 321: else ! 322: return(STEOF); ! 323: ! 324: if(code == STCONTINUE) ! 325: { ! 326: if (newname) ! 327: { ! 328: free(infname); ! 329: infname = newname; ! 330: newname = NULL; ! 331: } ! 332: lineno = thislin; ! 333: err("illegal continuation card ignored"); ! 334: nextcd = NULL; ! 335: goto top; ! 336: } ! 337: ! 338: if(nextcd > s) ! 339: { ! 340: q = nextcd; ! 341: p = s; ! 342: while(q < endcd) ! 343: *p++ = *q++; ! 344: endcd = p; ! 345: } ! 346: for(nextcd = endcd ; ! 347: nextcd+66<=send && (code = getcd(nextcd))==STCONTINUE ; ! 348: nextcd = endcd ) ! 349: ; ! 350: nextch = s; ! 351: lastch = nextcd - 1; ! 352: if(nextcd >= send) ! 353: nextcd = NULL; ! 354: lineno = prevlin; ! 355: prevlin = thislin; ! 356: return(STINITIAL); ! 357: } ! 358: ! 359: LOCAL getcd(b) ! 360: register char *b; ! 361: { ! 362: register int c; ! 363: register char *p, *bend; ! 364: int speclin; ! 365: static char a[6]; ! 366: static char *aend = a+6; ! 367: int num; ! 368: ! 369: top: ! 370: endcd = b; ! 371: bend = b+66; ! 372: speclin = NO; ! 373: ! 374: if( (c = getc(infile)) == '&') ! 375: { ! 376: a[0] = BLANK; ! 377: a[5] = 'x'; ! 378: speclin = YES; ! 379: bend = send; ! 380: } ! 381: else if(c=='c' || c=='C' || c=='*') ! 382: { ! 383: while( (c = getc(infile)) != '\n') ! 384: if(c == EOF) ! 385: return(STEOF); ! 386: ++thislin; ! 387: goto top; ! 388: } ! 389: else if(c == '#') ! 390: { ! 391: c = getc(infile); ! 392: while (c == BLANK || c == '\t') ! 393: c = getc(infile); ! 394: ! 395: num = 0; ! 396: while (isdigit(c)) ! 397: { ! 398: num = 10*num + c - '0'; ! 399: c = getc(infile); ! 400: } ! 401: thislin = num - 1; ! 402: ! 403: while (c == BLANK || c == '\t') ! 404: c = getc(infile); ! 405: ! 406: if (c == '"') ! 407: { ! 408: char fname[1024]; ! 409: int len = 0; ! 410: ! 411: c = getc(infile); ! 412: while (c != '"' && c != '\n') ! 413: { ! 414: fname[len++] = c; ! 415: c = getc(infile); ! 416: } ! 417: fname[len++] = '\0'; ! 418: ! 419: if (newname) ! 420: free(newname); ! 421: newname = (char *) ckalloc(len); ! 422: strcpy(newname, fname); ! 423: } ! 424: ! 425: while (c != '\n') ! 426: if (c == EOF) ! 427: return (STEOF); ! 428: else ! 429: c = getc(infile); ! 430: goto top; ! 431: } ! 432: ! 433: else if(c != EOF) ! 434: { ! 435: /* a tab in columns 1-6 skips to column 7 */ ! 436: ungetc(c, infile); ! 437: for(p=a; p<aend && (c=getc(infile)) != '\n' && c!=EOF; ) ! 438: if(c == '\t') ! 439: { ! 440: while(p < aend) ! 441: *p++ = BLANK; ! 442: speclin = YES; ! 443: bend = send; ! 444: } ! 445: else ! 446: *p++ = c; ! 447: } ! 448: if(c == EOF) ! 449: return(STEOF); ! 450: if(c == '\n') ! 451: { ! 452: while(p < aend) ! 453: *p++ = BLANK; ! 454: if( ! speclin ) ! 455: while(endcd < bend) ! 456: *endcd++ = BLANK; ! 457: } ! 458: else { /* read body of line */ ! 459: while( endcd<bend && (c=getc(infile)) != '\n' && c!=EOF ) ! 460: *endcd++ = c; ! 461: if(c == EOF) ! 462: return(STEOF); ! 463: if(c != '\n') ! 464: { ! 465: while( (c=getc(infile)) != '\n') ! 466: if(c == EOF) ! 467: return(STEOF); ! 468: } ! 469: ! 470: if( ! speclin ) ! 471: while(endcd < bend) ! 472: *endcd++ = BLANK; ! 473: } ! 474: ++thislin; ! 475: if( !isspace(a[5]) && a[5]!='0') ! 476: return(STCONTINUE); ! 477: for(p=a; p<aend; ++p) ! 478: if( !isspace(*p) ) goto initline; ! 479: for(p = b ; p<endcd ; ++p) ! 480: if( !isspace(*p) ) goto initline; ! 481: goto top; ! 482: ! 483: initline: ! 484: nxtstno = 0; ! 485: for(p = a ; p<a+5 ; ++p) ! 486: if( !isspace(*p) ) ! 487: if(isdigit(*p)) ! 488: nxtstno = 10*nxtstno + (*p - '0'); ! 489: else { ! 490: if (newname) ! 491: { ! 492: free(infname); ! 493: infname = newname; ! 494: newname = NULL; ! 495: } ! 496: lineno = thislin; ! 497: err("nondigit in statement number field"); ! 498: nxtstno = 0; ! 499: break; ! 500: } ! 501: return(STINITIAL); ! 502: } ! 503: ! 504: LOCAL crunch() ! 505: { ! 506: register char *i, *j, *j0, *j1, *prvstr; ! 507: int ten, nh, quote; ! 508: ! 509: /* i is the next input character to be looked at ! 510: j is the next output character */ ! 511: parlev = 0; ! 512: expcom = 0; /* exposed ','s */ ! 513: expeql = 0; /* exposed equal signs */ ! 514: j = s; ! 515: prvstr = s; ! 516: for(i=s ; i<=lastch ; ++i) ! 517: { ! 518: if(isspace(*i) ) ! 519: continue; ! 520: if(*i=='\'' || *i=='"') ! 521: { ! 522: quote = *i; ! 523: *j = MYQUOTE; /* special marker */ ! 524: for(;;) ! 525: { ! 526: if(++i > lastch) ! 527: { ! 528: err("unbalanced quotes; closing quote supplied"); ! 529: break; ! 530: } ! 531: if(*i == quote) ! 532: if(i<lastch && i[1]==quote) ++i; ! 533: else break; ! 534: else if(*i=='\\' && i<lastch) ! 535: switch(*++i) ! 536: { ! 537: case 't': ! 538: *i = '\t'; break; ! 539: case 'b': ! 540: *i = '\b'; break; ! 541: case 'n': ! 542: *i = '\n'; break; ! 543: case 'f': ! 544: *i = '\f'; break; ! 545: case 'v': ! 546: *i = '\v'; break; ! 547: case '0': ! 548: *i = '\0'; break; ! 549: default: ! 550: break; ! 551: } ! 552: *++j = *i; ! 553: } ! 554: j[1] = MYQUOTE; ! 555: j += 2; ! 556: prvstr = j; ! 557: } ! 558: else if( (*i=='h' || *i=='H') && j>prvstr) /* test for Hollerith strings */ ! 559: { ! 560: if( ! isdigit(j[-1])) goto copychar; ! 561: nh = j[-1] - '0'; ! 562: ten = 10; ! 563: j1 = prvstr - 1; ! 564: if (j1<j-5) j1=j-5; ! 565: for(j0=j-2 ; j0>j1; -- j0) ! 566: { ! 567: if( ! isdigit(*j0 ) ) break; ! 568: nh += ten * (*j0-'0'); ! 569: ten*=10; ! 570: } ! 571: if(j0 <= j1) goto copychar; ! 572: /* a hollerith must be preceded by a punctuation mark. ! 573: '*' is possible only as repetition factor in a data statement ! 574: not, in particular, in character*2h ! 575: */ ! 576: ! 577: if( !(*j0=='*'&&s[0]=='d') && *j0!='/' && *j0!='(' && ! 578: *j0!=',' && *j0!='=' && *j0!='.') ! 579: goto copychar; ! 580: if(i+nh > lastch) ! 581: { ! 582: erri("%dH too big", nh); ! 583: nh = lastch - i; ! 584: } ! 585: j0[1] = MYQUOTE; /* special marker */ ! 586: j = j0 + 1; ! 587: while(nh-- > 0) ! 588: { ! 589: if(*++i == '\\') ! 590: switch(*++i) ! 591: { ! 592: case 't': ! 593: *i = '\t'; break; ! 594: case 'b': ! 595: *i = '\b'; break; ! 596: case 'n': ! 597: *i = '\n'; break; ! 598: case 'f': ! 599: *i = '\f'; break; ! 600: case '0': ! 601: *i = '\0'; break; ! 602: default: ! 603: break; ! 604: } ! 605: *++j = *i; ! 606: } ! 607: j[1] = MYQUOTE; ! 608: j+=2; ! 609: prvstr = j; ! 610: } ! 611: else { ! 612: if(*i == '(') ++parlev; ! 613: else if(*i == ')') --parlev; ! 614: else if(parlev == 0) ! 615: if(*i == '=') expeql = 1; ! 616: else if(*i == ',') expcom = 1; ! 617: copychar: /*not a string or space -- copy, shifting case if necessary */ ! 618: if(shiftcase && isupper(*i)) ! 619: *j++ = tolower(*i); ! 620: else *j++ = *i; ! 621: } ! 622: } ! 623: lastch = j - 1; ! 624: nextch = s; ! 625: } ! 626: ! 627: LOCAL analyz() ! 628: { ! 629: register char *i; ! 630: ! 631: if(parlev != 0) ! 632: { ! 633: err("unbalanced parentheses, statement skipped"); ! 634: stkey = SUNKNOWN; ! 635: return; ! 636: } ! 637: if(nextch+2<=lastch && nextch[0]=='i' && nextch[1]=='f' && nextch[2]=='(') ! 638: { ! 639: /* assignment or if statement -- look at character after balancing paren */ ! 640: parlev = 1; ! 641: for(i=nextch+3 ; i<=lastch; ++i) ! 642: if(*i == (MYQUOTE)) ! 643: { ! 644: while(*++i != MYQUOTE) ! 645: ; ! 646: } ! 647: else if(*i == '(') ! 648: ++parlev; ! 649: else if(*i == ')') ! 650: { ! 651: if(--parlev == 0) ! 652: break; ! 653: } ! 654: if(i >= lastch) ! 655: stkey = SLOGIF; ! 656: else if(i[1] == '=') ! 657: stkey = SLET; ! 658: else if( isdigit(i[1]) ) ! 659: stkey = SARITHIF; ! 660: else stkey = SLOGIF; ! 661: if(stkey != SLET) ! 662: nextch += 2; ! 663: } ! 664: else if(expeql) /* may be an assignment */ ! 665: { ! 666: if(expcom && nextch<lastch && ! 667: nextch[0]=='d' && nextch[1]=='o') ! 668: { ! 669: stkey = SDO; ! 670: nextch += 2; ! 671: } ! 672: else stkey = SLET; ! 673: } ! 674: /* otherwise search for keyword */ ! 675: else { ! 676: stkey = getkwd(); ! 677: if(stkey==SGOTO && lastch>=nextch) ! 678: if(nextch[0]=='(') ! 679: stkey = SCOMPGOTO; ! 680: else if(isalpha(nextch[0])) ! 681: stkey = SASGOTO; ! 682: } ! 683: parlev = 0; ! 684: } ! 685: ! 686: ! 687: ! 688: LOCAL getkwd() ! 689: { ! 690: register char *i, *j; ! 691: register struct Keylist *pk, *pend; ! 692: int k; ! 693: ! 694: if(! isalpha(nextch[0]) ) ! 695: return(SUNKNOWN); ! 696: k = nextch[0] - 'a'; ! 697: if(pk = keystart[k]) ! 698: for(pend = keyend[k] ; pk<=pend ; ++pk ) ! 699: { ! 700: i = pk->keyname; ! 701: j = nextch; ! 702: while(*++i==*++j && *i!='\0') ! 703: ; ! 704: if(*i=='\0' && j<=lastch+1) ! 705: { ! 706: nextch = j; ! 707: #ifdef ONLY66 ! 708: if(no66flag && pk->notinf66) ! 709: errstr("Not a Fortran 66 keyword: %s", ! 710: pk->keyname); ! 711: #endif ! 712: return(pk->keyval); ! 713: } ! 714: } ! 715: return(SUNKNOWN); ! 716: } ! 717: ! 718: ! 719: ! 720: initkey() ! 721: { ! 722: extern struct Keylist keys[]; ! 723: register struct Keylist *p; ! 724: register int i,j; ! 725: ! 726: for(i = 0 ; i<26 ; ++i) ! 727: keystart[i] = NULL; ! 728: ! 729: for(p = keys ; p->keyname ; ++p) ! 730: { ! 731: j = p->keyname[0] - 'a'; ! 732: if(keystart[j] == NULL) ! 733: keystart[j] = p; ! 734: keyend[j] = p; ! 735: } ! 736: } ! 737: ! 738: LOCAL gettok() ! 739: { ! 740: int havdot, havexp, havdbl; ! 741: int radix, val; ! 742: extern struct Punctlist puncts[]; ! 743: struct Punctlist *pp; ! 744: extern struct Fmtlist fmts[]; ! 745: extern struct Dotlist dots[]; ! 746: struct Dotlist *pd; ! 747: ! 748: char *i, *j, *n1, *p; ! 749: ! 750: if(*nextch == (MYQUOTE)) ! 751: { ! 752: ++nextch; ! 753: p = token; ! 754: while(nextch <= lastch && *nextch != MYQUOTE) ! 755: *p++ = *nextch++; ! 756: ++nextch; ! 757: toklen = p - token; ! 758: *p = '\0'; ! 759: return (SHOLLERITH); ! 760: } ! 761: /* ! 762: if(stkey == SFORMAT) ! 763: { ! 764: for(pf = fmts; pf->fmtchar; ++pf) ! 765: { ! 766: if(*nextch == pf->fmtchar) ! 767: { ! 768: ++nextch; ! 769: if(pf->fmtval == SLPAR) ! 770: ++parlev; ! 771: else if(pf->fmtval == SRPAR) ! 772: --parlev; ! 773: return(pf->fmtval); ! 774: } ! 775: } ! 776: if( isdigit(*nextch) ) ! 777: { ! 778: p = token; ! 779: *p++ = *nextch++; ! 780: while(nextch<=lastch && isdigit(*nextch) ) ! 781: *p++ = *nextch++; ! 782: toklen = p - token; ! 783: *p = '\0'; ! 784: if(nextch<=lastch && *nextch=='p') ! 785: { ! 786: ++nextch; ! 787: return(SSCALE); ! 788: } ! 789: else return(SICON); ! 790: } ! 791: if( isalpha(*nextch) ) ! 792: { ! 793: p = token; ! 794: *p++ = *nextch++; ! 795: while(nextch<=lastch && ! 796: (*nextch=='.' || isdigit(*nextch) || isalpha(*nextch) )) ! 797: *p++ = *nextch++; ! 798: toklen = p - token; ! 799: *p = '\0'; ! 800: return(SFIELD); ! 801: } ! 802: goto badchar; ! 803: } ! 804: /* Not a format statement */ ! 805: ! 806: if(needkwd) ! 807: { ! 808: needkwd = 0; ! 809: return( getkwd() ); ! 810: } ! 811: ! 812: for(pp=puncts; pp->punchar; ++pp) ! 813: if(*nextch == pp->punchar) ! 814: { ! 815: if( (*nextch=='*' || *nextch=='/') && ! 816: nextch<lastch && nextch[1]==nextch[0]) ! 817: { ! 818: if(*nextch == '*') ! 819: val = SPOWER; ! 820: else val = SCONCAT; ! 821: nextch+=2; ! 822: } ! 823: else { ! 824: val = pp->punval; ! 825: if(val==SLPAR) ! 826: ++parlev; ! 827: else if(val==SRPAR) ! 828: --parlev; ! 829: ++nextch; ! 830: } ! 831: return(val); ! 832: } ! 833: if(*nextch == '.') ! 834: if(nextch >= lastch) goto badchar; ! 835: else if(isdigit(nextch[1])) goto numconst; ! 836: else { ! 837: for(pd=dots ; (j=pd->dotname) ; ++pd) ! 838: { ! 839: for(i=nextch+1 ; i<=lastch ; ++i) ! 840: if(*i != *j) break; ! 841: else if(*i != '.') ++j; ! 842: else { ! 843: nextch = i+1; ! 844: return(pd->dotval); ! 845: } ! 846: } ! 847: goto badchar; ! 848: } ! 849: if( isalpha(*nextch) ) ! 850: { ! 851: p = token; ! 852: *p++ = *nextch++; ! 853: while(nextch<=lastch) ! 854: if( isalpha(*nextch) || isdigit(*nextch) ) ! 855: *p++ = *nextch++; ! 856: else break; ! 857: toklen = p - token; ! 858: *p = '\0'; ! 859: if(inioctl && nextch<=lastch && *nextch=='=') ! 860: { ! 861: ++nextch; ! 862: return(SNAMEEQ); ! 863: } ! 864: if(toklen>8 && eqn(8,token,"function") && isalpha(token[8]) && ! 865: nextch<lastch && nextch[0]=='(' && ! 866: (nextch[1]==')' | isalpha(nextch[1])) ) ! 867: { ! 868: nextch -= (toklen - 8); ! 869: return(SFUNCTION); ! 870: } ! 871: if(toklen > VL) ! 872: { ! 873: char buff[30]; ! 874: sprintf(buff, "name %s too long, truncated to %d", ! 875: token, VL); ! 876: err(buff); ! 877: toklen = VL; ! 878: token[VL] = '\0'; ! 879: } ! 880: if(toklen==1 && *nextch==MYQUOTE) ! 881: { ! 882: switch(token[0]) ! 883: { ! 884: case 'z': case 'Z': ! 885: case 'x': case 'X': ! 886: radix = 16; break; ! 887: case 'o': case 'O': ! 888: radix = 8; break; ! 889: case 'b': case 'B': ! 890: radix = 2; break; ! 891: default: ! 892: err("bad bit identifier"); ! 893: return(SNAME); ! 894: } ! 895: ++nextch; ! 896: for(p = token ; *nextch!=MYQUOTE ; ) ! 897: if ( *nextch == BLANK || *nextch == '\t') ! 898: nextch++; ! 899: else ! 900: { ! 901: if (isupper(*nextch)) ! 902: *nextch = tolower(*nextch); ! 903: if (hextoi(*p++ = *nextch++) >= radix) ! 904: { ! 905: err("invalid binary character"); ! 906: break; ! 907: } ! 908: } ! 909: ++nextch; ! 910: toklen = p - token; ! 911: return( radix==16 ? SHEXCON : ! 912: (radix==8 ? SOCTCON : SBITCON) ); ! 913: } ! 914: return(SNAME); ! 915: } ! 916: if( ! isdigit(*nextch) ) goto badchar; ! 917: numconst: ! 918: havdot = NO; ! 919: havexp = NO; ! 920: havdbl = NO; ! 921: for(n1 = nextch ; nextch<=lastch ; ++nextch) ! 922: { ! 923: if(*nextch == '.') ! 924: if(havdot) break; ! 925: else if(nextch+2<=lastch && isalpha(nextch[1]) ! 926: && isalpha(nextch[2])) ! 927: break; ! 928: else havdot = YES; ! 929: else if( !intonly && (*nextch=='d' || *nextch=='e') ) ! 930: { ! 931: p = nextch; ! 932: havexp = YES; ! 933: if(*nextch == 'd') ! 934: havdbl = YES; ! 935: if(nextch<lastch) ! 936: if(nextch[1]=='+' || nextch[1]=='-') ! 937: ++nextch; ! 938: if( (nextch >= lastch) || ! isdigit(*++nextch) ) ! 939: { ! 940: nextch = p; ! 941: havdbl = havexp = NO; ! 942: break; ! 943: } ! 944: for(++nextch ; ! 945: nextch<=lastch && isdigit(*nextch); ! 946: ++nextch); ! 947: break; ! 948: } ! 949: else if( ! isdigit(*nextch) ) ! 950: break; ! 951: } ! 952: p = token; ! 953: i = n1; ! 954: while(i < nextch) ! 955: *p++ = *i++; ! 956: toklen = p - token; ! 957: *p = '\0'; ! 958: if(havdbl) return(SDCON); ! 959: if(havdot || havexp) return( dblflag ? SDCON : SRCON); ! 960: return(SICON); ! 961: badchar: ! 962: s[0] = *nextch++; ! 963: return(SUNKNOWN); ! 964: } ! 965: ! 966: /* KEYWORD AND SPECIAL CHARACTER TABLES ! 967: */ ! 968: ! 969: struct Punctlist puncts[ ] = ! 970: { ! 971: '(', SLPAR, ! 972: ')', SRPAR, ! 973: '=', SEQUALS, ! 974: ',', SCOMMA, ! 975: '+', SPLUS, ! 976: '-', SMINUS, ! 977: '*', SSTAR, ! 978: '/', SSLASH, ! 979: '$', SCURRENCY, ! 980: ':', SCOLON, ! 981: 0, 0 } ; ! 982: ! 983: /* ! 984: LOCAL struct Fmtlist fmts[ ] = ! 985: { ! 986: '(', SLPAR, ! 987: ')', SRPAR, ! 988: '/', SSLASH, ! 989: ',', SCOMMA, ! 990: '-', SMINUS, ! 991: ':', SCOLON, ! 992: 0, 0 } ; ! 993: */ ! 994: ! 995: LOCAL struct Dotlist dots[ ] = ! 996: { ! 997: "and.", SAND, ! 998: "or.", SOR, ! 999: "not.", SNOT, ! 1000: "true.", STRUE, ! 1001: "false.", SFALSE, ! 1002: "eq.", SEQ, ! 1003: "ne.", SNE, ! 1004: "lt.", SLT, ! 1005: "le.", SLE, ! 1006: "gt.", SGT, ! 1007: "ge.", SGE, ! 1008: "neqv.", SNEQV, ! 1009: "eqv.", SEQV, ! 1010: 0, 0 } ; ! 1011: ! 1012: LOCAL struct Keylist keys[ ] = ! 1013: { ! 1014: { "assign", SASSIGN }, ! 1015: { "automatic", SAUTOMATIC, YES }, ! 1016: { "backspace", SBACKSPACE }, ! 1017: { "blockdata", SBLOCK }, ! 1018: { "call", SCALL }, ! 1019: { "character", SCHARACTER, YES }, ! 1020: { "close", SCLOSE, YES }, ! 1021: { "common", SCOMMON }, ! 1022: { "complex", SCOMPLEX }, ! 1023: { "continue", SCONTINUE }, ! 1024: { "data", SDATA }, ! 1025: { "dimension", SDIMENSION }, ! 1026: { "doubleprecision", SDOUBLE }, ! 1027: { "doublecomplex", SDCOMPLEX, YES }, ! 1028: { "elseif", SELSEIF, YES }, ! 1029: { "else", SELSE, YES }, ! 1030: { "endfile", SENDFILE }, ! 1031: { "endif", SENDIF, YES }, ! 1032: { "end", SEND }, ! 1033: { "entry", SENTRY, YES }, ! 1034: { "equivalence", SEQUIV }, ! 1035: { "external", SEXTERNAL }, ! 1036: { "format", SFORMAT }, ! 1037: { "function", SFUNCTION }, ! 1038: { "goto", SGOTO }, ! 1039: { "implicit", SIMPLICIT, YES }, ! 1040: { "include", SINCLUDE, YES }, ! 1041: { "inquire", SINQUIRE, YES }, ! 1042: { "intrinsic", SINTRINSIC, YES }, ! 1043: { "integer", SINTEGER }, ! 1044: { "logical", SLOGICAL }, ! 1045: #ifdef NAMELIST ! 1046: { "namelist", SNAMELIST, YES }, ! 1047: #endif ! 1048: { "none", SUNDEFINED, YES }, ! 1049: { "open", SOPEN, YES }, ! 1050: { "parameter", SPARAM, YES }, ! 1051: { "pause", SPAUSE }, ! 1052: { "print", SPRINT }, ! 1053: { "program", SPROGRAM, YES }, ! 1054: { "punch", SPUNCH, YES }, ! 1055: { "read", SREAD }, ! 1056: { "real", SREAL }, ! 1057: { "return", SRETURN }, ! 1058: { "rewind", SREWIND }, ! 1059: { "save", SSAVE, YES }, ! 1060: { "static", SSTATIC, YES }, ! 1061: { "stop", SSTOP }, ! 1062: { "subroutine", SSUBROUTINE }, ! 1063: { "then", STHEN, YES }, ! 1064: { "undefined", SUNDEFINED, YES }, ! 1065: { "write", SWRITE }, ! 1066: { 0, 0 } ! 1067: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.