|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)y2.c 4.1 (Berkeley) 2/11/83";
3: #endif not lint
4:
5: # include "dextern"
6: # define IDENTIFIER 257
7: # define MARK 258
8: # define TERM 259
9: # define LEFT 260
10: # define RIGHT 261
11: # define BINARY 262
12: # define PREC 263
13: # define LCURLY 264
14: # define C_IDENTIFIER 265 /* name followed by colon */
15: # define NUMBER 266
16: # define START 267
17: # define TYPEDEF 268
18: # define TYPENAME 269
19: # define UNION 270
20: # define ENDFILE 0
21:
22: /* communication variables between various I/O routines */
23:
24: char *infile; /* input file name */
25: int numbval; /* value of an input number */
26: char tokname[NAMESIZE]; /* input token name */
27:
28: /* storage of names */
29:
30: char cnames[CNAMSZ]; /* place where token and nonterminal names are stored */
31: int cnamsz = CNAMSZ; /* size of cnames */
32: char * cnamp = cnames; /* place where next name is to be put in */
33: int ndefout = 3; /* number of defined symbols output */
34:
35: /* storage of types */
36: int ntypes; /* number of types defined */
37: char * typeset[NTYPES]; /* pointers to type tags */
38:
39: /* symbol tables for tokens and nonterminals */
40:
41: int ntokens = 0;
42: struct toksymb tokset[NTERMS];
43: int toklev[NTERMS];
44: int nnonter = -1;
45: struct ntsymb nontrst[NNONTERM];
46: int start; /* start symbol */
47:
48: /* assigned token type values */
49: int extval = 0;
50:
51: /* input and output file descriptors */
52:
53: FILE * finput; /* yacc input file */
54: FILE * faction; /* file for saving actions */
55: FILE * fdefine; /* file for # defines */
56: FILE * ftable; /* y.tab.c file */
57: FILE * ftemp; /* tempfile to pass 2 */
58: FILE * foutput; /* y.output file */
59:
60: /* storage for grammar rules */
61:
62: int mem0[MEMSIZE] ; /* production storage */
63: int *mem = mem0;
64: int nprod= 1; /* number of productions */
65: int *prdptr[NPROD]; /* pointers to descriptions of productions */
66: int levprd[NPROD] ; /* precedence levels for the productions */
67:
68:
69: setup(argc,argv) int argc; char *argv[];
70: { int i,j,lev,t, ty;
71: int c;
72: int *p;
73: char actname[8];
74:
75: foutput = NULL;
76: fdefine = NULL;
77: i = 1;
78: while( argc >= 2 && argv[1][0] == '-' ) {
79: while( *++(argv[1]) ){
80: switch( *argv[1] ){
81: case 'v':
82: case 'V':
83: foutput = fopen(FILEU, "w" );
84: if( foutput == NULL ) error( "cannot open y.output" );
85: continue;
86: case 'D':
87: case 'd':
88: fdefine = fopen( FILED, "w" );
89: continue;
90: case 'o':
91: case 'O':
92: fprintf( stderr, "`o' flag now default in yacc\n" );
93: continue;
94:
95: case 'r':
96: case 'R':
97: error( "Ratfor Yacc is dead: sorry...\n" );
98:
99: default:
100: error( "illegal option: %c", *argv[1]);
101: }
102: }
103: argv++;
104: argc--;
105: }
106:
107: ftable = fopen( OFILE, "w" );
108: if( ftable == NULL ) error( "cannot open table file" );
109:
110: ftemp = fopen( TEMPNAME, "w" );
111: faction = fopen( ACTNAME, "w" );
112: if( ftemp==NULL || faction==NULL ) error( "cannot open temp file" );
113:
114: if( argc < 2 || ((finput=fopen( infile=argv[1], "r" )) == NULL ) ){
115: error( "cannot open input file" );
116: }
117:
118: cnamp = cnames;
119: defin(0,"$end");
120: extval = 0400;
121: defin(0,"error");
122: defin(1,"$accept");
123: mem=mem0;
124: lev = 0;
125: ty = 0;
126: i=0;
127:
128: /* sorry -- no yacc parser here.....
129: we must bootstrap somehow... */
130:
131: for( t=gettok(); t!=MARK && t!= ENDFILE; ){
132: switch( t ){
133:
134: case ';':
135: t = gettok();
136: break;
137:
138: case START:
139: if( (t=gettok()) != IDENTIFIER ){
140: error( "bad %%start construction" );
141: }
142: start = chfind(1,tokname);
143: t = gettok();
144: continue;
145:
146: case TYPEDEF:
147: if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" );
148: ty = numbval;
149: for(;;){
150: t = gettok();
151: switch( t ){
152:
153: case IDENTIFIER:
154: if( (t=chfind( 1, tokname ) ) < NTBASE ) {
155: j = TYPE( toklev[t] );
156: if( j!= 0 && j != ty ){
157: error( "type redeclaration of token %s",
158: tokset[t].name );
159: }
160: else SETTYPE( toklev[t],ty);
161: }
162: else {
163: j = nontrst[t-NTBASE].tvalue;
164: if( j != 0 && j != ty ){
165: error( "type redeclaration of nonterminal %s",
166: nontrst[t-NTBASE].name );
167: }
168: else nontrst[t-NTBASE].tvalue = ty;
169: }
170: case ',':
171: continue;
172:
173: case ';':
174: t = gettok();
175: break;
176: default:
177: break;
178: }
179: break;
180: }
181: continue;
182:
183: case UNION:
184: /* copy the union declaration to the output */
185: cpyunion();
186: t = gettok();
187: continue;
188:
189: case LEFT:
190: case BINARY:
191: case RIGHT:
192: ++i;
193: case TERM:
194: lev = t-TERM; /* nonzero means new prec. and assoc. */
195: ty = 0;
196:
197: /* get identifiers so defined */
198:
199: t = gettok();
200: if( t == TYPENAME ){ /* there is a type defined */
201: ty = numbval;
202: t = gettok();
203: }
204:
205: for(;;) {
206: switch( t ){
207:
208: case ',':
209: t = gettok();
210: continue;
211:
212: case ';':
213: break;
214:
215: case IDENTIFIER:
216: j = chfind(0,tokname);
217: if( lev ){
218: if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of %s", tokname );
219: SETASC(toklev[j],lev);
220: SETPLEV(toklev[j],i);
221: }
222: if( ty ){
223: if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname );
224: SETTYPE(toklev[j],ty);
225: }
226: if( (t=gettok()) == NUMBER ){
227: tokset[j].value = numbval;
228: if( j < ndefout && j>2 ){
229: error( "please define type number of %s earlier",
230: tokset[j].name );
231: }
232: t=gettok();
233: }
234: continue;
235:
236: }
237:
238: break;
239: }
240:
241: continue;
242:
243: case LCURLY:
244: defout();
245: cpycode();
246: t = gettok();
247: continue;
248:
249: default:
250: error( "syntax error" );
251:
252: }
253:
254: }
255:
256: if( t == ENDFILE ){
257: error( "unexpected EOF before %%" );
258: }
259:
260: /* t is MARK */
261:
262: defout();
263:
264: fprintf( ftable, "#define yyclearin yychar = -1\n" );
265: fprintf( ftable, "#define yyerrok yyerrflag = 0\n" );
266: fprintf( ftable, "extern int yychar;\nextern short yyerrflag;\n" );
267: fprintf( ftable, "#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
268: if( !ntypes ) fprintf( ftable, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
269: fprintf( ftable, "YYSTYPE yylval, yyval;\n" );
270:
271: prdptr[0]=mem;
272: /* added production */
273: *mem++ = NTBASE;
274: *mem++ = start; /* if start is 0, we will overwrite with the lhs of the first rule */
275: *mem++ = 1;
276: *mem++ = 0;
277: prdptr[1]=mem;
278:
279: while( (t=gettok()) == LCURLY ) cpycode();
280:
281: if( t != C_IDENTIFIER ) error( "bad syntax on first rule" );
282:
283: if( !start ) prdptr[0][1] = chfind(1,tokname);
284:
285: /* read rules */
286:
287: while( t!=MARK && t!=ENDFILE ){
288:
289: /* process a rule */
290:
291: if( t == '|' ){
292: *mem++ = *prdptr[nprod-1];
293: }
294: else if( t == C_IDENTIFIER ){
295: *mem = chfind(1,tokname);
296: if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" );
297: ++mem;
298: }
299: else error( "illegal rule: missing semicolon or | ?" );
300:
301: /* read rule body */
302:
303:
304: t = gettok();
305: more_rule:
306: while( t == IDENTIFIER ) {
307: *mem = chfind(1,tokname);
308: if( *mem<NTBASE ) levprd[nprod] = toklev[*mem];
309: ++mem;
310: t = gettok();
311: }
312:
313:
314: if( t == PREC ){
315: if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" );
316: j = chfind(2,tokname);
317: if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
318: levprd[nprod]=toklev[j];
319: t = gettok();
320: }
321:
322: if( t == '=' ){
323: levprd[nprod] |= ACTFLAG;
324: fprintf( faction, "\ncase %d:", nprod );
325: cpyact( mem-prdptr[nprod]-1 );
326: fprintf( faction, " break;" );
327: if( (t=gettok()) == IDENTIFIER ){
328: /* action within rule... */
329:
330: sprintf( actname, "$$%d", nprod );
331: j = chfind(1,actname); /* make it a nonterminal */
332:
333: /* the current rule will become rule number nprod+1 */
334: /* move the contents down, and make room for the null */
335:
336: for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p;
337: mem += 2;
338:
339: /* enter null production for action */
340:
341: p = prdptr[nprod];
342:
343: *p++ = j;
344: *p++ = -nprod;
345:
346: /* update the production information */
347:
348: levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
349: levprd[nprod] = ACTFLAG;
350:
351: if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
352: prdptr[nprod] = p;
353:
354: /* make the action appear in the original rule */
355: *mem++ = j;
356:
357: /* get some more of the rule */
358:
359: goto more_rule;
360: }
361:
362: }
363:
364: while( t == ';' ) t = gettok();
365:
366: *mem++ = -nprod;
367:
368: /* check that default action is reasonable */
369:
370: if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue ){
371: /* no explicit action, LHS has value */
372: register tempty;
373: tempty = prdptr[nprod][1];
374: if( tempty < 0 ) error( "must return a value, since LHS has a type" );
375: else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue;
376: else tempty = TYPE( toklev[tempty] );
377: if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue ){
378: error( "default action causes potential type clash" );
379: }
380: }
381:
382: if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
383: prdptr[nprod] = mem;
384: levprd[nprod]=0;
385:
386: }
387:
388: /* end of all rules */
389:
390: finact();
391: if( t == MARK ){
392: fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
393: while( (c=getc(finput)) != EOF ) putc( c, ftable );
394: }
395: fclose( finput );
396: }
397:
398: finact(){
399: /* finish action routine */
400:
401: fclose(faction);
402:
403: fprintf( ftable, "# define YYERRCODE %d\n", tokset[2].value );
404:
405: }
406:
407: defin( t, s ) register char *s; {
408: /* define s to be a terminal if t=0
409: or a nonterminal if t=1 */
410:
411: register val;
412:
413: if (t) {
414: if( ++nnonter >= NNONTERM ) error("too many nonterminals, limit %d",NNONTERM);
415: nontrst[nnonter].name = cstash(s);
416: return( NTBASE + nnonter );
417: }
418: /* must be a token */
419: if( ++ntokens >= NTERMS ) error("too many terminals, limit %d",NTERMS );
420: tokset[ntokens].name = cstash(s);
421:
422: /* establish value for token */
423:
424: if( s[0]==' ' && s[2]=='\0' ) /* single character literal */
425: val = s[1];
426: else if ( s[0]==' ' && s[1]=='\\' ) { /* escape sequence */
427: if( s[3] == '\0' ){ /* single character escape sequence */
428: switch ( s[2] ){
429: /* character which is escaped */
430: case 'n': val = '\n'; break;
431: case 'r': val = '\r'; break;
432: case 'b': val = '\b'; break;
433: case 't': val = '\t'; break;
434: case 'f': val = '\f'; break;
435: case '\'': val = '\''; break;
436: case '"': val = '"'; break;
437: case '\\': val = '\\'; break;
438: default: error( "invalid escape" );
439: }
440: }
441: else if( s[2] <= '7' && s[2]>='0' ){ /* \nnn sequence */
442: if( s[3]<'0' || s[3] > '7' || s[4]<'0' ||
443: s[4]>'7' || s[5] != '\0' ) error("illegal \\nnn construction" );
444: val = 64*s[2] + 8*s[3] + s[4] - 73*'0';
445: if( val == 0 ) error( "'\\000' is illegal" );
446: }
447: }
448: else {
449: val = extval++;
450: }
451: tokset[ntokens].value = val;
452: toklev[ntokens] = 0;
453: return( ntokens );
454: }
455:
456: defout(){ /* write out the defines (at the end of the declaration section) */
457:
458: register int i, c;
459: register char *cp;
460:
461: for( i=ndefout; i<=ntokens; ++i ){
462:
463: cp = tokset[i].name;
464: if( *cp == ' ' ) ++cp; /* literals */
465:
466: for( ; (c= *cp)!='\0'; ++cp ){
467:
468: if( islower(c) || isupper(c) || isdigit(c) || c=='_' ); /* VOID */
469: else goto nodef;
470: }
471:
472: fprintf( ftable, "# define %s %d\n", tokset[i].name, tokset[i].value );
473: if( fdefine != NULL ) fprintf( fdefine, "# define %s %d\n", tokset[i].name, tokset[i].value );
474:
475: nodef: ;
476: }
477:
478: ndefout = ntokens+1;
479:
480: }
481:
482: char *
483: cstash( s ) register char *s; {
484: char *temp;
485:
486: temp = cnamp;
487: do {
488: if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" );
489: else *cnamp++ = *s;
490: } while ( *s++ );
491: return( temp );
492: }
493:
494: gettok() {
495: register i, base;
496: static int peekline; /* number of '\n' seen in lookahead */
497: register c, match, reserve;
498:
499: begin:
500: reserve = 0;
501: lineno += peekline;
502: peekline = 0;
503: c = getc(finput);
504: while( c==' ' || c=='\n' || c=='\t' || c=='\f' ){
505: if( c == '\n' ) ++lineno;
506: c=getc(finput);
507: }
508: if( c == '/' ){ /* skip comment */
509: lineno += skipcom();
510: goto begin;
511: }
512:
513: switch(c){
514:
515: case EOF:
516: return(ENDFILE);
517: case '{':
518: ungetc( c, finput );
519: return( '=' ); /* action ... */
520: case '<': /* get, and look up, a type name (union member name) */
521: i = 0;
522: while( (c=getc(finput)) != '>' && c>=0 && c!= '\n' ){
523: tokname[i] = c;
524: if( ++i >= NAMESIZE ) --i;
525: }
526: if( c != '>' ) error( "unterminated < ... > clause" );
527: tokname[i] = '\0';
528: for( i=1; i<=ntypes; ++i ){
529: if( !strcmp( typeset[i], tokname ) ){
530: numbval = i;
531: return( TYPENAME );
532: }
533: }
534: typeset[numbval = ++ntypes] = cstash( tokname );
535: return( TYPENAME );
536:
537: case '"':
538: case '\'':
539: match = c;
540: tokname[0] = ' ';
541: i = 1;
542: for(;;){
543: c = getc(finput);
544: if( c == '\n' || c == EOF )
545: error("illegal or missing ' or \"" );
546: if( c == '\\' ){
547: c = getc(finput);
548: tokname[i] = '\\';
549: if( ++i >= NAMESIZE ) --i;
550: }
551: else if( c == match ) break;
552: tokname[i] = c;
553: if( ++i >= NAMESIZE ) --i;
554: }
555: break;
556:
557: case '%':
558: case '\\':
559:
560: switch(c=getc(finput)) {
561:
562: case '0': return(TERM);
563: case '<': return(LEFT);
564: case '2': return(BINARY);
565: case '>': return(RIGHT);
566: case '%':
567: case '\\': return(MARK);
568: case '=': return(PREC);
569: case '{': return(LCURLY);
570: default: reserve = 1;
571: }
572:
573: default:
574:
575: if( isdigit(c) ){ /* number */
576: numbval = c-'0' ;
577: base = (c=='0') ? 8 : 10 ;
578: for( c=getc(finput); isdigit(c) ; c=getc(finput) ){
579: numbval = numbval*base + c - '0';
580: }
581: ungetc( c, finput );
582: return(NUMBER);
583: }
584: else if( islower(c) || isupper(c) || c=='_' || c=='.' || c=='$' ){
585: i = 0;
586: while( islower(c) || isupper(c) || isdigit(c) || c=='_' || c=='.' || c=='$' ){
587: tokname[i] = c;
588: if( reserve && isupper(c) ) tokname[i] += 'a'-'A';
589: if( ++i >= NAMESIZE ) --i;
590: c = getc(finput);
591: }
592: }
593: else return(c);
594:
595: ungetc( c, finput );
596: }
597:
598: tokname[i] = '\0';
599:
600: if( reserve ){ /* find a reserved word */
601: if( !strcmp(tokname,"term")) return( TERM );
602: if( !strcmp(tokname,"token")) return( TERM );
603: if( !strcmp(tokname,"left")) return( LEFT );
604: if( !strcmp(tokname,"nonassoc")) return( BINARY );
605: if( !strcmp(tokname,"binary")) return( BINARY );
606: if( !strcmp(tokname,"right")) return( RIGHT );
607: if( !strcmp(tokname,"prec")) return( PREC );
608: if( !strcmp(tokname,"start")) return( START );
609: if( !strcmp(tokname,"type")) return( TYPEDEF );
610: if( !strcmp(tokname,"union")) return( UNION );
611: error("invalid escape, or illegal reserved word: %s", tokname );
612: }
613:
614: /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */
615:
616: c = getc(finput);
617: while( c==' ' || c=='\t'|| c=='\n' || c=='\f' || c== '/' ) {
618: if( c == '\n' ) ++peekline;
619: else if( c == '/' ){ /* look for comments */
620: peekline += skipcom();
621: }
622: c = getc(finput);
623: }
624: if( c == ':' ) return( C_IDENTIFIER );
625: ungetc( c, finput );
626: return( IDENTIFIER );
627: }
628:
629: fdtype( t ){ /* determine the type of a symbol */
630: register v;
631: if( t >= NTBASE ) v = nontrst[t-NTBASE].tvalue;
632: else v = TYPE( toklev[t] );
633: if( v <= 0 ) error( "must specify type for %s", (t>=NTBASE)?nontrst[t-NTBASE].name:
634: tokset[t].name );
635: return( v );
636: }
637:
638: chfind( t, s ) register char *s; {
639: int i;
640:
641: if (s[0]==' ')t=0;
642: TLOOP(i){
643: if(!strcmp(s,tokset[i].name)){
644: return( i );
645: }
646: }
647: NTLOOP(i){
648: if(!strcmp(s,nontrst[i].name)) {
649: return( i+NTBASE );
650: }
651: }
652: /* cannot find name */
653: if( t>1 )
654: error( "%s should have been defined earlier", s );
655: return( defin( t, s ) );
656: }
657:
658: cpyunion(){
659: /* copy the union declaration to the output, and the define file if present */
660:
661: int level, c;
662: fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
663: fprintf( ftable, "typedef union " );
664: if( fdefine ) fprintf( fdefine, "\ntypedef union " );
665:
666: level = 0;
667: for(;;){
668: if( (c=getc(finput)) < 0 ) error( "EOF encountered while processing %%union" );
669: putc( c, ftable );
670: if( fdefine ) putc( c, fdefine );
671:
672: switch( c ){
673:
674: case '\n':
675: ++lineno;
676: break;
677:
678: case '{':
679: ++level;
680: break;
681:
682: case '}':
683: --level;
684: if( level == 0 ) { /* we are finished copying */
685: fprintf( ftable, " YYSTYPE;\n" );
686: if( fdefine ) fprintf( fdefine, " YYSTYPE;\nextern YYSTYPE yylval;\n" );
687: return;
688: }
689: }
690: }
691: }
692:
693: cpycode(){ /* copies code between \{ and \} */
694:
695: int c;
696: c = getc(finput);
697: if( c == '\n' ) {
698: c = getc(finput);
699: lineno++;
700: }
701: fprintf( ftable, "\n# line %d \"%s\"\n", lineno, infile );
702: while( c>=0 ){
703: if( c=='\\' )
704: if( (c=getc(finput)) == '}' ) return;
705: else putc('\\', ftable );
706: if( c=='%' )
707: if( (c=getc(finput)) == '}' ) return;
708: else putc('%', ftable );
709: putc( c , ftable );
710: if( c == '\n' ) ++lineno;
711: c = getc(finput);
712: }
713: error("eof before %%}" );
714: }
715:
716: skipcom(){ /* skip over comments */
717: register c, i=0; /* i is the number of lines skipped */
718:
719: /* skipcom is called after reading a / */
720:
721: if( getc(finput) != '*' ) error( "illegal comment" );
722: c = getc(finput);
723: while( c != EOF ){
724: while( c == '*' ){
725: if( (c=getc(finput)) == '/' ) return( i );
726: }
727: if( c == '\n' ) ++i;
728: c = getc(finput);
729: }
730: error( "EOF inside comment" );
731: /* NOTREACHED */
732: }
733:
734: cpyact(offset){ /* copy C action to the next ; or closing } */
735: int brac, c, match, j, s, tok;
736:
737: fprintf( faction, "\n# line %d \"%s\"\n", lineno, infile );
738:
739: brac = 0;
740:
741: loop:
742: c = getc(finput);
743: swt:
744: switch( c ){
745:
746: case ';':
747: if( brac == 0 ){
748: putc( c , faction );
749: return;
750: }
751: goto lcopy;
752:
753: case '{':
754: brac++;
755: goto lcopy;
756:
757: case '$':
758: s = 1;
759: tok = -1;
760: c = getc(finput);
761: if( c == '<' ){ /* type description */
762: ungetc( c, finput );
763: if( gettok() != TYPENAME ) error( "bad syntax on $<ident> clause" );
764: tok = numbval;
765: c = getc(finput);
766: }
767: if( c == '$' ){
768: fprintf( faction, "yyval");
769: if( ntypes ){ /* put out the proper tag... */
770: if( tok < 0 ) tok = fdtype( *prdptr[nprod] );
771: fprintf( faction, ".%s", typeset[tok] );
772: }
773: goto loop;
774: }
775: if( c == '-' ){
776: s = -s;
777: c = getc(finput);
778: }
779: if( isdigit(c) ){
780: j=0;
781: while( isdigit(c) ){
782: j= j*10+c-'0';
783: c = getc(finput);
784: }
785:
786: j = j*s - offset;
787: if( j > 0 ){
788: error( "Illegal use of $%d", j+offset );
789: }
790:
791: fprintf( faction, "yypvt[-%d]", -j );
792: if( ntypes ){ /* put out the proper tag */
793: if( j+offset <= 0 && tok < 0 ) error( "must specify type of $%d", j+offset );
794: if( tok < 0 ) tok = fdtype( prdptr[nprod][j+offset] );
795: fprintf( faction, ".%s", typeset[tok] );
796: }
797: goto swt;
798: }
799: putc( '$' , faction );
800: if( s<0 ) putc('-', faction );
801: goto swt;
802:
803: case '}':
804: if( --brac ) goto lcopy;
805: putc( c, faction );
806: return;
807:
808:
809: case '/': /* look for comments */
810: putc( c , faction );
811: c = getc(finput);
812: if( c != '*' ) goto swt;
813:
814: /* it really is a comment */
815:
816: putc( c , faction );
817: c = getc(finput);
818: while( c != EOF ){
819: while( c=='*' ){
820: putc( c , faction );
821: if( (c=getc(finput)) == '/' ) goto lcopy;
822: }
823: putc( c , faction );
824: if( c == '\n' )++lineno;
825: c = getc(finput);
826: }
827: error( "EOF inside comment" );
828:
829: case '\'': /* character constant */
830: match = '\'';
831: goto string;
832:
833: case '"': /* character string */
834: match = '"';
835:
836: string:
837:
838: putc( c , faction );
839: while( c=getc(finput) ){
840:
841: if( c=='\\' ){
842: putc( c , faction );
843: c=getc(finput);
844: if( c == '\n' ) ++lineno;
845: }
846: else if( c==match ) goto lcopy;
847: else if( c=='\n' ) error( "newline in string or char. const." );
848: putc( c , faction );
849: }
850: error( "EOF in string or character constant" );
851:
852: case EOF:
853: error("action does not terminate" );
854:
855: case '\n': ++lineno;
856: goto lcopy;
857:
858: }
859:
860: lcopy:
861: putc( c , faction );
862: goto loop;
863: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.