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