1 %token CHAR CCL NCCL STR DELIM SCON ITER NEWE NULLS
5 %left CHAR CCL NCCL '(' '.' STR NULLS
12 #define YYSTYPE union _yystype_
29 if(debug) sect2dump();
33 lexinput: defns delim prods end
36 if(!funcflag)phead2();
51 ={ strcpy((char*)dp,(char*)$2.cp);
53 dp += strlen((char*)$2.cp) + 1;
54 strcpy((char*)dp,(char*)$3.cp);
57 error("Too many definitions");
58 dp += strlen((char*)$3.cp) + 1;
59 if(dp >= dchar+DEFCHAR)
60 error("Definitions too long");
61 subs[dptr]=def[dptr]=0; /* for lookup - require ending null */
68 if(sect == DEFSECTION && debug) sect1dump();
74 ={ $$.i = mn2(RNEWE,$1.i,$2.i);
82 i = mn1(S1FINAL,casecount);
83 else i = mn1(FINAL,casecount);
84 $$.i = mn2(RCAT,$1.i,i);
91 if(debug) sect2dump();
95 ={ $$.i = mn0($1.i); }
101 i = mn2(RSTR,i,*p++);
113 for(i='\n'+1;i<NCH;i++){
118 if(ccptr > ccl+CCLSIZE)
119 error("Too many large character classes");
127 ={ $$.i = mnp(RCCL,$1.cp); }
129 ={ $$.i = mnp(RNCCL,$1.cp); }
131 ={ $$.i = mn1(STAR,$1.i); }
133 ={ $$.i = mn1(PLUS,$1.i); }
135 ={ $$.i = mn1(QUEST,$1.i); }
137 ={ $$.i = mn2(BAR,$1.i,$3.i); }
139 ={ $$.i = mn2(RCAT,$1.i,$2.i); }
142 j = mn1(S2FINAL,-casecount);
143 i = mn2(RCAT,$1.i,j);
144 $$.i = mn2(DIV,i,$3.i);
147 $$.i = mn2(RCAT,$1.i,$3.i);
148 warning("Extra slash removed");
152 | r ITER ',' ITER '}'
159 warning("Iteration range must be positive");
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++){
167 g = mn2(RCAT,g,dupl($1.i));
175 if($2.i < 0)warning("Can't have negative iteration");
176 else if($2.i == 0) $$.i = mn0(RNULLS);
180 j = mn2(RCAT,j,dupl($1.i));
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 */
193 j = mn2(RCAT,j,dupl($1.i));
194 k = mn1(PLUS,dupl($1.i));
195 $$.i = mn2(RCAT,j,k);
199 ={ $$.i = mn2(RSCON,$2.i,(uintptr)$1.cp); }
201 ={ $$.i = mn1(CARAT,$2.i); }
205 j = mn1(S2FINAL,-casecount);
206 k = mn2(RCAT,$1.i,j);
209 else $$.i = mn2(RCAT,$1.i,i);
215 ={ $$.i = mn0(RNULLS); }
225 static int sectbegin;
226 static uchar token[TOKENSIZE];
233 if(sect == DEFSECTION) { /* definitions section */
235 if(prev == '\n'){ /* next char is at beginning of line */
242 Bprint(&fout,"#define YYNEWLINE %d\n",'\n');
243 Bprint(&fout,"int\nyylex(void){\nint nstr; extern int yyprevious;\nif(yyprevious){}\n");
245 i = treesize*(sizeof(*name)+sizeof(*left)+
246 sizeof(*right)+sizeof(*nullstr)+sizeof(*parent))+ALITTLEEXTRA;
249 error("Too little core for parse tree");
251 name = myalloc(treesize,sizeof(*name));
252 left = myalloc(treesize,sizeof(*left));
253 right = myalloc(treesize,sizeof(*right));
254 nullstr = myalloc(treesize,sizeof(*nullstr));
255 parent = myalloc(treesize,sizeof(*parent));
256 ptr = myalloc(treesize,sizeof(*ptr));
257 if(name == 0 || left == 0 || right == 0 || parent == 0 || nullstr == 0 || ptr == 0)
258 error("Too little core for parse tree");
259 return(freturn(DELIM));
260 case 'p': case 'P': /* has overridden number of positions */
261 while(*p && !isdigit(*p))p++;
262 maxpos = atol((char*)p);
264 if (debug) print("positions (%%p) now %d\n",maxpos);
266 if(report == 2)report = 1;
268 case 'n': case 'N': /* has overridden number of states */
269 while(*p && !isdigit(*p))p++;
270 nstates = atol((char*)p);
272 if(debug)print( " no. states (%%n) now %d\n",nstates);
274 if(report == 2)report = 1;
276 case 'e': case 'E': /* has overridden number of tree nodes */
277 while(*p && !isdigit(*p))p++;
278 treesize = atol((char*)p);
280 if (debug) print("treesize (%%e) now %d\n",treesize);
282 if(report == 2)report = 1;
285 while (*p && !isdigit(*p))p++;
286 outsize = atol((char*)p);
287 if (report ==2) report=1;
289 case 'a': case 'A': /* has overridden number of transitions */
290 while(*p && !isdigit(*p))p++;
291 if(report == 2)report = 1;
292 ntrans = atol((char*)p);
294 if (debug)print("N. trans (%%a) now %d\n",ntrans);
297 case 'k': case 'K': /* overriden packed char classes */
298 while (*p && !isdigit(*p))p++;
299 if (report==2) report=1;
301 pchlen = atol((char*)p);
303 if (debug) print( "Size classes (%%k) now %d\n",pchlen);
305 pchar=pcptr=myalloc(pchlen, sizeof(*pchar));
309 while(getl(p) && strcmp((char*)p,"%}") != 0)
310 Bprint(&fout, "%s\n",(char*)p);
311 if(p[0] == '%') continue;
312 error("Premature eof");
313 case 's': case 'S': /* start conditions */
315 while(*p && strchr(" \t,", *p) == 0) p++;
318 while(*p && strchr(" \t,", *p)) p++;
320 while(*p && strchr(" \t,", *p) == 0)p++;
323 if (*t == 0) continue;
325 Bprint(&fout,"#define %s %d\n",(char*)t,i);
326 strcpy((char*)sp, (char*)t);
328 sname[sptr] = 0; /* required by lookup */
329 if(sptr >= STARTSIZE)
330 error("Too many start conditions");
331 sp += strlen((char*)sp) + 1;
332 if(sp >= stchar+STARTCHAR)
333 error("Start conditions too long");
337 warning("Invalid request %s",p);
339 } /* end of switch after seeing '%' */
340 case ' ': case '\t': /* must be code */
342 Bprint(&fout, "%s\n",(char*)p);
344 default: /* definition */
345 while(*p && !isspace(*p)) p++;
353 warning("Substitution strings may not begin with digits");
354 return(freturn(STR));
357 /* still sect 1, but prev != '\n' */
360 while(*p && isspace(*p)) p++;
362 warning("No translation given - null string assumed");
363 strcpy((char*)token, (char*)p);
366 return(freturn(STR));
369 /* end of section one processing */
370 } else if(sect == RULESECTION){ /* rules and actions */
376 if(prev == '\n') continue;
381 if(sectbegin == TRUE){
383 while((c=gch()) && c != '\n');
386 if(!funcflag)phead2();
388 Bprint(&fout,"case %d:\n",casecount);
390 Bprint(&fout,"break;\n");
391 while((c=gch()) && c != '\n');
392 if(peek == ' ' || peek == '\t' || sectbegin == TRUE){
393 warning("Executable statements should occur right after %%");
399 if(prev != '\n') goto character;
400 if(peek == '{'){ /* included code */
402 while(!eof && getl(buf) && strcmp("%}",(char*)buf) != 0)
403 Bprint(&fout,"%s\n",(char*)buf);
414 if(peek == ' ' || peek == '\t' || peek == '\n'){
415 Bprint(&fout,"%d\n",30000+casecount++);
421 if(peek == '\n' || peek == ' ' || peek == '\t' || peek == '|' || peek == '/'){
427 if(prev != '\n' && scon != TRUE) goto character; /* valid only at line begin */
444 case '{': /* either iteration or definition */
445 if(isdigit(c=gch())){ /* iteration */
454 yylval.i = atol((char*)token);
458 } else { /* definition */
465 i = lookup(token,def);
467 warning("Definition %s not found",token);
472 case '<': /* start condition ? */
473 if(prev != '\n') /* not at line begin, not start */
479 while(c != ',' && c && c != '>'){
486 i = lookup(token,sname);
488 warning("Undefined start condition %s",token);
492 } while(c && c != '>');
494 /* check if previous value re-usable */
495 for (xp=slist; xp<t; ){
496 if (strcmp((char*)xp, (char*)t)==0)
501 /* re-use previous pointer to string */
505 if(slptr > slist+STARTSIZE) /* note not packed ! */
506 error("Too many start conditions used");
512 while((c=gch()) && c != '"' && c != '\n'){
513 if(c == '\\') c = usescape(gch());
516 warning("String too long");
523 warning("Non-terminated string");
537 for(i=1;i<NCH;i++) symbol[i] = 0;
539 if((c = gch()) == '^'){
543 while(c != ']' && c){
544 if(c == '\\') c = usescape(gch());
547 if((c=gch()) == '-' && peek != ']'){ /* range specified */
549 if(c == '\\') c = usescape(gch());
556 if(!(('A' <= j && k <= 'Z') ||
557 ('a' <= j && k <= 'z') ||
558 ('0' <= j && k <= '9')))
559 warning("Non-portable Character Class");
561 symbol[n] = 1; /* implementation dependent */
565 /* try to pack ccl's */
568 if(symbol[j])token[i++] = j;
571 while(p <ccptr && strcmp((char*)token,(char*)p) != 0)p++;
572 if(p < ccptr) /* found it */
576 strcpy((char*)ccptr,(char*)token);
577 ccptr += strlen((char*)token) + 1;
578 if(ccptr >= ccl+CCLSIZE)
579 error("Too many large character classes");
587 if(iter){ /* second part of an iteration */
589 if('0' <= c && c <= '9')
598 if(peek == '?' || peek == '*' || peek == '+')
612 if(x == SCON)scon = TRUE;
621 Bprint(&fout,"\n/*this comes from section three - debug */\n");
623 while(getl(buf) && !eof)
624 Bprint(&fout,"%s\n",(char*)buf);
633 print("now return ");
634 if(i < NCH) allprint(i);
636 printf(" yylval = ");
638 case STR: case CCL: case NCCL:
645 print("%d",yylval.i);