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