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*43618Sbostic static char sccsid[] = "@(#)parser.y 4.3 (Berkeley) 06/24/90";
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 ={
9633344Sbostic 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;
24433344Sbostic p = myalloc(i,1);
245*43618Sbostic if(p == 0)
24614492Ssam error("Too little core for parse tree");
247*43618Sbostic free(p);
24833344Sbostic name = (int *)myalloc(treesize,sizeof(*name));
24933344Sbostic left = (int *)myalloc(treesize,sizeof(*left));
25033344Sbostic right = (int *)myalloc(treesize,sizeof(*right));
25133344Sbostic nullstr = (char *)myalloc(treesize,sizeof(*nullstr));
25233344Sbostic 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;
296*43618Sbostic free(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;
40033344Sbostic 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);
41333344Sbostic 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");
56433344Sbostic 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 {
59033344Sbostic 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 */
63433344Sbostic yylval = (int)p;
63514492Ssam else {
63633344Sbostic 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;
65533344Sbostic 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
freturn(i)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