|
|
1.1 root 1: #ifndef lint
2: static char *sccsid ="@(#)scan.c 2.4 (Berkeley) 4/22/87";
3: #endif lint
4:
5: # include "pass1.h"
6: # include <a.out.h>
7: # include <stab.h>
8: # include <ctype.h>
9: # include <signal.h>
10:
11: /* temporarily */
12:
13: int asm_esc = 0; /* asm escaped used in file */
14: /* lexical actions */
15:
16: # define A_ERR 0 /* illegal character */
17: # define A_LET 1 /* saw a letter */
18: # define A_DIG 2 /* saw a digit */
19: # define A_1C 3 /* return a single character */
20: # define A_STR 4 /* string */
21: # define A_CC 5 /* character constant */
22: # define A_BCD 6 /* GCOS BCD constant */
23: # define A_SL 7 /* saw a / */
24: # define A_DOT 8 /* saw a . */
25: # define A_PL 9 /* + */
26: # define A_MI 10 /* - */
27: # define A_EQ 11 /* = */
28: # define A_NOT 12 /* ! */
29: # define A_LT 13 /* < */
30: # define A_GT 14 /* > */
31: # define A_AND 16 /* & */
32: # define A_OR 17 /* | */
33: # define A_WS 18 /* whitespace (not \n) */
34: # define A_NL 19 /* \n */
35:
36: /* character classes */
37:
38: # define LEXLET 01
39: # define LEXDIG 02
40: # define LEXOCT 04
41: # define LEXHEX 010
42: # define LEXWS 020
43: # define LEXDOT 040
44:
45: /* reserved word actions */
46:
47: # define AR_TY 0 /* type word */
48: # define AR_RW 1 /* simple reserved word */
49: # define AR_CL 2 /* storage class word */
50: # define AR_S 3 /* struct */
51: # define AR_U 4 /* union */
52: # define AR_E 5 /* enum */
53: # define AR_A 6 /* asm */
54:
55: /* text buffer */
56: #ifndef FLEXNAMES
57: # define LXTSZ 100
58: #else
59: #define LXTSZ BUFSIZ
60: #endif
61: char yytext[LXTSZ];
62: char * lxgcp;
63:
64: extern int proflg;
65: extern int gdebug;
66: extern int fpe();
67: struct sigvec fpe_sigvec;
68: int oldway; /* allocate storage so lint will compile as well */
69: #ifndef LINT
70: extern int lastloc;
71: #endif
72:
73: unsigned caloff();
74: /* ARGSUSED */
75: mainp1( argc, argv ) int argc; char *argv[]; { /* control multiple files */
76:
77: register i;
78: register char *cp;
79: extern int idebug, bdebug, tdebug, edebug;
80: extern int ddebug, xdebug, gdebug, adebug;
81: extern unsigned int offsz;
82: int fdef = 0;
83: extern char *release;
84:
85: offsz = caloff();
86: for( i=1; i<argc; ++i ){
87: if( *(cp=argv[i]) == '-' && *++cp == 'X' ){
88: while( *++cp ){
89: switch( *cp ){
90:
91: case 'r':
92: fprintf( stderr, "Release: %s\n",
93: release );
94: break;
95:
96: case 'd':
97: ++ddebug;
98: break;
99: case 'i':
100: ++idebug;
101: break;
102: case 'b':
103: ++bdebug;
104: break;
105: case 't':
106: ++tdebug;
107: break;
108: case 'e':
109: ++edebug;
110: break;
111: case 'x':
112: ++xdebug;
113: break;
114: case 'P': /* profiling */
115: ++proflg;
116: break;
117: case 'g':
118: ++gdebug;
119: break;
120: case 'a':
121: ++adebug;
122: break;
123: case 'G':
124: ++gdebug;
125: oldway = 1;
126: break;
127: }
128: }
129: }
130: else {
131: if( *(argv[i]) != '-' ) switch( fdef++ ) {
132: case 0:
133: case 1:
134: if( freopen(argv[i], fdef==1 ? "r" : "w", fdef==1 ? stdin : stdout) == NULL) {
135: fprintf(stderr, "ccom:can't open %s\n", argv[i]);
136: exit(1);
137: }
138: break;
139:
140: default:
141: ;
142: }
143: }
144: }
145:
146: # ifdef ONEPASS
147: p2init( argc, argv );
148: # endif
149:
150: for( i=0; i<SYMTSZ; ++i ) stab[i].stype = TNULL;
151:
152: lineno = 1;
153:
154: lxinit();
155: tinit();
156: mkdope();
157:
158: /* dimension table initialization */
159:
160: dimtab[NULL] = 0;
161: dimtab[CHAR] = SZCHAR;
162: dimtab[INT] = SZINT;
163: dimtab[FLOAT] = SZFLOAT;
164: dimtab[DOUBLE] = SZDOUBLE;
165: dimtab[LONG] = SZLONG;
166: dimtab[SHORT] = SZSHORT;
167: dimtab[UCHAR] = SZCHAR;
168: dimtab[USHORT] = SZSHORT;
169: dimtab[UNSIGNED] = SZINT;
170: dimtab[ULONG] = SZLONG;
171: /* starts past any of the above */
172: curdim = 16;
173: reached = 1;
174:
175: fpe_sigvec.sv_handler = fpe;
176: (void) sigvec(SIGFPE, &fpe_sigvec, (struct sigvec *) NULL);
177:
178: yyparse();
179: yyaccpt();
180:
181: ejobcode( nerrors ? 1 : 0 );
182: return(nerrors?1:0);
183:
184: }
185:
186: # ifdef ibm
187:
188: # define CSMASK 0377
189: # define CSSZ 256
190:
191: # else
192:
193: # define CSMASK 0177
194: # define CSSZ 128
195:
196: # endif
197:
198: short lxmask[CSSZ+1];
199:
200: lxenter( s, m ) register char *s; register short m; {
201: /* enter a mask into lxmask */
202: register c;
203:
204: while( c= *s++ ) lxmask[c+1] |= m;
205:
206: }
207:
208:
209: # define lxget(c,m) (lxgcp=yytext,lxmore(c,m))
210:
211: lxmore( c, m ) register c, m; {
212: register char *cp;
213:
214: *(cp = lxgcp) = c;
215: while( c=getchar(), lxmask[c+1]&m ){
216: if( cp < &yytext[LXTSZ-1] ){
217: *++cp = c;
218: }
219: }
220: ungetc(c,stdin);
221: *(lxgcp = cp+1) = '\0';
222: }
223:
224: struct lxdope {
225: short lxch; /* the character */
226: short lxact; /* the action to be performed */
227: short lxtok; /* the token number to be returned */
228: short lxval; /* the value to be returned */
229: } lxdope[] = {
230:
231: '@', A_ERR, 0, 0, /* illegal characters go here... */
232: '_', A_LET, 0, 0, /* letters point here */
233: '0', A_DIG, 0, 0, /* digits point here */
234: ' ', A_WS, 0, 0, /* whitespace goes here */
235: '\n', A_NL, 0, 0,
236: '"', A_STR, 0, 0, /* character string */
237: '\'', A_CC, 0, 0, /* character constant */
238: '`', A_BCD, 0, 0, /* GCOS BCD constant */
239: '(', A_1C, LP, 0,
240: ')', A_1C, RP, 0,
241: '{', A_1C, LC, 0,
242: '}', A_1C, RC, 0,
243: '[', A_1C, LB, 0,
244: ']', A_1C, RB, 0,
245: '*', A_1C, MUL, MUL,
246: '?', A_1C, QUEST, 0,
247: ':', A_1C, COLON, 0,
248: '+', A_PL, PLUS, PLUS,
249: '-', A_MI, MINUS, MINUS,
250: '/', A_SL, DIVOP, DIV,
251: '%', A_1C, DIVOP, MOD,
252: '&', A_AND, AND, AND,
253: '|', A_OR, OR, OR,
254: '^', A_1C, ER, ER,
255: '!', A_NOT, UNOP, NOT,
256: '~', A_1C, UNOP, COMPL,
257: ',', A_1C, CM, CM,
258: ';', A_1C, SM, 0,
259: '.', A_DOT, STROP, DOT,
260: '<', A_LT, RELOP, LT,
261: '>', A_GT, RELOP, GT,
262: '=', A_EQ, ASSIGN, ASSIGN,
263: -1, A_1C, 0, 0,
264: };
265:
266: struct lxdope *lxcp[CSSZ+1];
267:
268: lxinit(){
269: register struct lxdope *p;
270: register i;
271: register char *cp;
272: /* set up character classes */
273:
274: lxenter( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$", LEXLET );
275: lxenter( "0123456789", LEXDIG );
276: lxenter( "0123456789abcdefABCDEF", LEXHEX );
277: /* \013 should become \v someday; \013 is OK for ASCII and EBCDIC */
278: lxenter( " \t\r\b\f\013", LEXWS );
279: lxenter( "01234567", LEXOCT );
280: lxmask['.'+1] |= LEXDOT;
281:
282: /* make lxcp point to appropriate lxdope entry for each character */
283:
284: /* initialize error entries */
285:
286: for( i= 0; i<=CSSZ; ++i ) lxcp[i] = lxdope;
287:
288: /* make unique entries */
289:
290: for( p=lxdope; ; ++p ) {
291: lxcp[p->lxch+1] = p;
292: if( p->lxch < 0 ) break;
293: }
294:
295: /* handle letters, digits, and whitespace */
296: /* by convention, first, second, and third places */
297:
298: cp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$";
299: while( *cp ) lxcp[*cp++ + 1] = &lxdope[1];
300: cp = "123456789";
301: while( *cp ) lxcp[*cp++ + 1] = &lxdope[2];
302: cp = "\t\b\r\f\013";
303: while( *cp ) lxcp[*cp++ + 1] = &lxdope[3];
304:
305: /* first line might have title */
306: lxtitle();
307:
308: }
309:
310: int lxmatch; /* character to be matched in char or string constant */
311:
312: lxstr(ct){
313: /* match a string or character constant, up to lxmatch */
314:
315: register c;
316: register val;
317: register i;
318:
319: i=0;
320: while( (c=getchar()) != lxmatch ){
321: switch( c ) {
322:
323: case EOF:
324: uerror( "unexpected EOF" );
325: break;
326:
327: case '\n':
328: uerror( "newline in string or char constant" );
329: ++lineno;
330: break;
331:
332: case '\\':
333: switch( c = getchar() ){
334:
335: case '\n':
336: ++lineno;
337: continue;
338:
339: default:
340: if (hflag)
341: uerror("superfluous backslash in string/character constant");
342: /*FALLTHROUGH*/
343: case '\\':
344: case '\"':
345: case '\'':
346: val = c;
347: goto mkcc;
348:
349: case 'n':
350: val = '\n';
351: goto mkcc;
352:
353: case 'r':
354: val = '\r';
355: goto mkcc;
356:
357: case 'b':
358: val = '\b';
359: goto mkcc;
360:
361: case 't':
362: val = '\t';
363: goto mkcc;
364:
365: case 'f':
366: val = '\f';
367: goto mkcc;
368:
369: case 'v':
370: val = '\013';
371: goto mkcc;
372:
373: case '0':
374: case '1':
375: case '2':
376: case '3':
377: case '4':
378: case '5':
379: case '6':
380: case '7':
381: val = c-'0';
382: c=getchar(); /* try for 2 */
383: if( lxmask[c+1] & LEXOCT ){
384: val = (val<<3) | (c-'0');
385: c = getchar(); /* try for 3 */
386: if( lxmask[c+1] & LEXOCT ){
387: val = (val<<3) | (c-'0');
388: }
389: else ungetc( c ,stdin);
390: }
391: else ungetc( c ,stdin);
392:
393: goto mkcc1;
394:
395: }
396: default:
397: val =c;
398: mkcc:
399: val = CCTRANS(val);
400: mkcc1:
401: if( lxmatch == '\'' ){
402: val = CHARCAST(val); /* it is, after all, a "character" constant */
403: makecc( val, i );
404: }
405: else { /* stash the byte into the string */
406: if( strflg ) {
407: if( ct==0 || i<ct ) putbyte( val );
408: else if( i == ct ) werror( "non-null byte ignored in string initializer" );
409: }
410: else bycode( val, i );
411: }
412: ++i;
413: continue;
414: }
415: break;
416: }
417: /* end of string or char constant */
418:
419: if( lxmatch == '"' ){
420: if( strflg ){ /* end the string */
421: if( ct==0 || i<ct ) putbyte( 0 ); /* the null at the end */
422: }
423: else { /* the initializer gets a null byte */
424: bycode( 0, i++ );
425: bycode( -1, i );
426: dimtab[curdim] = i; /* in case of later sizeof ... */
427: }
428: }
429: else { /* end the character constant */
430: if( i == 0 ) uerror( "empty character constant" );
431: if( i>(SZINT/SZCHAR) || ( (pflag||hflag)&&i>1) )
432: uerror( "too many characters in character constant" );
433: }
434: }
435:
436: lxcom(){
437: register c;
438: /* saw a /*: process a comment */
439:
440: for(;;){
441:
442: switch( c = getchar() ){
443:
444: case EOF:
445: uerror( "unexpected EOF" );
446: return;
447:
448: case '\n':
449: ++lineno;
450:
451: default:
452: continue;
453:
454: case '*':
455: if( (c = getchar()) == '/' ) return;
456: else ungetc( c ,stdin);
457: continue;
458:
459: # ifdef LINT
460: case 'V':
461: lxget( c, LEXLET|LEXDIG );
462: {
463: extern int vaflag;
464: int i;
465: i = yytext[7]?yytext[7]-'0':0;
466: yytext[7] = '\0';
467: if( strcmp( yytext, "VARARGS" ) ) continue;
468: vaflag = i;
469: continue;
470: }
471: case 'L':
472: lxget( c, LEXLET );
473: if( strcmp( yytext, "LINTLIBRARY" ) ) continue;
474: {
475: extern int libflag;
476: libflag = 1;
477: }
478: continue;
479:
480: case 'A':
481: lxget( c, LEXLET );
482: if( strcmp( yytext, "ARGSUSED" ) ) continue;
483: {
484: extern int argflag, vflag;
485: argflag = 1;
486: vflag = 0;
487: }
488: continue;
489:
490: case 'N':
491: lxget( c, LEXLET );
492: if( strcmp( yytext, "NOTREACHED" ) ) continue;
493: reached = 0;
494: continue;
495: # endif
496: }
497: }
498: }
499:
500: yylex(){
501: for(;;){
502:
503: register lxchar;
504: register struct lxdope *p;
505: register struct symtab *sp;
506: int id;
507:
508: switch( (p=lxcp[(lxchar=getchar())+1])->lxact ){
509:
510: onechar:
511: ungetc( lxchar ,stdin);
512:
513: case A_1C:
514: /* eat up a single character, and return an opcode */
515:
516: yylval.intval = p->lxval;
517: return( p->lxtok );
518:
519: case A_ERR:
520: uerror( "illegal character: %03o (octal)", lxchar );
521: break;
522:
523: case A_LET:
524: /* collect an identifier, check for reserved word, and return */
525: lxget( lxchar, LEXLET|LEXDIG );
526: if( (lxchar=lxres()) > 0 ) return( lxchar ); /* reserved word */
527: if( lxchar== 0 ) continue;
528: #ifdef FLEXNAMES
529: id = lookup( hash(yytext),
530: #else
531: id = lookup( yytext,
532: #endif
533: /* tag name for struct/union/enum */
534: (stwart&TAGNAME)? STAG:
535: /* member name for struct/union */
536: (stwart&(INSTRUCT|INUNION|FUNNYNAME))?SMOS:0 );
537: sp = &stab[id];
538: if( sp->sclass == TYPEDEF && !stwart ){
539: stwart = instruct;
540: yylval.nodep = mkty( sp->stype, sp->dimoff, sp->sizoff );
541: return( TYPE );
542: }
543: stwart = (stwart&SEENAME) ? instruct : 0;
544: yylval.intval = id;
545: return( NAME );
546:
547: case A_DIG:
548: /* collect a digit string, then look at last one... */
549: lastcon = 0;
550: lxget( lxchar, LEXDIG );
551: switch( lxchar=getchar() ){
552:
553: case 'x':
554: case 'X':
555: if( yytext[0] != '0' && !yytext[1] ) uerror( "illegal hex constant" );
556: lxmore( lxchar, LEXHEX );
557: /* convert the value */
558: {
559: register char *cp;
560: for( cp = yytext+2; *cp; ++cp ){
561: /* this code won't work for all wild character sets,
562: but seems ok for ascii and ebcdic */
563: lastcon <<= 4;
564: if( isdigit( *cp ) ) lastcon += *cp-'0';
565: else if( isupper( *cp ) ) lastcon += *cp - 'A'+ 10;
566: else lastcon += *cp - 'a'+ 10;
567: }
568: }
569:
570: hexlong:
571: /* criterion for longness for hex and octal constants is that it
572: fit within 0177777 */
573: if( lastcon & ~0177777L ) yylval.intval = 1;
574: else yylval.intval = 0;
575:
576: goto islong;
577:
578: case '.':
579: lxmore( lxchar, LEXDIG );
580:
581: getfp:
582: if( (lxchar=getchar()) == 'e' || lxchar == 'E' ){ /* exponent */
583:
584: case 'e':
585: case 'E':
586: if( (lxchar=getchar()) == '+' || lxchar == '-' ){
587: *lxgcp++ = 'e';
588: }
589: else {
590: ungetc(lxchar,stdin);
591: lxchar = 'e';
592: }
593: lxmore( lxchar, LEXDIG );
594: /* now have the whole thing... */
595: }
596: else { /* no exponent */
597: ungetc( lxchar ,stdin);
598: }
599: return( isitfloat( yytext ) );
600:
601: default:
602: ungetc( lxchar ,stdin);
603: if( yytext[0] == '0' ){
604: /* convert in octal */
605: register char *cp;
606: for( cp = yytext+1; *cp; ++cp ){
607: lastcon <<= 3;
608: lastcon += *cp - '0';
609: }
610: goto hexlong;
611: }
612: else {
613: /* convert in decimal */
614: register char *cp;
615: for( cp = yytext; *cp; ++cp ){
616: lastcon = lastcon * 10 + *cp - '0';
617: }
618: }
619:
620: /* decide if it is long or not (decimal case) */
621:
622: /* if it is positive and fits in 15 bits, or negative and
623: and fits in 15 bits plus an extended sign, it is int; otherwise long */
624: /* if there is an l or L following, all bets are off... */
625:
626: { CONSZ v;
627: v = lastcon & ~077777L;
628: if( v == 0 || v == ~077777L ) yylval.intval = 0;
629: else yylval.intval = 1;
630: }
631:
632: islong:
633: /* finally, look for trailing L or l */
634: if( (lxchar = getchar()) == 'L' || lxchar == 'l' ) yylval.intval = 1;
635: else ungetc( lxchar ,stdin);
636: return( ICON );
637: }
638:
639: case A_DOT:
640: /* look for a dot: if followed by a digit, floating point */
641: lxchar = getchar();
642: if( lxmask[lxchar+1] & LEXDIG ){
643: ungetc(lxchar,stdin);
644: lxget( '.', LEXDIG );
645: goto getfp;
646: }
647: stwart = FUNNYNAME;
648: goto onechar;
649:
650: case A_STR:
651: /* string constant */
652: lxmatch = '"';
653: return( STRING );
654:
655: case A_CC:
656: /* character constant */
657: lxmatch = '\'';
658: lastcon = 0;
659: lxstr(0);
660: yylval.intval = 0;
661: return( ICON );
662:
663: case A_BCD:
664: {
665: register i;
666: int j;
667: for( i=0; i<LXTSZ; ++i ){
668: if( ( j = getchar() ) == '`' ) break;
669: if( j == '\n' ){
670: uerror( "newline in BCD constant" );
671: break;
672: }
673: yytext[i] = j;
674: }
675: yytext[i] = '\0';
676: if( i>6 ) uerror( "BCD constant exceeds 6 characters" );
677: # ifdef gcos
678: else strtob( yytext, &lastcon, i );
679: lastcon >>= 6*(6-i);
680: # else
681: uerror( "gcos BCD constant illegal" );
682: # endif
683: yylval.intval = 0; /* not long */
684: return( ICON );
685: }
686:
687: case A_SL:
688: /* / */
689: if( (lxchar=getchar()) != '*' ) goto onechar;
690: lxcom();
691: case A_WS:
692: continue;
693:
694: case A_NL:
695: ++lineno;
696: lxtitle();
697: continue;
698:
699: case A_NOT:
700: /* ! */
701: if( (lxchar=getchar()) != '=' ) goto onechar;
702: yylval.intval = NE;
703: return( EQUOP );
704:
705: case A_MI:
706: /* - */
707: if( (lxchar=getchar()) == '-' ){
708: yylval.intval = DECR;
709: return( INCOP );
710: }
711: if( lxchar != '>' ) goto onechar;
712: stwart = FUNNYNAME;
713: yylval.intval=STREF;
714: return( STROP );
715:
716: case A_PL:
717: /* + */
718: if( (lxchar=getchar()) != '+' ) goto onechar;
719: yylval.intval = INCR;
720: return( INCOP );
721:
722: case A_AND:
723: /* & */
724: if( (lxchar=getchar()) != '&' ) goto onechar;
725: return( yylval.intval = ANDAND );
726:
727: case A_OR:
728: /* | */
729: if( (lxchar=getchar()) != '|' ) goto onechar;
730: return( yylval.intval = OROR );
731:
732: case A_LT:
733: /* < */
734: if( (lxchar=getchar()) == '<' ){
735: yylval.intval = LS;
736: return( SHIFTOP );
737: }
738: if( lxchar != '=' ) goto onechar;
739: yylval.intval = LE;
740: return( RELOP );
741:
742: case A_GT:
743: /* > */
744: if( (lxchar=getchar()) == '>' ){
745: yylval.intval = RS;
746: return(SHIFTOP );
747: }
748: if( lxchar != '=' ) goto onechar;
749: yylval.intval = GE;
750: return( RELOP );
751:
752: case A_EQ:
753: /* = */
754: switch( lxchar = getchar() ){
755:
756: case '=':
757: yylval.intval = EQ;
758: return( EQUOP );
759:
760: case '+':
761: yylval.intval = ASG PLUS;
762: break;
763:
764: case '-':
765: yylval.intval = ASG MINUS;
766:
767: warn:
768: if( lxmask[ (lxchar=getchar())+1] & (LEXLET|LEXDIG|LEXDOT) ){
769: werror( "ambiguous assignment: assignment op taken" );
770: }
771: ungetc( lxchar ,stdin);
772: break;
773:
774: case '*':
775: yylval.intval = ASG MUL;
776: goto warn;
777:
778: case '/':
779: yylval.intval = ASG DIV;
780: break;
781:
782: case '%':
783: yylval.intval = ASG MOD;
784: break;
785:
786: case '&':
787: yylval.intval = ASG AND;
788: break;
789:
790: case '|':
791: yylval.intval = ASG OR;
792: break;
793:
794: case '^':
795: yylval.intval = ASG ER;
796: break;
797:
798: case '<':
799: if( (lxchar=getchar()) != '<' ){
800: uerror( "=<%c illegal", lxchar );
801: }
802: yylval.intval = ASG LS;
803: break;
804:
805: case '>':
806: if( (lxchar=getchar()) != '>' ){
807: uerror( "=>%c illegal", lxchar );
808: }
809: yylval.intval = ASG RS;
810: break;
811:
812: default:
813: goto onechar;
814:
815: }
816:
817: return( ASOP );
818:
819: default:
820: cerror( "yylex error, character %03o (octal)", lxchar );
821:
822: }
823:
824: /* ordinarily, repeat here... */
825: cerror( "out of switch in yylex" );
826:
827: }
828:
829: }
830:
831: struct lxrdope {
832: /* dope for reserved, in alphabetical order */
833:
834: char *lxrch; /* name of reserved word */
835: short lxract; /* reserved word action */
836: short lxrval; /* value to be returned */
837: } lxrdope[] = {
838:
839: "asm", AR_A, 0,
840: "auto", AR_CL, AUTO,
841: "break", AR_RW, BREAK,
842: "char", AR_TY, CHAR,
843: "case", AR_RW, CASE,
844: "continue", AR_RW, CONTINUE,
845: "double", AR_TY, DOUBLE,
846: "default", AR_RW, DEFAULT,
847: "do", AR_RW, DO,
848: "extern", AR_CL, EXTERN,
849: "else", AR_RW, ELSE,
850: "enum", AR_E, ENUM,
851: "for", AR_RW, FOR,
852: "float", AR_TY, FLOAT,
853: "fortran", AR_CL, FORTRAN,
854: "goto", AR_RW, GOTO,
855: "if", AR_RW, IF,
856: "int", AR_TY, INT,
857: "long", AR_TY, LONG,
858: "return", AR_RW, RETURN,
859: "register", AR_CL, REGISTER,
860: "switch", AR_RW, SWITCH,
861: "struct", AR_S, 0,
862: "sizeof", AR_RW, SIZEOF,
863: "short", AR_TY, SHORT,
864: "static", AR_CL, STATIC,
865: "typedef", AR_CL, TYPEDEF,
866: "unsigned", AR_TY, UNSIGNED,
867: "union", AR_U, 0,
868: "void", AR_TY, UNDEF, /* tymerge adds FTN */
869: "while", AR_RW, WHILE,
870: "", 0, 0, /* to stop the search */
871: };
872:
873: lxres() {
874: /* check to see of yytext is reserved; if so,
875: /* do the appropriate action and return */
876: /* otherwise, return -1 */
877:
878: register c, ch;
879: register struct lxrdope *p;
880:
881: ch = yytext[0];
882:
883: if( !islower(ch) ) return( -1 );
884:
885: switch( ch ){
886:
887: case 'a':
888: c=0; break;
889: case 'b':
890: c=2; break;
891: case 'c':
892: c=3; break;
893: case 'd':
894: c=6; break;
895: case 'e':
896: c=9; break;
897: case 'f':
898: c=12; break;
899: case 'g':
900: c=15; break;
901: case 'i':
902: c=16; break;
903: case 'l':
904: c=18; break;
905: case 'r':
906: c=19; break;
907: case 's':
908: c=21; break;
909: case 't':
910: c=26; break;
911: case 'u':
912: c=27; break;
913: case 'v':
914: c=29; break;
915: case 'w':
916: c=30; break;
917:
918: default:
919: return( -1 );
920: }
921:
922: for( p= lxrdope+c; p->lxrch[0] == ch; ++p ){
923: if( !strcmp( yytext, p->lxrch ) ){ /* match */
924: switch( p->lxract ){
925:
926: case AR_TY:
927: /* type word */
928: stwart = instruct;
929: yylval.nodep = mkty( (TWORD)p->lxrval, 0, p->lxrval );
930: return( TYPE );
931:
932: case AR_RW:
933: {
934: extern int nsizeof;
935:
936: if (p->lxrval == SIZEOF)
937: ++nsizeof;
938: }
939: /* ordinary reserved word */
940: return( yylval.intval = p->lxrval );
941:
942: case AR_CL:
943: /* class word */
944: yylval.intval = p->lxrval;
945: return( CLASS );
946:
947: case AR_S:
948: /* struct */
949: stwart = INSTRUCT|SEENAME|TAGNAME;
950: yylval.intval = INSTRUCT;
951: return( STRUCT );
952:
953: case AR_U:
954: /* union */
955: stwart = INUNION|SEENAME|TAGNAME;
956: yylval.intval = INUNION;
957: return( STRUCT );
958:
959: case AR_E:
960: /* enums */
961: stwart = SEENAME|TAGNAME;
962: return( yylval.intval = ENUM );
963:
964: case AR_A:
965: /* asm */
966: asm_esc = 1; /* warn the world! */
967: lxget( ' ', LEXWS );
968: if( getchar() != '(' ) goto badasm;
969: lxget( ' ', LEXWS );
970: if( getchar() != '"' ) goto badasm;
971: # ifndef ONEPASS
972: # ifndef LINT
973: putchar(')');
974: # endif
975: # endif
976: while( (c=getchar()) != '"' ){
977: if( c=='\n' || c==EOF ) goto badasm;
978: # ifndef LINT
979: putchar(c);
980: # endif
981: }
982: lxget( ' ', LEXWS );
983: if( getchar() != ')' ) goto badasm;
984: # ifndef LINT
985: putchar('\n');
986: # endif
987: return( 0 );
988:
989: badasm:
990: uerror( "bad asm construction" );
991: return( 0 );
992:
993: default:
994: cerror( "bad AR_?? action" );
995: }
996: }
997: }
998: return( -1 );
999: }
1000:
1001: extern int labelno;
1002:
1003: lxtitle(){
1004: /* called after a newline; set linenumber and file name */
1005:
1006: register c, val;
1007: register char *cp, *cq;
1008:
1009: for(;;){ /* might be several such lines in a row */
1010: if( (c=getchar()) != '#' ){
1011: if( c != EOF ) ungetc(c,stdin);
1012: #ifndef LINT
1013: if ( lastloc != PROG) return;
1014: cp = ftitle;
1015: cq = ititle;
1016: while ( *cp ) if (*cp++ != *cq++) return;
1017: if ( *cq ) return;
1018: psline();
1019: #endif
1020: return;
1021: }
1022:
1023: lxget( ' ', LEXWS );
1024: val = 0;
1025: for( c=getchar(); isdigit(c); c=getchar() ){
1026: val = val*10+ c - '0';
1027: }
1028: if( c == EOF )
1029: continue;
1030: ungetc( c, stdin );
1031: lineno = val;
1032: lxget( ' ', LEXWS );
1033: if( (c=getchar()) != '\n' && c != EOF ){
1034: for( cp=ftitle; c!=EOF && c!='\n'; c=getchar(),++cp ){
1035: *cp = c;
1036: }
1037: *cp = '\0';
1038: #ifndef LINT
1039: if (ititle[0] == '\0') {
1040: cp = ftitle;
1041: cq = ititle;
1042: while ( *cp )
1043: *cq++ = *cp++;
1044: *cq = '\0';
1045: *--cq = '\0';
1046: #ifndef FLEXNAMES
1047: for ( cp = ititle+1; *(cp-1); cp += 8 ) {
1048: pstab(cp, N_SO);
1049: if (gdebug) printf("0,0,LL%d\n", labelno);
1050: }
1051: #else
1052: pstab(ititle+1, N_SO);
1053: if (gdebug) printf("0,0,LL%d\n", labelno);
1054: #endif
1055:
1056: *cq = '"';
1057: printf("LL%d:\n", labelno++);
1058: }
1059: #endif
1060: }
1061: }
1062: }
1063:
1064: #ifdef FLEXNAMES
1065: #define NSAVETAB 4096
1066: char *savetab;
1067: int saveleft;
1068:
1069: char *
1070: savestr(cp)
1071: register char *cp;
1072: {
1073: register int len;
1074:
1075: len = strlen(cp) + 1;
1076: if (len > saveleft) {
1077: saveleft = NSAVETAB;
1078: if (len > saveleft)
1079: saveleft = len;
1080: savetab = (char *)malloc(saveleft);
1081: if (savetab == 0)
1082: cerror("Ran out of memory (savestr)");
1083: }
1084: strncpy(savetab, cp, len);
1085: cp = savetab;
1086: savetab += len;
1087: saveleft -= len;
1088: return (cp);
1089: }
1090:
1091: /*
1092: * The definition for the segmented hash tables.
1093: */
1094: #define MAXHASH 20
1095: #define HASHINC 1013
1096: struct ht {
1097: char **ht_low;
1098: char **ht_high;
1099: int ht_used;
1100: } htab[MAXHASH];
1101:
1102: char *
1103: hash(s)
1104: char *s;
1105: {
1106: register char **h;
1107: register i;
1108: register char *cp;
1109: struct ht *htp;
1110: int sh;
1111:
1112: /*
1113: * The hash function is a modular hash of
1114: * the sum of the characters with the sum
1115: * doubled before each successive character
1116: * is added.
1117: */
1118: cp = s;
1119: i = 0;
1120: while (*cp)
1121: i = i*2 + *cp++;
1122: sh = (i&077777) % HASHINC;
1123: cp = s;
1124: /*
1125: * There are as many as MAXHASH active
1126: * hash tables at any given point in time.
1127: * The search starts with the first table
1128: * and continues through the active tables
1129: * as necessary.
1130: */
1131: for (htp = htab; htp < &htab[MAXHASH]; htp++) {
1132: if (htp->ht_low == 0) {
1133: register char **hp =
1134: (char **) calloc(sizeof (char **), HASHINC);
1135: if (hp == 0)
1136: cerror("ran out of memory (hash)");
1137: htp->ht_low = hp;
1138: htp->ht_high = htp->ht_low + HASHINC;
1139: }
1140: h = htp->ht_low + sh;
1141: /*
1142: * quadratic rehash increment
1143: * starts at 1 and incremented
1144: * by two each rehash.
1145: */
1146: i = 1;
1147: do {
1148: if (*h == 0) {
1149: if (htp->ht_used > (HASHINC * 3)/4)
1150: break;
1151: htp->ht_used++;
1152: *h = savestr(cp);
1153: return (*h);
1154: }
1155: if (**h == *cp && strcmp(*h, cp) == 0)
1156: return (*h);
1157: h += i;
1158: i += 2;
1159: if (h >= htp->ht_high)
1160: h -= HASHINC;
1161: } while (i < HASHINC);
1162: }
1163: cerror("ran out of hash tables");
1164: }
1165: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.