|
|
1.1 root 1: %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS
2: %left SCON '/' NEWE
3: %left '|'
4: %left '$' '^'
5: %left CHAR CCL NCCL '(' '.' STR NULLS
6: %left ITER
7: %left CAT
8: %left '*' '+' '?'
9:
10: %{
11: #define YYSTYPE union _yystype_
12: union _yystype_
13: {
14: int i;
15: char *cp;
16: };
17: # include "ldefs.c"
18: %}
19: %%
20: %{
21: int i;
22: int j,k;
23: int g;
24: char *p;
25: %}
26: acc : lexinput
27: ={
28: # ifdef DEBUG
29: if(debug) sect2dump();
30: # endif
31: }
32: ;
33: lexinput: defns delim prods end
34: | defns delim end
35: ={
36: if(!funcflag)phead2();
37: funcflag = TRUE;
38: }
39: | error
40: ={
41: # ifdef DEBUG
42: if(debug) {
43: sect1dump();
44: sect2dump();
45: }
46: # endif
47: }
48: ;
49: end: delim | ;
50: defns: defns STR STR
51: ={ scopy($2,dp);
52: def[dptr] = dp;
53: dp += slength($2) + 1;
54: scopy($3,dp);
55: subs[dptr++] = dp;
56: if(dptr >= DEFSIZE)
57: error("Too many definitions");
58: dp += slength($3) + 1;
59: if(dp >= dchar+DEFCHAR)
60: error("Definitions too long");
61: subs[dptr]=def[dptr]=0; /* for lookup - require ending null */
62: }
63: |
64: ;
65: delim: DELIM
66: ={
67: # ifdef DEBUG
68: if(sect == DEFSECTION && debug) sect1dump();
69: # endif
70: sect++;
71: }
72: ;
73: prods: prods pr
74: ={ $$.i = mn2(RNEWE,$1.i,$2.i);
75: }
76: | pr
77: ={ $$.i = $1.i;}
78: ;
79: pr: r NEWE
80: ={
81: if(divflg == TRUE)
82: i = mn1(S1FINAL,casecount);
83: else i = mn1(FINAL,casecount);
84: $$.i = mn2(RCAT,$1.i,i);
85: divflg = FALSE;
86: casecount++;
87: }
88: | error NEWE
89: ={
90: # ifdef DEBUG
91: if(debug) sect2dump();
92: # endif
93: }
94: r: CHAR
95: ={ $$.i = mn0($1.i); }
96: | STR
97: ={
98: p = $1.cp;
99: i = mn0(*p++);
100: while(*p)
101: i = mn2(RSTR,i,*p++);
102: $$.i = i;
103: }
104: | '.'
105: ={ symbol['\n'] = 0;
106: if(psave == FALSE){
107: p = ccptr;
108: psave = ccptr;
109: for(i=1;i<'\n';i++){
110: symbol[i] = 1;
111: *ccptr++ = i;
112: }
113: for(i='\n'+1;i<NCH;i++){
114: symbol[i] = 1;
115: *ccptr++ = i;
116: }
117: *ccptr++ = 0;
118: if(ccptr > ccl+CCLSIZE)
119: error("Too many large character classes");
120: }
121: else
122: p = psave;
123: $$.i = mn1(RCCL,p);
124: cclinter(1);
125: }
126: | CCL
127: ={ $$.i = mn1(RCCL,$1.i); }
128: | NCCL
129: ={ $$.i = mn1(RNCCL,$1.i); }
130: | r '*'
131: ={ $$.i = mn1(STAR,$1.i); }
132: | r '+'
133: ={ $$.i = mn1(PLUS,$1.i); }
134: | r '?'
135: ={ $$.i = mn1(QUEST,$1.i); }
136: | r '|' r
137: ={ $$.i = mn2(BAR,$1.i,$3.i); }
138: | r r %prec CAT
139: ={ $$.i = mn2(RCAT,$1.i,$2.i); }
140: | r '/' r
141: ={ if(!divflg){
142: j = mn1(S2FINAL,-casecount);
143: i = mn2(RCAT,$1.i,j);
144: $$.i = mn2(DIV,i,$3.i);
145: }
146: else {
147: $$.i = mn2(RCAT,$1.i,$3.i);
148: warning("Extra slash removed");
149: }
150: divflg = TRUE;
151: }
152: | r ITER ',' ITER '}'
153: ={ if($2.i > $4.i){
154: i = $2.i;
155: $2.i = $4.i;
156: $4.i = i;
157: }
158: if($4.i <= 0)
159: warning("Iteration range must be positive");
160: else {
161: j = $1.i;
162: for(k = 2; k<=$2.i;k++)
163: j = mn2(RCAT,j,dupl($1.i));
164: for(i = $2.i+1; i<=$4.i; i++){
165: g = dupl($1.i);
166: for(k=2;k<=i;k++)
167: g = mn2(RCAT,g,dupl($1.i));
168: j = mn2(BAR,j,g);
169: }
170: $$.i = j;
171: }
172: }
173: | r ITER '}'
174: ={
175: if($2.i < 0)warning("Can't have negative iteration");
176: else if($2.i == 0) $$.i = mn0(RNULLS);
177: else {
178: j = $1.i;
179: for(k=2;k<=$2.i;k++)
180: j = mn2(RCAT,j,dupl($1.i));
181: $$.i = j;
182: }
183: }
184: | r ITER ',' '}'
185: ={
186: /* from n to infinity */
187: if($2.i < 0)warning("Can't have negative iteration");
188: else if($2.i == 0) $$.i = mn1(STAR,$1.i);
189: else if($2.i == 1)$$.i = mn1(PLUS,$1.i);
190: else { /* >= 2 iterations minimum */
191: j = $1.i;
192: for(k=2;k<$2.i;k++)
193: j = mn2(RCAT,j,dupl($1.i));
194: k = mn1(PLUS,dupl($1.i));
195: $$.i = mn2(RCAT,j,k);
196: }
197: }
198: | SCON r
199: ={ $$.i = mn2(RSCON,$2.i,$1.i); }
200: | '^' r
201: ={ $$.i = mn1(CARAT,$2.i); }
202: | r '$'
203: ={ i = mn0('\n');
204: if(!divflg){
205: j = mn1(S2FINAL,-casecount);
206: k = mn2(RCAT,$1.i,j);
207: $$.i = mn2(DIV,k,i);
208: }
209: else $$.i = mn2(RCAT,$1.i,i);
210: divflg = TRUE;
211: }
212: | '(' r ')'
213: ={ $$.i = $2.i; }
214: | NULLS
215: ={ $$.i = mn0(RNULLS); }
216: ;
217: %%
218: yylex(){
219: register char *p;
220: register int c, i;
221: char *t, *xp;
222: int n, j, k, x;
223: static int sectbegin;
224: static char token[TOKENSIZE];
225: static int iter;
226:
227: # ifdef DEBUG
228: yylval.i = 0;
229: # endif
230:
231: if(sect == DEFSECTION) { /* definitions section */
232: while(!eof) {
233: if(prev == '\n'){ /* next char is at beginning of line */
234: getl(p=buf);
235: switch(*p){
236: case '%':
237: switch(c= *(p+1)){
238: case '%':
239: lgate();
240: if(!ratfor)fprintf(fout,"# ");
241: fprintf(fout,"define YYNEWLINE %d\n",ctable['\n']);
242: if(!ratfor)fprintf(fout,"yylex(){\nint nstr; extern int yyprevious;\n");
243: sectbegin = TRUE;
244: i = treesize*(sizeof(*name)+sizeof(*left)+
245: sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;
246: c = (int)myalloc(i,1);
247: if(c == 0)
248: error("Too little core for parse tree");
249: p = (char *)c;
250: cfree((char *)p,i,1);
251: name = (int *)myalloc(treesize,sizeof(*name));
252: left = (int *)myalloc(treesize,sizeof(*left));
253: right = (int *)myalloc(treesize,sizeof(*right));
254: nullstr = myalloc(treesize,sizeof(*nullstr));
255: parent = (int *)myalloc(treesize,sizeof(*parent));
256: if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0)
257: error("Too little core for parse tree");
258: return(freturn(DELIM));
259: case 'p': case 'P': /* has overridden number of positions */
260: while(*p && !digit(*p))p++;
261: maxpos = siconv(p);
262: # ifdef DEBUG
263: if (debug) printf("positions (%%p) now %d\n",maxpos);
264: # endif
265: if(report == 2)report = 1;
266: continue;
267: case 'n': case 'N': /* has overridden number of states */
268: while(*p && !digit(*p))p++;
269: nstates = siconv(p);
270: # ifdef DEBUG
271: if(debug)printf( " no. states (%%n) now %d\n",nstates);
272: # endif
273: if(report == 2)report = 1;
274: continue;
275: case 'e': case 'E': /* has overridden number of tree nodes */
276: while(*p && !digit(*p))p++;
277: treesize = siconv(p);
278: # ifdef DEBUG
279: if (debug) printf("treesize (%%e) now %d\n",treesize);
280: # endif
281: if(report == 2)report = 1;
282: continue;
283: case 'o': case 'O':
284: while (*p && !digit(*p))p++;
285: outsize = siconv(p);
286: if (report ==2) report=1;
287: continue;
288: case 'a': case 'A': /* has overridden number of transitions */
289: while(*p && !digit(*p))p++;
290: if(report == 2)report = 1;
291: ntrans = siconv(p);
292: # ifdef DEBUG
293: if (debug)printf("N. trans (%%a) now %d\n",ntrans);
294: # endif
295: continue;
296: case 'k': case 'K': /* overriden packed char classes */
297: while (*p && !digit(*p))p++;
298: if (report==2) report=1;
299: cfree((char *)pchar, pchlen, sizeof(*pchar));
300: pchlen = siconv(p);
301: # ifdef DEBUG
302: if (debug) printf( "Size classes (%%k) now %d\n",pchlen);
303: # endif
304: pchar=pcptr=myalloc(pchlen, sizeof(*pchar));
305: continue;
306: case 't': case 'T': /* character set specifier */
307: ZCH = atoi(p+2);
308: if (ZCH < NCH) ZCH = NCH;
309: if (ZCH > 2*NCH) error("ch table needs redeclaration");
310: chset = TRUE;
311: for(i = 0; i<ZCH; i++)
312: ctable[i] = 0;
313: while(getl(p) && scomp(p,"%T") != 0 && scomp(p,"%t") != 0){
314: if((n = siconv(p)) <= 0 || n > ZCH){
315: warning("Character value %d out of range",n);
316: continue;
317: }
318: while(!space(*p) && *p) p++;
319: while(space(*p)) p++;
320: t = p;
321: while(*t){
322: c = ctrans(&t);
323: if(ctable[c]){
324: if (printable(c))
325: warning("Character '%c' used twice",c);
326: else
327: warning("Character %o used twice",c);
328: }
329: else ctable[c] = n;
330: t++;
331: }
332: p = buf;
333: }
334: {
335: char chused[2*NCH]; int kr;
336: for(i=0; i<ZCH; i++)
337: chused[i]=0;
338: for(i=0; i<NCH; i++)
339: chused[ctable[i]]=1;
340: for(kr=i=1; i<NCH; i++)
341: if (ctable[i]==0)
342: {
343: while (chused[kr] == 0)
344: kr++;
345: ctable[i]=kr;
346: chused[kr]=1;
347: }
348: }
349: lgate();
350: continue;
351: case 'r': case 'R':
352: c = 'r';
353: case 'c': case 'C':
354: if(lgatflg)
355: error("Too late for language specifier");
356: ratfor = (c == 'r');
357: continue;
358: case '{':
359: lgate();
360: sharpline();
361: while(getl(p) && scomp(p,"%}") != 0)
362: fprintf(fout, "%s\n",p);
363: if(p[0] == '%') continue;
364: error("Premature eof");
365: case 's': case 'S': /* start conditions */
366: lgate();
367: while(*p && index(*p," \t,") < 0) p++;
368: n = TRUE;
369: while(n){
370: while(*p && index(*p," \t,") >= 0) p++;
371: t = p;
372: while(*p && index(*p," \t,") < 0)p++;
373: if(!*p) n = FALSE;
374: *p++ = 0;
375: if (*t == 0) continue;
376: i = sptr*2;
377: if(!ratfor)fprintf(fout,"# ");
378: fprintf(fout,"define %s %d\n",t,i);
379: scopy(t,sp);
380: sname[sptr++] = sp;
381: sname[sptr] = 0; /* required by lookup */
382: if(sptr >= STARTSIZE)
383: error("Too many start conditions");
384: sp += slength(sp) + 1;
385: if(sp >= schar+STARTCHAR)
386: error("Start conditions too long");
387: }
388: continue;
389: default:
390: warning("Invalid request %s",p);
391: continue;
392: } /* end of switch after seeing '%' */
393: case ' ': case '\t': /* must be code */
394: lgate();
395: fprintf(fout, "%s\n",p);
396: continue;
397: default: /* definition */
398: while(*p && !space(*p)) p++;
399: if(*p == 0)
400: continue;
401: prev = *p;
402: *p = 0;
403: bptr = p+1;
404: yylval.cp = buf;
405: if(digit(buf[0]))
406: warning("Substitution strings may not begin with digits");
407: return(freturn(STR));
408: }
409: }
410: /* still sect 1, but prev != '\n' */
411: else {
412: p = bptr;
413: while(*p && space(*p)) p++;
414: if(*p == 0)
415: warning("No translation given - null string assumed");
416: scopy(p,token);
417: yylval.cp = token;
418: prev = '\n';
419: return(freturn(STR));
420: }
421: }
422: /* end of section one processing */
423: }
424: else if(sect == RULESECTION){ /* rules and actions */
425: while(!eof){
426: switch(c=gch()){
427: case '\0':
428: return(freturn(0));
429: case '\n':
430: if(prev == '\n') continue;
431: x = NEWE;
432: break;
433: case ' ':
434: case '\t':
435: if(sectbegin == TRUE){
436: sharpline();
437: cpyact();
438: while((c=gch()) && c != '\n');
439: continue;
440: }
441: if(!funcflag)phead2();
442: funcflag = TRUE;
443: if(ratfor)fprintf(fout,"%d\n",30000+casecount);
444: else fprintf(fout,"case %d:\n",casecount);
445: sharpline();
446: if(cpyact()){
447: if(ratfor)fprintf(fout,"goto 30997\n");
448: else fprintf(fout,"break;\n");
449: }
450: while((c=gch()) && c != '\n');
451: if(peek == ' ' || peek == '\t' || sectbegin == TRUE){
452: warning("Executable statements should occur right after %%");
453: continue;
454: }
455: x = NEWE;
456: break;
457: case '%':
458: if(prev != '\n') goto character;
459: if(peek == '{'){ /* included code */
460: sharpline();
461: getl(buf);
462: while(!eof && getl(buf) && scomp("%}",buf) != 0)
463: fprintf(fout,"%s\n",buf);
464: continue;
465: }
466: if(peek == '%'){
467: c = gch();
468: c = gch();
469: x = DELIM;
470: break;
471: }
472: goto character;
473: case '|':
474: if(peek == ' ' || peek == '\t' || peek == '\n'){
475: if(ratfor)fprintf(fout,"%d\n",30000+casecount++);
476: else fprintf(fout,"case %d:\n",casecount++);
477: continue;
478: }
479: x = '|';
480: break;
481: case '$':
482: if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
483: x = c;
484: break;
485: }
486: goto character;
487: case '^':
488: if(prev != '\n' && scon != TRUE) goto character; /* valid only at line begin */
489: x = c;
490: break;
491: case '?':
492: case '+':
493: case '.':
494: case '*':
495: case '(':
496: case ')':
497: case ',':
498: case '/':
499: x = c;
500: break;
501: case '}':
502: iter = FALSE;
503: x = c;
504: break;
505: case '{': /* either iteration or definition */
506: if(digit(c=gch())){ /* iteration */
507: iter = TRUE;
508: ieval:
509: i = 0;
510: while(digit(c)){
511: token[i++] = c;
512: c = gch();
513: }
514: token[i] = 0;
515: yylval.i = siconv(token);
516: munput('c',c);
517: x = ITER;
518: break;
519: }
520: else { /* definition */
521: i = 0;
522: while(c && c!='}'){
523: token[i++] = c;
524: c = gch();
525: }
526: token[i] = 0;
527: i = lookup(token,def);
528: if(i < 0)
529: warning("Definition %s not found",token);
530: else
531: munput('s',subs[i]);
532: continue;
533: }
534: case '<': /* start condition ? */
535: if(prev != '\n') /* not at line begin, not start */
536: goto character;
537: t = slptr;
538: do {
539: i = 0;
540: c = gch();
541: while(c != ',' && c && c != '>'){
542: token[i++] = c;
543: c = gch();
544: }
545: token[i] = 0;
546: if(i == 0)
547: goto character;
548: i = lookup(token,sname);
549: if(i < 0) {
550: warning("Undefined start condition %s",token);
551: continue;
552: }
553: *slptr++ = i+1;
554: } while(c && c != '>');
555: *slptr++ = 0;
556: /* check if previous value re-usable */
557: for (xp=slist; xp<t; )
558: {
559: if (strcmp(xp, t)==0)
560: break;
561: while (*xp++);
562: }
563: if (xp<t)
564: {
565: /* re-use previous pointer to string */
566: slptr=t;
567: t=xp;
568: }
569: if(slptr > slist+STARTSIZE) /* note not packed ! */
570: error("Too many start conditions used");
571: yylval.cp = t;
572: x = SCON;
573: break;
574: case '"':
575: i = 0;
576: while((c=gch()) && c != '"' && c != '\n'){
577: if(c == '\\') c = usescape(c=gch());
578: token[i++] = c;
579: if(i > TOKENSIZE){
580: warning("String too long");
581: i = TOKENSIZE-1;
582: break;
583: }
584: }
585: if(c == '\n') {
586: yyline--;
587: warning("Non-terminated string");
588: yyline++;
589: }
590: token[i] = 0;
591: if(i == 0)x = NULLS;
592: else if(i == 1){
593: yylval.i = token[0];
594: x = CHAR;
595: }
596: else {
597: yylval.cp = token;
598: x = STR;
599: }
600: break;
601: case '[':
602: for(i=1;i<NCH;i++) symbol[i] = 0;
603: x = CCL;
604: if((c = gch()) == '^'){
605: x = NCCL;
606: c = gch();
607: }
608: while(c != ']' && c){
609: if(c == '\\') c = usescape(c=gch());
610: symbol[c] = 1;
611: j = c;
612: if((c=gch()) == '-' && peek != ']'){ /* range specified */
613: c = gch();
614: if(c == '\\') c = usescape(c=gch());
615: k = c;
616: if(j > k) {
617: n = j;
618: j = k;
619: k = n;
620: }
621: if(!(('A' <= j && k <= 'Z') ||
622: ('a' <= j && k <= 'z') ||
623: ('0' <= j && k <= '9')))
624: warning("Non-portable Character Class");
625: for(n=j+1;n<=k;n++)
626: symbol[n] = 1; /* implementation dependent */
627: c = gch();
628: }
629: }
630: /* try to pack ccl's */
631: i = 0;
632: for(j=0;j<NCH;j++)
633: if(symbol[j])token[i++] = j;
634: token[i] = 0;
635: p = ccptr;
636: if(optim){
637: p = ccl;
638: while(p <ccptr && scomp(token,p) != 0)p++;
639: }
640: if(p < ccptr) /* found it */
641: yylval.cp = p;
642: else {
643: yylval.cp = ccptr;
644: scopy(token,ccptr);
645: ccptr += slength(token) + 1;
646: if(ccptr >= ccl+CCLSIZE)
647: error("Too many large character classes");
648: }
649: cclinter(x==CCL);
650: break;
651: case '\\':
652: c = usescape(c=gch());
653: default:
654: character:
655: if(iter){ /* second part of an iteration */
656: iter = FALSE;
657: if('0' <= c && c <= '9')
658: goto ieval;
659: }
660: if(alpha(peek)){
661: i = 0;
662: yylval.cp = token;
663: token[i++] = c;
664: while(alpha(peek))
665: token[i++] = gch();
666: if(peek == '?' || peek == '*' || peek == '+')
667: munput('c',token[--i]);
668: token[i] = 0;
669: if(i == 1){
670: yylval.i = token[0];
671: x = CHAR;
672: }
673: else x = STR;
674: }
675: else {
676: yylval.i = c;
677: x = CHAR;
678: }
679: }
680: scon = FALSE;
681: if(x == SCON)scon = TRUE;
682: sectbegin = FALSE;
683: return(freturn(x));
684: }
685: }
686: /* section three */
687: ptail();
688: # ifdef DEBUG
689: if(debug)
690: fprintf(fout,"\n/*this comes from section three - debug */\n");
691: # endif
692: sharpline();
693: while(getl(buf) && !eof)
694: fprintf(fout,"%s\n",buf);
695: return(freturn(0));
696: }
697: /* end of yylex */
698: # ifdef DEBUG
699: freturn(i)
700: int i; {
701: if(yydebug) {
702: printf("now return ");
703: if(i < NCH) allprint(i);
704: else printf("%d",i);
705: printf(" yylval = ");
706: switch(i){
707: case STR: case CCL: case NCCL:
708: strpt(yylval.cp);
709: break;
710: case CHAR:
711: allprint(yylval.i);
712: break;
713: default:
714: printf("%d",yylval.i);
715: break;
716: }
717: putchar('\n');
718: }
719: return(i);
720: }
721: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.