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