plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

sub1.c (10164B)


      1 # include "ldefs.h"
      2 uchar *
      3 getl(uchar *p)	/* return next line of input, throw away trailing '\n' */
      4 	/* returns 0 if eof is had immediately */
      5 {
      6 	int c;
      7 	uchar *s, *t;
      8 
      9 	t = s = p;
     10 	while(((c = gch()) != 0) && c != '\n')
     11 		*t++ = c;
     12 	*t = 0;
     13 	if(c == 0 && s == t) return((uchar *)0);
     14 	prev = '\n';
     15 	pres = '\n';
     16 	return(s);
     17 }
     18 
     19 void
     20 printerr(char *type, char *fmt, va_list argl)
     21 {
     22 	char buf[1024];
     23 
     24 	if(!eof)fprint(errorf,"%d: ",yyline);
     25 	fprint(errorf,"(%s) ", type);
     26 	vseprint(buf, buf+sizeof(buf), fmt, argl);
     27 	fprint(errorf, "%s\n", buf);
     28 }
     29 
     30 
     31 void
     32 error(char *s,...)
     33 {
     34 	va_list argl;
     35 
     36 	va_start(argl, s);
     37 	printerr("Error", s, argl);
     38 	va_end(argl);
     39 # ifdef DEBUG
     40 	if(debug && sect != ENDSECTION) {
     41 		sect1dump();
     42 		sect2dump();
     43 	}
     44 # endif
     45 	if(
     46 # ifdef DEBUG
     47 		debug ||
     48 # endif
     49 		report == 1) statistics();
     50 	exits("error");	/* error return code */
     51 }
     52 
     53 void
     54 warning(char *s,...)
     55 {
     56 	va_list argl;
     57 
     58 	va_start(argl, s);
     59 	printerr("Warning", s, argl);
     60 	va_end(argl);
     61 	Bflush(&fout);
     62 }
     63 
     64 void
     65 lgate(void)
     66 {
     67 	int fd;
     68 
     69 	if (lgatflg) return;
     70 	lgatflg=1;
     71 	if(foutopen == 0){
     72 		fd = create("lex.yy.c", OWRITE, 0666);
     73 		if(fd < 0)
     74 			error("Can't open lex.yy.c");
     75 		Binit(&fout, fd, OWRITE);
     76 		foutopen = 1;
     77 		}
     78 	phead1();
     79 }
     80 
     81 void
     82 cclinter(int sw)
     83 {
     84 		/* sw = 1 ==> ccl */
     85 	int i, j, k;
     86 	int m;
     87 	if(!sw){		/* is NCCL */
     88 		for(i=1;i<NCH;i++)
     89 			symbol[i] ^= 1;			/* reverse value */
     90 	}
     91 	for(i=1;i<NCH;i++)
     92 		if(symbol[i]) break;
     93 	if(i >= NCH) return;
     94 	i = cindex[i];
     95 	/* see if ccl is already in our table */
     96 	j = 0;
     97 	if(i){
     98 		for(j=1;j<NCH;j++){
     99 			if((symbol[j] && cindex[j] != i) ||
    100 			   (!symbol[j] && cindex[j] == i)) break;
    101 		}
    102 	}
    103 	if(j >= NCH) return;		/* already in */
    104 	m = 0;
    105 	k = 0;
    106 	for(i=1;i<NCH;i++)
    107 		if(symbol[i]){
    108 			if(!cindex[i]){
    109 				cindex[i] = ccount;
    110 				symbol[i] = 0;
    111 				m = 1;
    112 			} else k = 1;
    113 		}
    114 			/* m == 1 implies last value of ccount has been used */
    115 	if(m)ccount++;
    116 	if(k == 0) return;	/* is now in as ccount wholly */
    117 	/* intersection must be computed */
    118 	for(i=1;i<NCH;i++){
    119 		if(symbol[i]){
    120 			m = 0;
    121 			j = cindex[i];	/* will be non-zero */
    122 			for(k=1;k<NCH;k++){
    123 				if(cindex[k] == j){
    124 					if(symbol[k]) symbol[k] = 0;
    125 					else {
    126 						cindex[k] = ccount;
    127 						m = 1;
    128 					}
    129 				}
    130 			}
    131 			if(m)ccount++;
    132 		}
    133 	}
    134 }
    135 
    136 int
    137 usescape(int c)
    138 {
    139 	int d;
    140 	switch(c){
    141 	case 'n': c = '\n'; break;
    142 	case 'r': c = '\r'; break;
    143 	case 't': c = '\t'; break;
    144 	case 'b': c = '\b'; break;
    145 	case 'f': c = 014; break;		/* form feed for ascii */
    146 	case '0': case '1': case '2': case '3':
    147 	case '4': case '5': case '6': case '7':
    148 		c -= '0';
    149 		while('0' <= (d=gch()) && d <= '7'){
    150 			c = c * 8 + (d-'0');
    151 			if(!('0' <= peek && peek <= '7')) break;
    152 			}
    153 		break;
    154 	}
    155 	return(c);
    156 }
    157 
    158 int
    159 lookup(uchar *s, uchar **t)
    160 {
    161 	int i;
    162 	i = 0;
    163 	while(*t){
    164 		if(strcmp((char *)s, *(char **)t) == 0)
    165 			return(i);
    166 		i++;
    167 		t++;
    168 	}
    169 	return(-1);
    170 }
    171 
    172 int
    173 cpyact(void)
    174 { /* copy C action to the next ; or closing } */
    175 	int brac, c, mth;
    176 	int savline, sw;
    177 
    178 	brac = 0;
    179 	sw = TRUE;
    180 	savline = 0;
    181 
    182 while(!eof){
    183 	c = gch();
    184 swt:
    185 	switch( c ){
    186 
    187 case '|':	if(brac == 0 && sw == TRUE){
    188 			if(peek == '|')gch();		/* eat up an extra '|' */
    189 			return(0);
    190 		}
    191 		break;
    192 
    193 case ';':
    194 		if( brac == 0 ){
    195 			Bputc(&fout, c);
    196 			Bputc(&fout, '\n');
    197 			return(1);
    198 		}
    199 		break;
    200 
    201 case '{':
    202 		brac++;
    203 		savline=yyline;
    204 		break;
    205 
    206 case '}':
    207 		brac--;
    208 		if( brac == 0 ){
    209 			Bputc(&fout, c);
    210 			Bputc(&fout, '\n');
    211 			return(1);
    212 		}
    213 		break;
    214 
    215 case '/':	/* look for comments */
    216 		Bputc(&fout, c);
    217 		c = gch();
    218 		if( c != '*' ) goto swt;
    219 
    220 		/* it really is a comment */
    221 
    222 		Bputc(&fout, c);
    223 		savline=yyline;
    224 		while( c=gch() ){
    225 			if( c=='*' ){
    226 				Bputc(&fout, c);
    227 				if( (c=gch()) == '/' ) goto loop;
    228 			}
    229 			Bputc(&fout, c);
    230 		}
    231 		yyline=savline;
    232 		error( "EOF inside comment" );
    233 
    234 case '\'':	/* character constant */
    235 		mth = '\'';
    236 		goto string;
    237 
    238 case '"':	/* character string */
    239 		mth = '"';
    240 
    241 	string:
    242 
    243 		Bputc(&fout, c);
    244 		while( c=gch() ){
    245 			if( c=='\\' ){
    246 				Bputc(&fout, c);
    247 				c=gch();
    248 			}
    249 			else if( c==mth ) goto loop;
    250 			Bputc(&fout, c);
    251 			if (c == '\n') {
    252 				yyline--;
    253 				error( "Non-terminated string or character constant");
    254 			}
    255 		}
    256 		error( "EOF in string or character constant" );
    257 
    258 case '\0':
    259 		yyline = savline;
    260 		error("Action does not terminate");
    261 default:
    262 		break;		/* usual character */
    263 		}
    264 loop:
    265 	if(c != ' ' && c != '\t' && c != '\n') sw = FALSE;
    266 	Bputc(&fout, c);
    267 	}
    268 	error("Premature EOF");
    269 	return(0);
    270 }
    271 
    272 int
    273 gch(void){
    274 	int c;
    275 	prev = pres;
    276 	c = pres = peek;
    277 	peek = pushptr > pushc ? *--pushptr : Bgetc(fin);
    278 	if(peek == Beof && sargc > 1){
    279 		Bterm(fin);
    280 		fin = Bopen(sargv[fptr++],OREAD);
    281 		if(fin == 0)
    282 			error("Cannot open file %s",sargv[fptr-1]);
    283 		peek = Bgetc(fin);
    284 		sargc--;
    285 		sargv++;
    286 	}
    287 	if(c == Beof) {
    288 		eof = TRUE;
    289 		Bterm(fin);
    290 		fin = 0;
    291 		return(0);
    292 	}
    293 	if(c == '\n')yyline++;
    294 	return(c);
    295 }
    296 
    297 int
    298 mn2(int a, int d, uintptr c)
    299 {
    300 	name[tptr] = a;
    301 	left[tptr] = d;
    302 	right[tptr] = c;
    303 	parent[tptr] = 0;
    304 	nullstr[tptr] = 0;
    305 	switch(a){
    306 	case RSTR:
    307 		parent[d] = tptr;
    308 		break;
    309 	case BAR:
    310 	case RNEWE:
    311 		if(nullstr[d] || nullstr[c]) nullstr[tptr] = TRUE;
    312 		parent[d] = parent[c] = tptr;
    313 		break;
    314 	case RCAT:
    315 	case DIV:
    316 		if(nullstr[d] && nullstr[c])nullstr[tptr] = TRUE;
    317 		parent[d] = parent[c] = tptr;
    318 		break;
    319 	case RSCON:
    320 		parent[d] = tptr;
    321 		nullstr[tptr] = nullstr[d];
    322 		break;
    323 # ifdef DEBUG
    324 	default:
    325 		warning("bad switch mn2 %d %d",a,d);
    326 		break;
    327 # endif
    328 		}
    329 	if(tptr > treesize)
    330 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
    331 	return(tptr++);
    332 }
    333 
    334 int
    335 mnp(int a, void *p)
    336 {
    337 	name[tptr] = a;
    338 	left[tptr] = 0;
    339 	parent[tptr] = 0;
    340 	nullstr[tptr] = 0;
    341 	ptr[tptr] = p;
    342 	switch(a){
    343 	case RCCL:
    344 	case RNCCL:
    345 		if(strlen(p) == 0) nullstr[tptr] = TRUE;
    346 		break;
    347 	default:
    348 		error("bad switch mnp %d %P", a, p);
    349 		break;
    350 	}
    351 	if(tptr > treesize)
    352 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
    353 	return(tptr++);
    354 }
    355 
    356 int
    357 mn1(int a, int d)
    358 {
    359 	name[tptr] = a;
    360 	left[tptr] = d;
    361 	parent[tptr] = 0;
    362 	nullstr[tptr] = 0;
    363 	switch(a){
    364 	case STAR:
    365 	case QUEST:
    366 		nullstr[tptr] = TRUE;
    367 		parent[d] = tptr;
    368 		break;
    369 	case PLUS:
    370 	case CARAT:
    371 		nullstr[tptr] = nullstr[d];
    372 		parent[d] = tptr;
    373 		break;
    374 	case S2FINAL:
    375 		nullstr[tptr] = TRUE;
    376 		break;
    377 # ifdef DEBUG
    378 	case FINAL:
    379 	case S1FINAL:
    380 		break;
    381 	default:
    382 		warning("bad switch mn1 %d %d",a,d);
    383 		break;
    384 # endif
    385 	}
    386 	if(tptr > treesize)
    387 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
    388 	return(tptr++);
    389 }
    390 
    391 int
    392 mn0(int a)
    393 {
    394 	name[tptr] = a;
    395 	parent[tptr] = 0;
    396 	nullstr[tptr] = 0;
    397 	if(a >= NCH) switch(a){
    398 	case RNULLS: nullstr[tptr] = TRUE; break;
    399 # ifdef DEBUG
    400 	default:
    401 		warning("bad switch mn0 %d",a);
    402 		break;
    403 # endif
    404 	}
    405 	if(tptr > treesize)
    406 		error("Parse tree too big %s",(treesize == TREESIZE?"\nTry using %e num":""));
    407 	return(tptr++);
    408 }
    409 
    410 void
    411 munputc(int p)
    412 {
    413 	*pushptr++ = peek;		/* watch out for this */
    414 	peek = p;
    415 	if(pushptr >= pushc+TOKENSIZE)
    416 		error("Too many characters pushed");
    417 }
    418 
    419 void
    420 munputs(uchar *p)
    421 {
    422 	int i,j;
    423 	*pushptr++ = peek;
    424 	peek = p[0];
    425 	i = strlen((char*)p);
    426 	for(j = i-1; j>=1; j--)
    427 		*pushptr++ = p[j];
    428 	if(pushptr >= pushc+TOKENSIZE)
    429 		error("Too many characters pushed");
    430 }
    431 
    432 int
    433 dupl(int n)
    434 {
    435 	/* duplicate the subtree whose root is n, return ptr to it */
    436 	int i;
    437 
    438 	i = name[n];
    439 	if(i < NCH) return(mn0(i));
    440 	switch(i){
    441 	case RNULLS:
    442 		return(mn0(i));
    443 	case RCCL: case RNCCL:
    444 		return(mnp(i,ptr[n]));
    445 	case FINAL: case S1FINAL: case S2FINAL:
    446 		return(mn1(i,left[n]));
    447 	case STAR: case QUEST: case PLUS: case CARAT:
    448 		return(mn1(i,dupl(left[n])));
    449 	case RSTR: case RSCON:
    450 		return(mn2(i,dupl(left[n]),right[n]));
    451 	case BAR: case RNEWE: case RCAT: case DIV:
    452 		return(mn2(i,dupl(left[n]),dupl(right[n])));
    453 # ifdef DEBUG
    454 	default:
    455 		warning("bad switch dupl %d",n);
    456 # endif
    457 	}
    458 	return(0);
    459 }
    460 
    461 # ifdef DEBUG
    462 void
    463 allprint(int c)
    464 {
    465 	if(c < 0)
    466 		c += 256;	/* signed char */
    467 	switch(c){
    468 		case 014:
    469 			print("\\f");
    470 			charc++;
    471 			break;
    472 		case '\n':
    473 			print("\\n");
    474 			charc++;
    475 			break;
    476 		case '\t':
    477 			print("\\t");
    478 			charc++;
    479 			break;
    480 		case '\b':
    481 			print("\\b");
    482 			charc++;
    483 			break;
    484 		case ' ':
    485 			print("\\\bb");
    486 			break;
    487 		default:
    488 			if(!isprint(c)){
    489 				print("\\%-3o",c);
    490 				charc += 3;
    491 			} else
    492 				print("%c", c);
    493 			break;
    494 	}
    495 	charc++;
    496 }
    497 
    498 void
    499 strpt(uchar *s)
    500 {
    501 	charc = 0;
    502 	while(*s){
    503 		allprint(*s++);
    504 		if(charc > LINESIZE){
    505 			charc = 0;
    506 			print("\n\t");
    507 		}
    508 	}
    509 }
    510 
    511 void
    512 sect1dump(void)
    513 {
    514 	int i;
    515 
    516 	print("Sect 1:\n");
    517 	if(def[0]){
    518 		print("str	trans\n");
    519 		i = -1;
    520 		while(def[++i])
    521 			print("%s\t%s\n",def[i],subs[i]);
    522 	}
    523 	if(sname[0]){
    524 		print("start names\n");
    525 		i = -1;
    526 		while(sname[++i])
    527 			print("%s\n",sname[i]);
    528 	}
    529 }
    530 
    531 void
    532 sect2dump(void)
    533 {
    534 	print("Sect 2:\n");
    535 	treedump();
    536 }
    537 
    538 void
    539 treedump(void)
    540 {
    541 	int t;
    542 	uchar *p;
    543 	print("treedump %d nodes:\n",tptr);
    544 	for(t=0;t<tptr;t++){
    545 		print("%4d ",t);
    546 		parent[t] ? print("p=%4d",parent[t]) : print("      ");
    547 		print("  ");
    548 		if(name[t] < NCH)
    549 				allprint(name[t]);
    550 		else switch(name[t]){
    551 			case RSTR:
    552 				print("%d ",left[t]);
    553 				allprint(right[t]);
    554 				break;
    555 			case RCCL:
    556 				print("ccl ");
    557 				allprint(ptr[t]);
    558 				break;
    559 			case RNCCL:
    560 				print("nccl ");
    561 				allprint(ptr[t]);
    562 				break;
    563 			case DIV:
    564 				print("/ %d %d",left[t],right[t]);
    565 				break;
    566 			case BAR:
    567 				print("| %d %d",left[t],right[t]);
    568 				break;
    569 			case RCAT:
    570 				print("cat %d %d",left[t],right[t]);
    571 				break;
    572 			case PLUS:
    573 				print("+ %d",left[t]);
    574 				break;
    575 			case STAR:
    576 				print("* %d",left[t]);
    577 				break;
    578 			case CARAT:
    579 				print("^ %d",left[t]);
    580 				break;
    581 			case QUEST:
    582 				print("? %d",left[t]);
    583 				break;
    584 			case RNULLS:
    585 				print("nullstring");
    586 				break;
    587 			case FINAL:
    588 				print("final %d",left[t]);
    589 				break;
    590 			case S1FINAL:
    591 				print("s1final %d",left[t]);
    592 				break;
    593 			case S2FINAL:
    594 				print("s2final %d",left[t]);
    595 				break;
    596 			case RNEWE:
    597 				print("new %d %d",left[t],right[t]);
    598 				break;
    599 			case RSCON:
    600 				p = (uchar *)right[t];
    601 				print("start %s",sname[*p++-1]);
    602 				while(*p)
    603 					print(", %s",sname[*p++-1]);
    604 				print(" %d",left[t]);
    605 				break;
    606 			default:
    607 				print("unknown %d %d %d",name[t],left[t],right[t]);
    608 				break;
    609 		}
    610 		if(nullstr[t])print("\t(null poss.)");
    611 		print("\n");
    612 	}
    613 }
    614 # endif