114492Ssam %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS 214492Ssam %left SCON '/' NEWE 314492Ssam %left '|' 414492Ssam %left '$' '^' 514492Ssam %left CHAR CCL NCCL '(' '.' STR NULLS 614492Ssam %left ITER 714492Ssam %left CAT 814492Ssam %left '*' '+' '?' 914492Ssam 1014492Ssam %{ 1114492Ssam #ifndef lint 12*33344Sbostic static char sccsid[] = "@(#)parser.y 4.2 (Berkeley) 01/12/88"; 1314492Ssam #endif 1414492Ssam 1514492Ssam # include "ldefs.c" 1614492Ssam %} 1714492Ssam %% 1814492Ssam %{ 1914492Ssam int i; 2014492Ssam int j,k; 2114492Ssam int g; 2214492Ssam char *p; 2314492Ssam %} 2414492Ssam acc : lexinput 2514492Ssam ={ 2614492Ssam # ifdef DEBUG 2714492Ssam if(debug) sect2dump(); 2814492Ssam # endif 2914492Ssam } 3014492Ssam ; 3114492Ssam lexinput: defns delim prods end 3214492Ssam | defns delim end 3314492Ssam ={ 3414492Ssam if(!funcflag)phead2(); 3514492Ssam funcflag = TRUE; 3614492Ssam } 3714492Ssam | error 3814492Ssam ={ 3914492Ssam # ifdef DEBUG 4014492Ssam if(debug) { 4114492Ssam sect1dump(); 4214492Ssam sect2dump(); 4314492Ssam } 4414492Ssam # endif 4514492Ssam } 4614492Ssam ; 4714492Ssam end: delim | ; 4814492Ssam defns: defns STR STR 4914492Ssam ={ scopy($2,dp); 5014492Ssam def[dptr] = dp; 5114492Ssam dp += slength($2) + 1; 5214492Ssam scopy($3,dp); 5314492Ssam subs[dptr++] = dp; 5414492Ssam if(dptr >= DEFSIZE) 5514492Ssam error("Too many definitions"); 5614492Ssam dp += slength($3) + 1; 5714492Ssam if(dp >= dchar+DEFCHAR) 5814492Ssam error("Definitions too long"); 5914492Ssam subs[dptr]=def[dptr]=0; /* for lookup - require ending null */ 6014492Ssam } 6114492Ssam | 6214492Ssam ; 6314492Ssam delim: DELIM 6414492Ssam ={ 6514492Ssam # ifdef DEBUG 6614492Ssam if(sect == DEFSECTION && debug) sect1dump(); 6714492Ssam # endif 6814492Ssam sect++; 6914492Ssam } 7014492Ssam ; 7114492Ssam prods: prods pr 7214492Ssam ={ $$ = mn2(RNEWE,$1,$2); 7314492Ssam } 7414492Ssam | pr 7514492Ssam ={ $$ = $1;} 7614492Ssam ; 7714492Ssam pr: r NEWE 7814492Ssam ={ 7914492Ssam if(divflg == TRUE) 8014492Ssam i = mn1(S1FINAL,casecount); 8114492Ssam else i = mn1(FINAL,casecount); 8214492Ssam $$ = mn2(RCAT,$1,i); 8314492Ssam divflg = FALSE; 8414492Ssam casecount++; 8514492Ssam } 8614492Ssam | error NEWE 8714492Ssam ={ 8814492Ssam # ifdef DEBUG 8914492Ssam if(debug) sect2dump(); 9014492Ssam # endif 9114492Ssam } 9214492Ssam r: CHAR 9314492Ssam ={ $$ = mn0($1); } 9414492Ssam | STR 9514492Ssam ={ 96*33344Sbostic p = (char *)$1; 9714492Ssam i = mn0(*p++); 9814492Ssam while(*p) 9914492Ssam i = mn2(RSTR,i,*p++); 10014492Ssam $$ = i; 10114492Ssam } 10214492Ssam | '.' 10314492Ssam ={ symbol['\n'] = 0; 10414492Ssam if(psave == FALSE){ 10514492Ssam p = ccptr; 10614492Ssam psave = ccptr; 10714492Ssam for(i=1;i<'\n';i++){ 10814492Ssam symbol[i] = 1; 10914492Ssam *ccptr++ = i; 11014492Ssam } 11114492Ssam for(i='\n'+1;i<NCH;i++){ 11214492Ssam symbol[i] = 1; 11314492Ssam *ccptr++ = i; 11414492Ssam } 11514492Ssam *ccptr++ = 0; 11614492Ssam if(ccptr > ccl+CCLSIZE) 11714492Ssam error("Too many large character classes"); 11814492Ssam } 11914492Ssam else 12014492Ssam p = psave; 12114492Ssam $$ = mn1(RCCL,p); 12214492Ssam cclinter(1); 12314492Ssam } 12414492Ssam | CCL 12514492Ssam ={ $$ = mn1(RCCL,$1); } 12614492Ssam | NCCL 12714492Ssam ={ $$ = mn1(RNCCL,$1); } 12814492Ssam | r '*' 12914492Ssam ={ $$ = mn1(STAR,$1); } 13014492Ssam | r '+' 13114492Ssam ={ $$ = mn1(PLUS,$1); } 13214492Ssam | r '?' 13314492Ssam ={ $$ = mn1(QUEST,$1); } 13414492Ssam | r '|' r 13514492Ssam ={ $$ = mn2(BAR,$1,$3); } 13614492Ssam | r r %prec CAT 13714492Ssam ={ $$ = mn2(RCAT,$1,$2); } 13814492Ssam | r '/' r 13914492Ssam ={ if(!divflg){ 14014492Ssam j = mn1(S2FINAL,-casecount); 14114492Ssam i = mn2(RCAT,$1,j); 14214492Ssam $$ = mn2(DIV,i,$3); 14314492Ssam } 14414492Ssam else { 14514492Ssam $$ = mn2(RCAT,$1,$3); 14614492Ssam warning("Extra slash removed"); 14714492Ssam } 14814492Ssam divflg = TRUE; 14914492Ssam } 15014492Ssam | r ITER ',' ITER '}' 15114492Ssam ={ if($2 > $4){ 15214492Ssam i = $2; 15314492Ssam $2 = $4; 15414492Ssam $4 = i; 15514492Ssam } 15614492Ssam if($4 <= 0) 15714492Ssam warning("Iteration range must be positive"); 15814492Ssam else { 15914492Ssam j = $1; 16014492Ssam for(k = 2; k<=$2;k++) 16114492Ssam j = mn2(RCAT,j,dupl($1)); 16214492Ssam for(i = $2+1; i<=$4; i++){ 16314492Ssam g = dupl($1); 16414492Ssam for(k=2;k<=i;k++) 16514492Ssam g = mn2(RCAT,g,dupl($1)); 16614492Ssam j = mn2(BAR,j,g); 16714492Ssam } 16814492Ssam $$ = j; 16914492Ssam } 17014492Ssam } 17114492Ssam | r ITER '}' 17214492Ssam ={ 17314492Ssam if($2 < 0)warning("Can't have negative iteration"); 17414492Ssam else if($2 == 0) $$ = mn0(RNULLS); 17514492Ssam else { 17614492Ssam j = $1; 17714492Ssam for(k=2;k<=$2;k++) 17814492Ssam j = mn2(RCAT,j,dupl($1)); 17914492Ssam $$ = j; 18014492Ssam } 18114492Ssam } 18214492Ssam | r ITER ',' '}' 18314492Ssam ={ 18414492Ssam /* from n to infinity */ 18514492Ssam if($2 < 0)warning("Can't have negative iteration"); 18614492Ssam else if($2 == 0) $$ = mn1(STAR,$1); 18714492Ssam else if($2 == 1)$$ = mn1(PLUS,$1); 18814492Ssam else { /* >= 2 iterations minimum */ 18914492Ssam j = $1; 19014492Ssam for(k=2;k<$2;k++) 19114492Ssam j = mn2(RCAT,j,dupl($1)); 19214492Ssam k = mn1(PLUS,dupl($1)); 19314492Ssam $$ = mn2(RCAT,j,k); 19414492Ssam } 19514492Ssam } 19614492Ssam | SCON r 19714492Ssam ={ $$ = mn2(RSCON,$2,$1); } 19814492Ssam | '^' r 19914492Ssam ={ $$ = mn1(CARAT,$2); } 20014492Ssam | r '$' 20114492Ssam ={ i = mn0('\n'); 20214492Ssam if(!divflg){ 20314492Ssam j = mn1(S2FINAL,-casecount); 20414492Ssam k = mn2(RCAT,$1,j); 20514492Ssam $$ = mn2(DIV,k,i); 20614492Ssam } 20714492Ssam else $$ = mn2(RCAT,$1,i); 20814492Ssam divflg = TRUE; 20914492Ssam } 21014492Ssam | '(' r ')' 21114492Ssam ={ $$ = $2; } 21214492Ssam | NULLS 21314492Ssam ={ $$ = mn0(RNULLS); } 21414492Ssam ; 21514492Ssam %% 21614492Ssam yylex(){ 21714492Ssam register char *p; 21814492Ssam register int c, i; 21914492Ssam char *t, *xp; 22014492Ssam int n, j, k, x; 22114492Ssam static int sectbegin; 22214492Ssam static char token[TOKENSIZE]; 22314492Ssam static int iter; 22414492Ssam 22514492Ssam # ifdef DEBUG 22614492Ssam yylval = 0; 22714492Ssam # endif 22814492Ssam 22914492Ssam if(sect == DEFSECTION) { /* definitions section */ 23014492Ssam while(!eof) { 23114492Ssam if(prev == '\n'){ /* next char is at beginning of line */ 23214492Ssam getl(p=buf); 23314492Ssam switch(*p){ 23414492Ssam case '%': 23514492Ssam switch(c= *(p+1)){ 23614492Ssam case '%': 23714492Ssam lgate(); 23814492Ssam if(!ratfor)fprintf(fout,"# "); 23914492Ssam fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']); 24014492Ssam if(!ratfor)fprintf(fout,"yylex(){\nint nstr; extern int yyprevious;\n"); 24114492Ssam sectbegin = TRUE; 24214492Ssam i = treesize*(sizeof(*name)+sizeof(*left)+ 24314492Ssam sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA; 244*33344Sbostic p = myalloc(i,1); 24514492Ssam if(c == 0) 24614492Ssam error("Too little core for parse tree"); 24714492Ssam cfree(p,i,1); 248*33344Sbostic name = (int *)myalloc(treesize,sizeof(*name)); 249*33344Sbostic left = (int *)myalloc(treesize,sizeof(*left)); 250*33344Sbostic right = (int *)myalloc(treesize,sizeof(*right)); 251*33344Sbostic nullstr = (char *)myalloc(treesize,sizeof(*nullstr)); 252*33344Sbostic parent = (int *)myalloc(treesize,sizeof(*parent)); 25314492Ssam if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0) 25414492Ssam error("Too little core for parse tree"); 25514492Ssam return(freturn(DELIM)); 25614492Ssam case 'p': case 'P': /* has overridden number of positions */ 25714492Ssam while(*p && !digit(*p))p++; 25814492Ssam maxpos = siconv(p); 25914492Ssam # ifdef DEBUG 26014492Ssam if (debug) printf("positions (%%p) now %d\n",maxpos); 26114492Ssam # endif 26214492Ssam if(report == 2)report = 1; 26314492Ssam continue; 26414492Ssam case 'n': case 'N': /* has overridden number of states */ 26514492Ssam while(*p && !digit(*p))p++; 26614492Ssam nstates = siconv(p); 26714492Ssam # ifdef DEBUG 26814492Ssam if(debug)printf( " no. states (%%n) now %d\n",nstates); 26914492Ssam # endif 27014492Ssam if(report == 2)report = 1; 27114492Ssam continue; 27214492Ssam case 'e': case 'E': /* has overridden number of tree nodes */ 27314492Ssam while(*p && !digit(*p))p++; 27414492Ssam treesize = siconv(p); 27514492Ssam # ifdef DEBUG 27614492Ssam if (debug) printf("treesize (%%e) now %d\n",treesize); 27714492Ssam # endif 27814492Ssam if(report == 2)report = 1; 27914492Ssam continue; 28014492Ssam case 'o': case 'O': 28114492Ssam while (*p && !digit(*p))p++; 28214492Ssam outsize = siconv(p); 28314492Ssam if (report ==2) report=1; 28414492Ssam continue; 28514492Ssam case 'a': case 'A': /* has overridden number of transitions */ 28614492Ssam while(*p && !digit(*p))p++; 28714492Ssam if(report == 2)report = 1; 28814492Ssam ntrans = siconv(p); 28914492Ssam # ifdef DEBUG 29014492Ssam if (debug)printf("N. trans (%%a) now %d\n",ntrans); 29114492Ssam # endif 29214492Ssam continue; 29314492Ssam case 'k': case 'K': /* overriden packed char classes */ 29414492Ssam while (*p && !digit(*p))p++; 29514492Ssam if (report==2) report=1; 29614492Ssam cfree(pchar, pchlen, sizeof(*pchar)); 29714492Ssam pchlen = siconv(p); 29814492Ssam # ifdef DEBUG 29914492Ssam if (debug) printf( "Size classes (%%k) now %d\n",pchlen); 30014492Ssam # endif 30114492Ssam pchar=pcptr=myalloc(pchlen, sizeof(*pchar)); 30214492Ssam continue; 30314492Ssam case 't': case 'T': /* character set specifier */ 30414492Ssam ZCH = atoi(p+2); 30514492Ssam if (ZCH < NCH) ZCH = NCH; 30614492Ssam if (ZCH > 2*NCH) error("ch table needs redeclaration"); 30714492Ssam chset = TRUE; 30814492Ssam for(i = 0; i<ZCH; i++) 30914492Ssam ctable[i] = 0; 31014492Ssam while(getl(p) && scomp(p,"%T") != 0 && scomp(p,"%t") != 0){ 31114492Ssam if((n = siconv(p)) <= 0 || n > ZCH){ 31214492Ssam warning("Character value %d out of range",n); 31314492Ssam continue; 31414492Ssam } 31514492Ssam while(!space(*p) && *p) p++; 31614492Ssam while(space(*p)) p++; 31714492Ssam t = p; 31814492Ssam while(*t){ 31914492Ssam c = ctrans(&t); 32014492Ssam if(ctable[c]){ 32114492Ssam if (printable(c)) 32214492Ssam warning("Character '%c' used twice",c); 32314492Ssam else 32414492Ssam warning("Character %o used twice",c); 32514492Ssam } 32614492Ssam else ctable[c] = n; 32714492Ssam t++; 32814492Ssam } 32914492Ssam p = buf; 33014492Ssam } 33114492Ssam { 33214492Ssam char chused[2*NCH]; int kr; 33314492Ssam for(i=0; i<ZCH; i++) 33414492Ssam chused[i]=0; 33514492Ssam for(i=0; i<NCH; i++) 33614492Ssam chused[ctable[i]]=1; 33714492Ssam for(kr=i=1; i<NCH; i++) 33814492Ssam if (ctable[i]==0) 33914492Ssam { 34014492Ssam while (chused[kr] == 0) 34114492Ssam kr++; 34214492Ssam ctable[i]=kr; 34314492Ssam chused[kr]=1; 34414492Ssam } 34514492Ssam } 34614492Ssam lgate(); 34714492Ssam continue; 34814492Ssam case 'r': case 'R': 34914492Ssam c = 'r'; 35014492Ssam case 'c': case 'C': 35114492Ssam if(lgatflg) 35214492Ssam error("Too late for language specifier"); 35314492Ssam ratfor = (c == 'r'); 35414492Ssam continue; 35514492Ssam case '{': 35614492Ssam lgate(); 35714492Ssam while(getl(p) && scomp(p,"%}") != 0) 35814492Ssam fprintf(fout, "%s\n",p); 35914492Ssam if(p[0] == '%') continue; 36014492Ssam error("Premature eof"); 36114492Ssam case 's': case 'S': /* start conditions */ 36214492Ssam lgate(); 36314492Ssam while(*p && index(*p," \t,") < 0) p++; 36414492Ssam n = TRUE; 36514492Ssam while(n){ 36614492Ssam while(*p && index(*p," \t,") >= 0) p++; 36714492Ssam t = p; 36814492Ssam while(*p && index(*p," \t,") < 0)p++; 36914492Ssam if(!*p) n = FALSE; 37014492Ssam *p++ = 0; 37114492Ssam if (*t == 0) continue; 37214492Ssam i = sptr*2; 37314492Ssam if(!ratfor)fprintf(fout,"# "); 37414492Ssam fprintf(fout,"define %s %d\n",t,i); 37514492Ssam scopy(t,sp); 37614492Ssam sname[sptr++] = sp; 37714492Ssam sname[sptr] = 0; /* required by lookup */ 37814492Ssam if(sptr >= STARTSIZE) 37914492Ssam error("Too many start conditions"); 38014492Ssam sp += slength(sp) + 1; 38114492Ssam if(sp >= schar+STARTCHAR) 38214492Ssam error("Start conditions too long"); 38314492Ssam } 38414492Ssam continue; 38514492Ssam default: 38614492Ssam warning("Invalid request %s",p); 38714492Ssam continue; 38814492Ssam } /* end of switch after seeing '%' */ 38914492Ssam case ' ': case '\t': /* must be code */ 39014492Ssam lgate(); 39114492Ssam fprintf(fout, "%s\n",p); 39214492Ssam continue; 39314492Ssam default: /* definition */ 39414492Ssam while(*p && !space(*p)) p++; 39514492Ssam if(*p == 0) 39614492Ssam continue; 39714492Ssam prev = *p; 39814492Ssam *p = 0; 39914492Ssam bptr = p+1; 400*33344Sbostic yylval = (int)buf; 40114492Ssam if(digit(buf[0])) 40214492Ssam warning("Substitution strings may not begin with digits"); 40314492Ssam return(freturn(STR)); 40414492Ssam } 40514492Ssam } 40614492Ssam /* still sect 1, but prev != '\n' */ 40714492Ssam else { 40814492Ssam p = bptr; 40914492Ssam while(*p && space(*p)) p++; 41014492Ssam if(*p == 0) 41114492Ssam warning("No translation given - null string assumed"); 41214492Ssam scopy(p,token); 413*33344Sbostic yylval = (int)token; 41414492Ssam prev = '\n'; 41514492Ssam return(freturn(STR)); 41614492Ssam } 41714492Ssam } 41814492Ssam /* end of section one processing */ 41914492Ssam } 42014492Ssam else if(sect == RULESECTION){ /* rules and actions */ 42114492Ssam while(!eof){ 42214492Ssam switch(c=gch()){ 42314492Ssam case '\0': 42414492Ssam return(freturn(0)); 42514492Ssam case '\n': 42614492Ssam if(prev == '\n') continue; 42714492Ssam x = NEWE; 42814492Ssam break; 42914492Ssam case ' ': 43014492Ssam case '\t': 43114492Ssam if(sectbegin == TRUE){ 43214492Ssam cpyact(); 43314492Ssam while((c=gch()) && c != '\n'); 43414492Ssam continue; 43514492Ssam } 43614492Ssam if(!funcflag)phead2(); 43714492Ssam funcflag = TRUE; 43814492Ssam if(ratfor)fprintf(fout,"%d\n",30000+casecount); 43914492Ssam else fprintf(fout,"case %d:\n",casecount); 44014492Ssam if(cpyact()){ 44114492Ssam if(ratfor)fprintf(fout,"goto 30997\n"); 44214492Ssam else fprintf(fout,"break;\n"); 44314492Ssam } 44414492Ssam while((c=gch()) && c != '\n'); 44514492Ssam if(peek == ' ' || peek == '\t' || sectbegin == TRUE){ 44614492Ssam warning("Executable statements should occur right after %%"); 44714492Ssam continue; 44814492Ssam } 44914492Ssam x = NEWE; 45014492Ssam break; 45114492Ssam case '%': 45214492Ssam if(prev != '\n') goto character; 45314492Ssam if(peek == '{'){ /* included code */ 45414492Ssam getl(buf); 45514492Ssam while(!eof && getl(buf) && scomp("%}",buf) != 0) 45614492Ssam fprintf(fout,"%s\n",buf); 45714492Ssam continue; 45814492Ssam } 45914492Ssam if(peek == '%'){ 46014492Ssam c = gch(); 46114492Ssam c = gch(); 46214492Ssam x = DELIM; 46314492Ssam break; 46414492Ssam } 46514492Ssam goto character; 46614492Ssam case '|': 46714492Ssam if(peek == ' ' || peek == '\t' || peek == '\n'){ 46814492Ssam if(ratfor)fprintf(fout,"%d\n",30000+casecount++); 46914492Ssam else fprintf(fout,"case %d:\n",casecount++); 47014492Ssam continue; 47114492Ssam } 47214492Ssam x = '|'; 47314492Ssam break; 47414492Ssam case '$': 47514492Ssam if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){ 47614492Ssam x = c; 47714492Ssam break; 47814492Ssam } 47914492Ssam goto character; 48014492Ssam case '^': 48114492Ssam if(prev != '\n' && scon != TRUE) goto character; /* valid only at line begin */ 48214492Ssam x = c; 48314492Ssam break; 48414492Ssam case '?': 48514492Ssam case '+': 48614492Ssam case '.': 48714492Ssam case '*': 48814492Ssam case '(': 48914492Ssam case ')': 49014492Ssam case ',': 49114492Ssam case '/': 49214492Ssam x = c; 49314492Ssam break; 49414492Ssam case '}': 49514492Ssam iter = FALSE; 49614492Ssam x = c; 49714492Ssam break; 49814492Ssam case '{': /* either iteration or definition */ 49914492Ssam if(digit(c=gch())){ /* iteration */ 50014492Ssam iter = TRUE; 50114492Ssam ieval: 50214492Ssam i = 0; 50314492Ssam while(digit(c)){ 50414492Ssam token[i++] = c; 50514492Ssam c = gch(); 50614492Ssam } 50714492Ssam token[i] = 0; 50814492Ssam yylval = siconv(token); 50914492Ssam munput('c',c); 51014492Ssam x = ITER; 51114492Ssam break; 51214492Ssam } 51314492Ssam else { /* definition */ 51414492Ssam i = 0; 51514492Ssam while(c && c!='}'){ 51614492Ssam token[i++] = c; 51714492Ssam c = gch(); 51814492Ssam } 51914492Ssam token[i] = 0; 52014492Ssam i = lookup(token,def); 52114492Ssam if(i < 0) 52214492Ssam warning("Definition %s not found",token); 52314492Ssam else 52414492Ssam munput('s',subs[i]); 52514492Ssam continue; 52614492Ssam } 52714492Ssam case '<': /* start condition ? */ 52814492Ssam if(prev != '\n') /* not at line begin, not start */ 52914492Ssam goto character; 53014492Ssam t = slptr; 53114492Ssam do { 53214492Ssam i = 0; 53314492Ssam c = gch(); 53414492Ssam while(c != ',' && c && c != '>'){ 53514492Ssam token[i++] = c; 53614492Ssam c = gch(); 53714492Ssam } 53814492Ssam token[i] = 0; 53914492Ssam if(i == 0) 54014492Ssam goto character; 54114492Ssam i = lookup(token,sname); 54214492Ssam if(i < 0) { 54314492Ssam warning("Undefined start condition %s",token); 54414492Ssam continue; 54514492Ssam } 54614492Ssam *slptr++ = i+1; 54714492Ssam } while(c && c != '>'); 54814492Ssam *slptr++ = 0; 54914492Ssam /* check if previous value re-usable */ 55014492Ssam for (xp=slist; xp<t; ) 55114492Ssam { 55214492Ssam if (strcmp(xp, t)==0) 55314492Ssam break; 55414492Ssam while (*xp++); 55514492Ssam } 55614492Ssam if (xp<t) 55714492Ssam { 55814492Ssam /* re-use previous pointer to string */ 55914492Ssam slptr=t; 56014492Ssam t=xp; 56114492Ssam } 56214492Ssam if(slptr > slist+STARTSIZE) /* note not packed ! */ 56314492Ssam error("Too many start conditions used"); 564*33344Sbostic yylval = (int)t; 56514492Ssam x = SCON; 56614492Ssam break; 56714492Ssam case '"': 56814492Ssam i = 0; 56914492Ssam while((c=gch()) && c != '"' && c != '\n'){ 57014492Ssam if(c == '\\') c = usescape(c=gch()); 57114492Ssam token[i++] = c; 57214492Ssam if(i > TOKENSIZE){ 57314492Ssam warning("String too long"); 57414492Ssam i = TOKENSIZE-1; 57514492Ssam break; 57614492Ssam } 57714492Ssam } 57814492Ssam if(c == '\n') { 57914492Ssam yyline--; 58014492Ssam warning("Non-terminated string"); 58114492Ssam yyline++; 58214492Ssam } 58314492Ssam token[i] = 0; 58414492Ssam if(i == 0)x = NULLS; 58514492Ssam else if(i == 1){ 58614492Ssam yylval = token[0]; 58714492Ssam x = CHAR; 58814492Ssam } 58914492Ssam else { 590*33344Sbostic yylval = (int)token; 59114492Ssam x = STR; 59214492Ssam } 59314492Ssam break; 59414492Ssam case '[': 59514492Ssam for(i=1;i<NCH;i++) symbol[i] = 0; 59614492Ssam x = CCL; 59714492Ssam if((c = gch()) == '^'){ 59814492Ssam x = NCCL; 59914492Ssam c = gch(); 60014492Ssam } 60114492Ssam while(c != ']' && c){ 60214492Ssam if(c == '\\') c = usescape(c=gch()); 60314492Ssam symbol[c] = 1; 60414492Ssam j = c; 60514492Ssam if((c=gch()) == '-' && peek != ']'){ /* range specified */ 60614492Ssam c = gch(); 60714492Ssam if(c == '\\') c = usescape(c=gch()); 60814492Ssam k = c; 60914492Ssam if(j > k) { 61014492Ssam n = j; 61114492Ssam j = k; 61214492Ssam k = n; 61314492Ssam } 61414492Ssam if(!(('A' <= j && k <= 'Z') || 61514492Ssam ('a' <= j && k <= 'z') || 61614492Ssam ('0' <= j && k <= '9'))) 61714492Ssam warning("Non-portable Character Class"); 61814492Ssam for(n=j+1;n<=k;n++) 61914492Ssam symbol[n] = 1; /* implementation dependent */ 62014492Ssam c = gch(); 62114492Ssam } 62214492Ssam } 62314492Ssam /* try to pack ccl's */ 62414492Ssam i = 0; 62514492Ssam for(j=0;j<NCH;j++) 62614492Ssam if(symbol[j])token[i++] = j; 62714492Ssam token[i] = 0; 62814492Ssam p = ccptr; 62914492Ssam if(optim){ 63014492Ssam p = ccl; 63114492Ssam while(p <ccptr && scomp(token,p) != 0)p++; 63214492Ssam } 63314492Ssam if(p < ccptr) /* found it */ 634*33344Sbostic yylval = (int)p; 63514492Ssam else { 636*33344Sbostic yylval = (int)ccptr; 63714492Ssam scopy(token,ccptr); 63814492Ssam ccptr += slength(token) + 1; 63914492Ssam if(ccptr >= ccl+CCLSIZE) 64014492Ssam error("Too many large character classes"); 64114492Ssam } 64214492Ssam cclinter(x==CCL); 64314492Ssam break; 64414492Ssam case '\\': 64514492Ssam c = usescape(c=gch()); 64614492Ssam default: 64714492Ssam character: 64814492Ssam if(iter){ /* second part of an iteration */ 64914492Ssam iter = FALSE; 65014492Ssam if('0' <= c && c <= '9') 65114492Ssam goto ieval; 65214492Ssam } 65314492Ssam if(alpha(peek)){ 65414492Ssam i = 0; 655*33344Sbostic yylval = (int)token; 65614492Ssam token[i++] = c; 65714492Ssam while(alpha(peek)) 65814492Ssam token[i++] = gch(); 65914492Ssam if(peek == '?' || peek == '*' || peek == '+') 66014492Ssam munput('c',token[--i]); 66114492Ssam token[i] = 0; 66214492Ssam if(i == 1){ 66314492Ssam yylval = token[0]; 66414492Ssam x = CHAR; 66514492Ssam } 66614492Ssam else x = STR; 66714492Ssam } 66814492Ssam else { 66914492Ssam yylval = c; 67014492Ssam x = CHAR; 67114492Ssam } 67214492Ssam } 67314492Ssam scon = FALSE; 67414492Ssam if(x == SCON)scon = TRUE; 67514492Ssam sectbegin = FALSE; 67614492Ssam return(freturn(x)); 67714492Ssam } 67814492Ssam } 67914492Ssam /* section three */ 68014492Ssam ptail(); 68114492Ssam # ifdef DEBUG 68214492Ssam if(debug) 68314492Ssam fprintf(fout,"\n/*this comes from section three - debug */\n"); 68414492Ssam # endif 68514492Ssam while(getl(buf) && !eof) 68614492Ssam fprintf(fout,"%s\n",buf); 68714492Ssam return(freturn(0)); 68814492Ssam } 68914492Ssam /* end of yylex */ 69014492Ssam # ifdef DEBUG 69114492Ssam freturn(i) 69214492Ssam int i; { 69314492Ssam if(yydebug) { 69414492Ssam printf("now return "); 69514492Ssam if(i < NCH) allprint(i); 69614492Ssam else printf("%d",i); 69714492Ssam printf(" yylval = "); 69814492Ssam switch(i){ 69914492Ssam case STR: case CCL: case NCCL: 70014492Ssam strpt(yylval); 70114492Ssam break; 70214492Ssam case CHAR: 70314492Ssam allprint(yylval); 70414492Ssam break; 70514492Ssam default: 70614492Ssam printf("%d",yylval); 70714492Ssam break; 70814492Ssam } 70914492Ssam putchar('\n'); 71014492Ssam } 71114492Ssam return(i); 71214492Ssam } 71314492Ssam # endif 714