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