1*47968Sbostic /*- 2*47968Sbostic * Copyright (c) 1979 The Regents of the University of California. 3*47968Sbostic * All rights reserved. 4*47968Sbostic * 5*47968Sbostic * %sccs.include.proprietary.c% 619571Smckusick */ 719571Smckusick 819571Smckusick #ifndef lint 9*47968Sbostic static char sccsid[] = "@(#)ey2.c 5.2 (Berkeley) 04/12/91"; 10*47968Sbostic #endif /* not lint */ 1119571Smckusick 1219571Smckusick # include "ey.h" 1319571Smckusick # define IDENTIFIER 257 1419571Smckusick # define MARK 258 1519571Smckusick # define TERM 259 1619571Smckusick # define LEFT 260 1719571Smckusick # define BINARY 261 1819571Smckusick # define RIGHT 262 1919571Smckusick # define PREC 263 2019571Smckusick # define LCURLY 264 2119571Smckusick # define C_IDENTIFIER 265 /* name followed by colon */ 2219571Smckusick # define NUMBER 266 2319571Smckusick 2419571Smckusick FILE *copen(); 2519571Smckusick 2619571Smckusick setup(argc,argv) int argc; char *argv[]; 2719571Smckusick { int i,j,lev,t; 2819571Smckusick int c; 2919571Smckusick 3019571Smckusick foutput = stdout; 3119571Smckusick i = 1; 3219571Smckusick while( argc >= 2 && argv[1][0] == '-' ) { 3319571Smckusick while( *++(argv[1]) ){ 3419571Smckusick switch( *argv[1] ){ 3519571Smckusick case 'v': 3619571Smckusick case 'V': 3719571Smckusick foutput = copen("y.output", 'w' ); 3819571Smckusick if( foutput == 0 ) error( "cannot open y.output"); 3919571Smckusick continue; 4019571Smckusick case 'o': 4119571Smckusick case 'O': 4219571Smckusick oflag = 1; 4319571Smckusick continue; 4419571Smckusick case 'r': 4519571Smckusick case 'R': 4619571Smckusick oflag = 1; 4719571Smckusick rflag = 1; 4819571Smckusick continue; 4919571Smckusick default: error( "illegal option: %c", *argv[1]); 5019571Smckusick } 5119571Smckusick } 5219571Smckusick argv++; 5319571Smckusick argc--; 5419571Smckusick } 5519571Smckusick 5619571Smckusick ftable = copen( oflag ? "yacc.tmp" : "y.tab.c" , 'w' ); 5719571Smckusick if( ftable==0 ) error( "cannot open table file" ); 5819571Smckusick if( argc > 1 ) { cin = copen( argv[1], 'r' ); 5919571Smckusick if( cin == 0 ) error( "cannot open input" ); 6019571Smckusick } 6119571Smckusick settab(); 6219571Smckusick fprintf( cout , "#\n"); 6319571Smckusick ctokn = "$end"; 6419571Smckusick defin(0); /* eof */ 6519571Smckusick extval = 0400; /* beginning of assigned values */ 6619571Smckusick ctokn = "error"; 6719571Smckusick defin(0); 6819571Smckusick ctokn = "$accept"; 6919571Smckusick defin(1); 7019571Smckusick mem=mem0; 7119571Smckusick cnamp = cnames; 7219571Smckusick lev=0; 7319571Smckusick i=0; 7419571Smckusick 7519571Smckusick while( ( t = gettok() ) != EOF ) { 7619571Smckusick switch( t ){ 7719571Smckusick case IDENTIFIER: j = chfind(0); 7819571Smckusick trmlev[j] = lev; 7919571Smckusick continue; 8019571Smckusick case ',': 8119571Smckusick case ';': continue; 8219571Smckusick case TERM: lev=0; continue; 8319571Smckusick case LEFT: lev=(++i<<3)|01; continue; 8419571Smckusick case BINARY: lev=(++i<<3)|02; continue; 8519571Smckusick case RIGHT: lev=(++i<<3)|03; continue; 8619571Smckusick case MARK: 8719571Smckusick defout(); 8819571Smckusick if( rflag ){ /* RATFOR */ 8919571Smckusick fprintf( cout , "define yyerrok yyerrf = 0\n" ); 9019571Smckusick fprintf( cout , "define yyclearin yychar = -1\n" ); 9119571Smckusick fprintf( cout , "subroutine yyactr(yyprdn)\n"); 9219571Smckusick fprintf( cout , "common/yycomn/yylval,yyval,yypv,yyvalv(150)\n" ); 9319571Smckusick fprintf( cout , "common/yylcom/yychar,yyerrf,yydebu\n" ); 9419571Smckusick fprintf( cout , "integer yychar, yyerrf, yydebu\n" ); 9519571Smckusick fprintf( cout , "integer yyprdn,yyval,yylval,yypv,yyvalv\n" ); 9619571Smckusick } 9719571Smckusick else { 9819571Smckusick fprintf( cout , "#define yyclearin yychar = -1\n" ); 9919571Smckusick fprintf( cout , "#define yyerrok yyerrflag = 0\n" ); 10019571Smckusick fprintf( cout , "extern int yychar, yyerrflag;\n" ); 10119571Smckusick fprintf( cout , "\nint yyval 0;\nint *yypv;\nint yylval 0;"); 10219571Smckusick fprintf( cout , "\nyyactr(__np__){\n"); 10319571Smckusick } 10419571Smckusick break; 10519571Smckusick case LCURLY: defout(); 10619571Smckusick cpycode(); 10719571Smckusick continue; 10819571Smckusick case NUMBER: 10919571Smckusick trmset[j].value = numbval; 11019571Smckusick if( j < ndefout && j>2 ) 11119571Smckusick error("please define type # of %s earlier", trmset[j].name ); 11219571Smckusick continue; 11319571Smckusick default: error("bad precedence syntax, input %d", t ); 11419571Smckusick } 11519571Smckusick break; 11619571Smckusick } 11719571Smckusick prdptr[0]=mem; 11819571Smckusick /* added production */ 11919571Smckusick *mem++ = NTBASE; 12019571Smckusick *mem++ = NTBASE+1; 12119571Smckusick *mem++ = 1; 12219571Smckusick *mem++ = 0; 12319571Smckusick prdptr[1]=mem; 12419571Smckusick i=0; 12519571Smckusick 12619571Smckusick /* i is 0 when a rule can begin, 1 otherwise */ 12719571Smckusick 12819571Smckusick for(;;) switch( t=gettok() ) { 12919571Smckusick case C_IDENTIFIER: if( mem == prdptr[1] ) { /* first time */ 13019571Smckusick if( rflag ){ 13119571Smckusick fprintf( cout , "goto 1000\n" ); 13219571Smckusick } 13319571Smckusick else fprintf( cout , "\nswitch(__np__){\n"); 13419571Smckusick } 13519571Smckusick if( i != 0 ) error( "previous rule not terminated" ); 13619571Smckusick *mem = chfind(1); 13719571Smckusick if( *mem < NTBASE )error( "token illegal on lhs of grammar rule" ); 13819571Smckusick i=1; 13919571Smckusick ++mem; 14019571Smckusick continue; 14119571Smckusick case IDENTIFIER: 14219571Smckusick *mem=chfind(1); 14319571Smckusick if(*mem < NTBASE)levprd[nprod]=trmlev[*mem]; 14419571Smckusick mem++; 14519571Smckusick if(i==0) error("missing :"); 14619571Smckusick continue; 14719571Smckusick case '=': levprd[nprod] |= 04; 14819571Smckusick if( i==0 ) error("semicolon preceeds action"); 14919571Smckusick fprintf( cout , rflag?"\n%d ":"\ncase %d:", nprod ); 15019571Smckusick cpyact(); 15119571Smckusick fprintf( cout , rflag ? " return" : " break;" ); 15219571Smckusick case '|': 15319571Smckusick case ';': if(i){ 15419571Smckusick *mem++ = -nprod; 15519571Smckusick prdptr[++nprod] = mem; 15619571Smckusick levprd[nprod]=0; 15719571Smckusick i=0;} 15819571Smckusick if (t=='|'){i=1;*mem++ = *prdptr[nprod-1];} 15919571Smckusick continue; 16019571Smckusick case 0: /* End Of File */ 16119571Smckusick case EOF: 16219571Smckusick case MARK: if( i != 0 ) error( "rule not terminated before %%%% or EOF" ); 16319571Smckusick settab(); 16419571Smckusick finact(); 16519571Smckusick /* copy the programs which follow the rules */ 16619571Smckusick if( t == MARK ){ 16719571Smckusick while (( c=fgetc( cin)) != EOF ) fputc(c,cout); 16819571Smckusick } 16919571Smckusick return; 17019571Smckusick case PREC: 17119571Smckusick if( i==0 ) error( "%%prec must appear inside rule" ); 17219571Smckusick if( gettok()!=IDENTIFIER)error("illegal %%prec syntax" ); 17319571Smckusick j=chfind(2); 17419571Smckusick if(j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name); 17519571Smckusick levprd[nprod]=trmlev[j]; 17619571Smckusick continue; 17719571Smckusick case LCURLY: 17819571Smckusick if( i!=0 ) error( "%%{ appears within a rule" ); 17919571Smckusick cpycode(); 18019571Smckusick continue; 18119571Smckusick default: error( "syntax error, input %d", t ); 18219571Smckusick } 18319571Smckusick } 18419571Smckusick 18519571Smckusick finact(){ 18619571Smckusick /* finish action routine */ 18719571Smckusick register i; 18819571Smckusick 18919571Smckusick if( rflag ){ 19019571Smckusick 19119571Smckusick fprintf( cout , "\n1000 goto(" ); 19219571Smckusick for( i=1; i<nprod; ++i ){ 19319571Smckusick fprintf( cout , "%d,", (levprd[i]&04)==0?999:i ); 19419571Smckusick } 19519571Smckusick fprintf( cout , "999),yyprdn\n" ); 19619571Smckusick fprintf( cout , "999 return\nend\n" ); 19719571Smckusick fprintf( cout , "define YYERRCODE %d\n", trmset[2].value ); 19819571Smckusick } 19919571Smckusick else { 20019571Smckusick fprintf( cout , "\n}\n}\n" ); 20119571Smckusick fprintf( cout , "int yyerrval %d;\n", trmset[2].value ); 20219571Smckusick } 20319571Smckusick } 20419571Smckusick defin(t) { 20519571Smckusick /* define ctokn to be a terminal if t=0 20619571Smckusick or a nonterminal if t=1 */ 20719571Smckusick char *cp,*p; 20819571Smckusick int c; 20919571Smckusick 21019571Smckusick 21119571Smckusick if (t) { 21219571Smckusick if( ++nnonter >= ntlim ) error("too many nonterminals, limit %d",ntlim); 21319571Smckusick nontrst[nnonter].name = ctokn; 21419571Smckusick return( NTBASE + nnonter ); 21519571Smckusick } 21619571Smckusick else { 21719571Smckusick if( ++nterms >= tlim ) error("too many terminals, limit %d",tlim ); 21819571Smckusick trmset[nterms].name = ctokn; 21919571Smckusick if( ctokn[0]==' ' && ctokn[2]=='\0' ) /* single character literal */ 22019571Smckusick trmset[nterms].value = ctokn[1]; 22119571Smckusick else if ( ctokn[0]==' ' && ctokn[1]=='\\' ) { /* escape sequence */ 22219571Smckusick if( ctokn[3] == '\0' ){ /* single character escape sequence */ 22319571Smckusick switch ( ctokn[2] ){ 22419571Smckusick /* character which is escaped */ 22519571Smckusick case 'n': trmset[nterms].value = '\n'; break; 22619571Smckusick case 'r': trmset[nterms].value = '\r'; break; 22719571Smckusick case 'b': trmset[nterms].value = '\b'; break; 22819571Smckusick case 't': trmset[nterms].value = '\t'; break; 22919571Smckusick case '\'': trmset[nterms].value = '\''; break; 23019571Smckusick case '"': trmset[nterms].value = '"'; break; 23119571Smckusick case '\\': trmset[nterms].value = '\\'; break; 23219571Smckusick default: error( "invalid escape" ); 23319571Smckusick } 23419571Smckusick } 23519571Smckusick else if( ctokn[2] <= '7' && ctokn[2]>='0' ){ /* \nnn sequence */ 23619571Smckusick if( ctokn[3]<'0' || ctokn[3] > '7' || ctokn[4]<'0' || 23719571Smckusick ctokn[4]>'7' || ctokn[5] != '\0' ) error("illegal \\nnn construction" ); 23819571Smckusick trmset[nterms].value = 64*(ctokn[2]-'0')+8*(ctokn[3]-'0')+ctokn[4]-'0'; 23919571Smckusick if( trmset[nterms].value == 0 ) error( "'\\000' is illegal" ); 24019571Smckusick } 24119571Smckusick } 24219571Smckusick else { 24319571Smckusick trmset[nterms].value = extval++; 24419571Smckusick 24519571Smckusick } 24619571Smckusick trmlev[nterms] = 0; 24719571Smckusick return( nterms ); 24819571Smckusick } 24919571Smckusick } 25019571Smckusick 25119571Smckusick defout(){ /* write out the defines (at the end of the declaration section) */ 25219571Smckusick 25319571Smckusick _REGISTER int i, c; 25419571Smckusick _REGISTER char *cp; 25519571Smckusick 25619571Smckusick for( i=ndefout; i<=nterms; ++i ){ 25719571Smckusick 25819571Smckusick cp = trmset[i].name; 25919571Smckusick if( *cp == ' ' ) ++cp; /* literals */ 26019571Smckusick 26119571Smckusick for( ; (c= *cp)!='\0'; ++cp ){ 26219571Smckusick 26319571Smckusick if( c>='a' && c<='z' || 26419571Smckusick c>='A' && c<='Z' || 26519571Smckusick c>='0' && c<='9' || 26619571Smckusick c=='_' ) ; /* VOID */ 26719571Smckusick else goto nodef; 26819571Smckusick } 26919571Smckusick 27019571Smckusick /* define it */ 27119571Smckusick 27219571Smckusick fprintf( cout , "%c define %s %d\n", rflag?' ':'#', trmset[i].name, trmset[i].value ); 27319571Smckusick 27419571Smckusick nodef: ; 27519571Smckusick } 27619571Smckusick 27719571Smckusick ndefout = nterms+1; 27819571Smckusick 27919571Smckusick } 28019571Smckusick 28119571Smckusick chstash( c ){ 28219571Smckusick /* put character away into cnames */ 28319571Smckusick if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" ); 28419571Smckusick else *cnamp++ = c; 28519571Smckusick } 28619571Smckusick 28719571Smckusick int gettok() { 28819571Smckusick int j, base; 28919571Smckusick static int peekline; /* number of '\n' seen in lookahead */ 29019571Smckusick auto int c, match, reserve; 29119571Smckusick 29219571Smckusick begin: 29319571Smckusick reserve = 0; 29419571Smckusick if( peekc>=0 ) { 29519571Smckusick c = peekc; 29619571Smckusick lineno += peekline; 29719571Smckusick peekc = -1; 29819571Smckusick peekline = 0; 29919571Smckusick } 30019571Smckusick else c = fgetc( cin); 30119571Smckusick while( c==' ' || c=='\n' || c=='\t' || c == '\014'){ 30219571Smckusick if( c == '\n' ) ++lineno; 30319571Smckusick c=fgetc( cin); 30419571Smckusick } 30519571Smckusick if (c=='/') 30619571Smckusick {if (fgetc( cin)!='*')error("illegal /"); 30719571Smckusick c=fgetc( cin); 30819571Smckusick while(c != EOF) { 30919571Smckusick if( c == '\n' ) ++lineno; 31019571Smckusick if (c=='*') 31119571Smckusick {if((c=fgetc( cin))=='/')break;} 31219571Smckusick else c=fgetc( cin);} 31319571Smckusick if (!c) return(0); 31419571Smckusick goto begin;} 31519571Smckusick j=0; 31619571Smckusick switch(c){ 31719571Smckusick case '"': 31819571Smckusick case '\'': match = c; 31919571Smckusick ctokn = cnamp; 32019571Smckusick chstash( ' ' ); 32119571Smckusick while(1){ 32219571Smckusick c = fgetc( cin); 32319571Smckusick if( c == '\n' || c == '\0' ) 32419571Smckusick error("illegal or missing ' or \""); 32519571Smckusick if( c == '\\' ){ 32619571Smckusick c = fgetc( cin); 32719571Smckusick chstash( '\\' ); 32819571Smckusick } 32919571Smckusick else if( c == match ) break; 33019571Smckusick chstash( c ); 33119571Smckusick } 33219571Smckusick break; 33319571Smckusick case '%': 33419571Smckusick case '\\': switch(c=fgetc( cin)) 33519571Smckusick {case '0': return(TERM); 33619571Smckusick case '<': return(LEFT); 33719571Smckusick case '2': return(BINARY); 33819571Smckusick case '>': return(RIGHT); 33919571Smckusick case '%': 34019571Smckusick case '\\': return(MARK); 34119571Smckusick case '=': return(PREC); 34219571Smckusick case '{': return(LCURLY); 34319571Smckusick default: reserve = 1; 34419571Smckusick } 34519571Smckusick default: if( c >= '0' && c <= '9' ){ /* number */ 34619571Smckusick numbval = c-'0' ; 34719571Smckusick base = (c=='0') ? 8 : 10 ; 34819571Smckusick for( c=fgetc( cin); c>='0' && c<='9'; c=fgetc( cin) ){ 34919571Smckusick numbval = numbval*base + c - '0'; 35019571Smckusick } 35119571Smckusick peekc = c; 35219571Smckusick return(NUMBER); 35319571Smckusick } 35419571Smckusick else if( (c>='a'&&c<='z')||(c>='A'&&c<='Z')||c=='_'||c=='.'||c=='$'){ 35519571Smckusick ctokn = cnamp; 35619571Smckusick while( (c>='a'&&c<='z') || 35719571Smckusick (c>='A'&&c<='Z') || 35819571Smckusick (c>='0'&&c<='9') || 35919571Smckusick c=='_' || c=='.' || c=='$' ) { 36019571Smckusick chstash( c ); 36119571Smckusick if( peekc>=0 ) { c = peekc; peekc = -1; } 36219571Smckusick else c = fgetc( cin); 36319571Smckusick } 36419571Smckusick } 36519571Smckusick else return(c); 36619571Smckusick 36719571Smckusick peekc=c; 36819571Smckusick } 36919571Smckusick chstash( '\0' ); 37019571Smckusick 37119571Smckusick if( reserve ){ /* find a reserved word */ 37219571Smckusick if( compare("term")) return( TERM ); 37319571Smckusick if( compare("TERM")) return( TERM ); 37419571Smckusick if( compare("token")) return( TERM ); 37519571Smckusick if( compare("TOKEN")) return( TERM ); 37619571Smckusick if( compare("left")) return( LEFT ); 37719571Smckusick if( compare("LEFT")) return( LEFT ); 37819571Smckusick if( compare("nonassoc")) return( BINARY ); 37919571Smckusick if( compare("NONASSOC")) return( BINARY ); 38019571Smckusick if( compare("binary")) return( BINARY ); 38119571Smckusick if( compare("BINARY")) return( BINARY ); 38219571Smckusick if( compare("right")) return( RIGHT ); 38319571Smckusick if( compare("RIGHT")) return( RIGHT ); 38419571Smckusick if( compare("prec")) return( PREC ); 38519571Smckusick if( compare("PREC")) return( PREC ); 38619571Smckusick error("invalid escape, or illegal reserved word: %s", ctokn ); 38719571Smckusick } 38819571Smckusick 38919571Smckusick /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */ 39019571Smckusick 39119571Smckusick look: 39219571Smckusick while( peekc==' ' || peekc=='\t' || peekc == '\n' || peekc == '\014' ) 39319571Smckusick { 39419571Smckusick if( peekc == '\n' ) ++peekline; 39519571Smckusick peekc = fgetc( cin); 39619571Smckusick } 39719571Smckusick 39819571Smckusick if( peekc != ':' ) return( IDENTIFIER ); 39919571Smckusick peekc = -1; 40019571Smckusick lineno += peekline; 40119571Smckusick peekline = 0; 40219571Smckusick return( C_IDENTIFIER ); 40319571Smckusick } 40419571Smckusick chfind(t) 40519571Smckusick 40619571Smckusick { int i,j; 40719571Smckusick 40819571Smckusick if (ctokn[0]==' ')t=0; 40919571Smckusick for(i=1;i<=nterms;i++) 41019571Smckusick if(compare(trmset[i].name)){ 41119571Smckusick cnamp = ctokn; 41219571Smckusick return( i ); 41319571Smckusick } 41419571Smckusick for(i=1;i<=nnonter;i++) 41519571Smckusick if(compare(nontrst[i].name)) { 41619571Smckusick cnamp = ctokn; 41719571Smckusick return( i+NTBASE ); 41819571Smckusick } 41919571Smckusick /* cannot find name */ 42019571Smckusick if( t>1 && ctokn[0] != ' ' ) 42119571Smckusick error( "%s should have been defined earlier", ctokn ); 42219571Smckusick return( defin( t ) ); 42319571Smckusick } 42419571Smckusick 42519571Smckusick cpycode(){ /* copies code between \{ and \} */ 42619571Smckusick 42719571Smckusick int c; 42819571Smckusick c = fgetc( cin); 42919571Smckusick if( c == '\n' ) { 43019571Smckusick c = fgetc( cin); 43119571Smckusick lineno++; 43219571Smckusick } 43319571Smckusick while( c != EOF ){ 43419571Smckusick if( c=='\\' ) 43519571Smckusick if( (c=fgetc( cin)) == '}' ) return; 43619571Smckusick else fputc('\\',cout); 43719571Smckusick if( c=='%' ) 43819571Smckusick if( (c=fgetc( cin)) == '}' ) return; 43919571Smckusick else fputc('%',cout); 44019571Smckusick fputc( c, cout ); 44119571Smckusick if( c == '\n' ) ++lineno; 44219571Smckusick c = fgetc( cin); 44319571Smckusick } 44419571Smckusick error("eof before %%}"); 44519571Smckusick } 44619571Smckusick 44719571Smckusick cpyact(){ /* copy C action to the next ; or closing } */ 44819571Smckusick int brac, c, match, *i, j, s; 44919571Smckusick 45019571Smckusick brac = 0; 45119571Smckusick 45219571Smckusick loop: 45319571Smckusick c = fgetc( cin); 45419571Smckusick swt: 45519571Smckusick switch( c ){ 45619571Smckusick 45719571Smckusick case ';': 45819571Smckusick if( brac == 0 ){ 45919571Smckusick fputc( c, cout ); 46019571Smckusick return; 46119571Smckusick } 46219571Smckusick goto lcopy; 46319571Smckusick 46419571Smckusick case '{': 46519571Smckusick brac++; 46619571Smckusick goto lcopy; 46719571Smckusick 46819571Smckusick case '$': 46919571Smckusick s = 1; 47019571Smckusick c = fgetc( cin); 47119571Smckusick if( c == '$' ){ 47219571Smckusick fprintf( cout , "yyval"); 47319571Smckusick goto loop; 47419571Smckusick } 47519571Smckusick if( c == '-' ){ 47619571Smckusick s = -s; 47719571Smckusick c = fgetc( cin); 47819571Smckusick } 47919571Smckusick if( c>='0' && c <= '9' ){ 48019571Smckusick j=0; 48119571Smckusick while( c>='0' && c<= '9' ){ 48219571Smckusick j= j*10+c-'0'; 48319571Smckusick c = fgetc( cin); 48419571Smckusick } 48519571Smckusick if( rflag ) fprintf( cout , "yyvalv(yypv%c%d)", s==1?'+':'-', j ); 48619571Smckusick else fprintf( cout , "yypv[%d]", s*j ); 48719571Smckusick goto swt; 48819571Smckusick } 48919571Smckusick fputc( '$' , cout); 49019571Smckusick if( s<0 ) fputc('-', cout); 49119571Smckusick goto swt; 49219571Smckusick 49319571Smckusick case '}': 49419571Smckusick brac--; 49519571Smckusick if( brac == 0 ){ 49619571Smckusick fputc( c , cout); 49719571Smckusick return; 49819571Smckusick } 49919571Smckusick goto lcopy; 50019571Smckusick 50119571Smckusick case '/': /* look for comments */ 50219571Smckusick fputc( c ,cout); 50319571Smckusick c = fgetc( cin); 50419571Smckusick if( c != '*' ) goto swt; 50519571Smckusick 50619571Smckusick /* it really is a comment */ 50719571Smckusick 50819571Smckusick fputc( c , cout); 50919571Smckusick while( (c=fgetc( cin)) != EOF ){ 51019571Smckusick if( c=='*' ){ 51119571Smckusick fputc( c , cout); 51219571Smckusick if( (c=fgetc( cin)) == '/' ) goto lcopy; 51319571Smckusick } 51419571Smckusick fputc( c , cout); 51519571Smckusick } 51619571Smckusick error( "EOF inside comment" ); 51719571Smckusick 51819571Smckusick case '\'': /* character constant */ 51919571Smckusick match = '\''; 52019571Smckusick goto string; 52119571Smckusick 52219571Smckusick case '"': /* character string */ 52319571Smckusick match = '"'; 52419571Smckusick 52519571Smckusick string: 52619571Smckusick 52719571Smckusick fputc( c , cout); 52819571Smckusick while( (c=fgetc( cin)) != EOF ){ 52919571Smckusick 53019571Smckusick if( c=='\\' ){ 53119571Smckusick fputc( c , cout); 53219571Smckusick c=fgetc( cin); 53319571Smckusick } 53419571Smckusick else if( c==match ) goto lcopy; 53519571Smckusick fputc( c , cout); 53619571Smckusick } 53719571Smckusick error( "EOF in string or character constant" ); 53819571Smckusick 53919571Smckusick case '\0': 54019571Smckusick error("action does not terminate"); 54119571Smckusick case '\n': ++lineno; 54219571Smckusick goto lcopy; 54319571Smckusick 54419571Smckusick } 54519571Smckusick 54619571Smckusick lcopy: 54719571Smckusick fputc( c , cout); 54819571Smckusick goto loop; 54919571Smckusick } 550