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