1: # 2: /* 3: * pi - Pascal interpreter code translator 4: * 5: * Charles Haley, Bill Joy UCB 6: * Version 1.2 January 1979 7: * 8: * 9: * pxp - Pascal execution profiler 10: * 11: * Bill Joy UCB 12: * Version 1.2 January 1979 13: */ 14: 15: #include "0.h" 16: #include "yy.h" 17: 18: /* 19: * Very simplified version of Graham-Rhodes error recovery 20: * method for LALR parsers. Backward move is embodied in 21: * default reductions of the yacc parser until an error condition 22: * is reached. Forward move is over a small number of input tokens 23: * and cannot "condense". The basic corrections are: 24: * 25: * 1) Delete the input token. 26: * 27: * 2) Replace the current input with a legal input. 28: * 29: * 3) Insert a legal token. 30: * 31: * All corrections are weighted, considered only if they allow 32: * at least two shifts, and the cost of a correction increases if 33: * it allows shifting over only a part of the lookahead. 34: * 35: * Another error situation is that which occurs when an identifier "fails" 36: * a reduction because it is not the required "class". 37: * In this case, we also consider replacing this identifier, which has 38: * already been shifted over, with an identifier of the correct class. 39: * 40: * Another correction performed here is unique symbol insertion. 41: * If the current state admits only one input, and no other alternative 42: * correction presents itself, then that symbol will be inserted. 43: * There is a danger in this of looping, and it is handled 44: * by counting true shifts over input (see below). 45: * 46: * 47: * A final class of corrections, considered only when the error 48: * occurred immediately after a shift over a terminal, involves 49: * the three basic corrections above, but with the point of error 50: * considered to be before this terminal was shifted over, effectively 51: * "unreading" this terminal. This is a feeble attempt at elimination 52: * of the left-right bias and because "if" has a low weight and some 53: * statements are quite simple i.e. 54: * 55: * cse ch of ... 56: * 57: * we can get a small number of errors. The major deficiency of 58: * this is that we back up only one token, and that the forward 59: * move is over a small number of tokens, often not enough to really 60: * tell what the input should be, e.g. in 61: * 62: * a[i] > a[i - 1] ... 63: * 64: * In such cases a bad identifier (misspelled keyword) or omitted 65: * keyword will be change or inserted as "if" as it has the lowest cost. 66: * This is not terribly bad, as "if"s are most common. 67: * This also allows the correction of other errors. 68: * 69: * This recovery depends on the default reductions which delay 70: * noticing the error until the parse reaches a state where the 71: * relevant "alternatives" are visible. Note that it does not 72: * consider tokens which will cause reductions before being 73: * shifted over. This requires the grammar to be written in a 74: * certain way for the recovery to work correctly. 75: * In some sense, also, the recovery suffers because we have 76: * LALR(1) tables rather than LR(1) tables, e.g. in 77: * 78: * if rec.field < rec2,field2 then 79: */ 80: 81: /* 82: * Definitions of possible corrective actions 83: */ 84: #define CPANIC 0 85: #define CDELETE 1 86: #define CREPLACE 2 87: #define CINSERT 3 88: #define CUNIQUE 4 89: #define CCHIDENT 5 90: 91: /* 92: * Multiplicative cost factors for corrective actions. 93: * 94: * When an error occurs we take YCSIZ - 1 look-ahead tokens. 95: * If a correction being considered will shift over only part of 96: * that look-ahead, it is not completely discarded, but rather 97: * "weighted", its cost being multiplied by a weighting factor. 98: * For a correction to be considered its weighted cost must be less 99: * than CLIMIT. 100: * 101: * Non-weighted costs are considered: 102: * 103: * LOW <= 3 104: * MEDIUM 4,5 105: * HIGH >= 6 106: * 107: * CURRENT WEIGHTING STRATEGY: Aug 20, 1977 108: * 109: * For all kinds of corrections we demand shifts over two symbols. 110: * Corrections have high weight even after two symbol 111: * shifts because the costs for deleting and inserting symbols are actually 112: * quite low; we do not want to change weighty symbols 113: * on inconclusive evidence. 114: * 115: * The weights are the same after the third look ahead. 116: * This prevents later, unrelated errors from causing "funny" 117: * biases of the weights toward one type of correction. 118: * 119: * Current look ahead is 5 symbols. 120: */ 121: 122: /*** CLIMIT is defined in yy.h for yycosts ***/ 123: #define CPRLIMIT 50 124: #define CCHIDCOST 3 125: 126: char insmult[8] = { INFINITY, INFINITY, INFINITY, 15, 8, 6, 3, 1 }; 127: char repmult[7] = { INFINITY, INFINITY, INFINITY, 8, 6, 3, 1 }; 128: char delmult[6] = { INFINITY, INFINITY, INFINITY, 6, 3, 1 }; 129: 130: #define NOCHAR -1 131: 132: #define Eprintf if (errtrace) printf 133: #define Tprintf if (testtrace) printf 134: 135: /* 136: * Action arrays of the parser needed here 137: */ 138: int yyact[], yypact[], *yypv; 139: 140: /* 141: * Yytips is the tip of the stack when using 142: * the function loccor to check for local 143: * syntactic correctness. As we don't want 144: * to copy the whole parser stack, but want 145: * to simulate parser moves, we "split" 146: * the parser stack and keep the tip here. 147: */ 148: #define YYTIPSIZ 16 149: int yytips[YYTIPSIZ], yytipct; 150: int yytipv[YYTIPSIZ]; 151: 152: /* 153: * The array YC saves the lookahead tokens for the 154: * forward moves. 155: * Yccnt is the number of tokens in the YC array. 156: */ 157: #define YCSIZ 6 158: 159: int yCcnt; 160: struct yytok YC0[YCSIZ + 1]; 161: struct yytok *YC; 162: 163: /* 164: * YCps gives the top of stack at 165: * the point of error. 166: */ 167: 168: char yyunique = 1; 169: 170: STATIC unsigned yyTshifts; 171: 172: /* 173: * Cact is the corrective action we have decided on 174: * so far, ccost its cost, and cchar the associated token. 175: * Cflag tells if the correction is over the previous input token. 176: */ 177: int cact, ccost, cchar, cflag; 178: 179: /* 180: * ACtok holds the token under 181: * consideration when examining 182: * the lookaheads in a state. 183: */ 184: struct yytok ACtok; 185: 186: #define acchar ACtok.Yychar 187: #define aclval ACtok.Yylval 188: 189: /* 190: * Make a correction to the current stack which has 191: * top of stack pointer Ps. 192: */ 193: yyrecover(Ps0, idfail) 194: int *Ps0, idfail; 195: { 196: register int c, i; 197: int yyrwant, yyrhave; 198: 199: #ifdef PI 200: Recovery = 1; 201: #endif 202: 203: YC = &YC0[1]; 204: #ifdef DEBUG 205: if (errtrace) { 206: setpfx('p'); 207: yerror("Point of error"); 208: printf("States %d %d ...", Ps0[0], Ps0[-1]); 209: if (idfail) 210: printf(" [Idfail]"); 211: putchar('\n'); 212: printf("Input %s%s", tokname(&Y)); 213: } 214: 215: #endif 216: /* 217: * We first save the current input token 218: * and its associated semantic information. 219: */ 220: if (yychar < 0) 221: yychar = yylex(); 222: copy(&YC[0], &Y, sizeof Y); 223: 224: /* 225: * Set the default action and cost 226: */ 227: cact = CPANIC, ccost = CLIMIT, cflag = 0; 228: 229: /* 230: * Peek ahead 231: */ 232: for (yCcnt = 1; yCcnt < YCSIZ; yCcnt++) { 233: yychar = yylex(); 234: copy(&YC[yCcnt], &Y, sizeof YC[0]); 235: #ifdef DEBUG 236: Eprintf(" | %s%s", tokname(&YC[yCcnt])); 237: #endif 238: } 239: #ifdef DEBUG 240: Eprintf("\n"); 241: #endif 242: 243: /* 244: * If we are here because a reduction failed, try 245: * correcting that. 246: */ 247: if (idfail) { 248: /* 249: * Save the particulars about 250: * the kind of identifier we want/have. 251: */ 252: yyrwant = yyidwant; 253: yyrhave = yyidhave; 254: #ifdef DEBUG 255: Tprintf(" Try Replace %s identifier with %s identifier cost=%d\n", 256: classes[yyidhave], classes[yyidwant], CCHIDCOST); 257: #endif 258: 259: /* 260: * Save the semantics of the ID on the 261: * stack, and null them out to free 262: * up the reduction in question. 263: */ 264: i = yypv[0]; 265: yypv[0] = nullsem(YID); 266: c = correct(NOCHAR, 0, CCHIDCOST, &repmult[2], Ps0, yypv); 267: yypv[0] = i; 268: #ifdef DEBUG 269: if (c < CPRLIMIT || fulltrace) 270: Eprintf("Cost %2d Replace %s identifier with %s identifier\n", c, classes[yyrhave], classes[yyrwant]); 271: #endif 272: if (c < ccost) 273: cact = CCHIDENT, ccost = c, cchar = YID; 274: } 275: 276: /* 277: * First try correcting the state we are in 278: */ 279: trystate(Ps0, yypv, 0, &insmult[1], &delmult[1], &repmult[1]); 280: 281: /* 282: * Now, if we just shifted over a terminal, try 283: * correcting it. 284: */ 285: if (OY.Yychar != -1 && OY.Yylval != nullsem(OY.Yychar)) { 286: YC--; 287: copy(&YC[0], &OY, sizeof YC[0]); 288: trystate(Ps0 - 1, yypv - 1, 1, insmult, delmult, repmult); 289: if (cflag == 0) 290: YC++; 291: else { 292: yypv--; 293: #ifdef PXP 294: yypw--; 295: #endif 296: Ps0--; 297: yCcnt++; 298: } 299: } 300: 301: /* 302: * Restoring the first look ahead into 303: * the scanner token allows the error message 304: * routine to print the error message with the text 305: * of the correct line. 306: */ 307: copy(&Y, &YC[0], sizeof Y); 308: 309: /* 310: * Unique symbol insertion. 311: * 312: * If there was no reasonable correction found, 313: * but only one input to the parser is acceptable 314: * we report that, and try it. 315: * 316: * Special precautions here to prevent looping. 317: * The number of true inputs shifted over at the point 318: * of the last unique insertion is recorded in the 319: * variable yyTshifts. If this is not less than 320: * the current number in yytshifts, we do not insert. 321: * Thus, after one unique insertion, no more unique 322: * insertions will be made until an input is shifted 323: * over. This guarantees termination. 324: */ 325: if (cact == CPANIC && !idfail) { 326: register int *ap; 327: 328: ap = &yyact[yypact[*Ps0 + 1]]; 329: if (*ap == -ERROR) 330: ap += 2; 331: if (ap[0] <= 0 && ap[2] > 0) { 332: cchar = -ap[0]; 333: if (cchar == YEOF) 334: yyexeof(); 335: if (cchar != ERROR && yyTshifts < yytshifts) { 336: cact = CUNIQUE; 337: #ifdef DEBUG 338: Eprintf("Unique symbol %s%s\n", charname(cchar)); 339: #endif 340: /* 341: * Note that the inserted symbol 342: * will not be counted as a true input 343: * (i.e. the "yytshifts--" below) 344: * so that a true shift will be needed 345: * to make yytshifts > yyTshifts. 346: */ 347: yyTshifts = yytshifts; 348: } 349: } 350: } 351: 352: /* 353: * Set up to perform the correction. 354: * Build a token appropriate for replacement 355: * or insertion in the yytok structure ACchar 356: * having the attributes of the input at the 357: * point of error. 358: */ 359: copy(&ACtok, &YC[0], sizeof ACtok); 360: acchar = cchar; 361: aclval = nullsem(acchar); 362: if (aclval != NIL) 363: recovered(); 364: switch (cact) { 365: /* 366: * Panic, just restore the 367: * lookahead and return. 368: */ 369: case CPANIC: 370: setpfx('E'); 371: if (idfail) { 372: copy(&Y, &OY, sizeof Y); 373: if (yyrhave == NIL) { 374: #ifdef PI 375: if (yybaduse(yypv[0], yyeline, ISUNDEF) == NIL) 376: #endif 377: yerror("Undefined identifier"); 378: } else { 379: yerror("Improper %s identifier", classes[yyrhave]); 380: #ifdef PI 381: yybaduse(yypv[0], yyeline, NIL); 382: #endif 383: } 384: /* 385: * Suppress message from panic routine 386: */ 387: yyshifts = 1; 388: } 389: i = 0; 390: /* Note that on one path we dont touch yyshifts ! */ 391: break; 392: /* 393: * Delete the input. 394: * Mark this as a shift over true input. 395: * Restore the lookahead starting at 396: * the second token. 397: */ 398: case CDELETE: 399: if (ccost != 0) 400: yerror("Deleted %s%s", tokname(&YC[0])); 401: yytshifts++; 402: i = 1; 403: yyshifts = 0; 404: break; 405: /* 406: * Replace the input with a new token. 407: */ 408: case CREPLACE: 409: if (acchar == YEOF) 410: yyexeof(); 411: if (acchar == YEND) 412: aclval = NIL; 413: yerror("Replaced %s%s with a %s%s", 414: tokname(&YC[0]), tokname(&ACtok)); 415: copy(&YC[0], &ACtok, sizeof YC[0]); 416: i = 0; 417: yyshifts = 0; 418: break; 419: /* 420: * Insert a token. 421: * Don't count this token as a true input shift. 422: * For inserted "end"s pas.y is responsible 423: * for the error message later so suppress it. 424: * Restore all the lookahead. 425: */ 426: case CINSERT: 427: if (acchar == YEOF) 428: yyexeof(); 429: if (acchar != YEND) 430: yerror("Inserted %s%s", tokname(&ACtok)); 431: yytshifts--; 432: i = 0; 433: yyshifts = 0; 434: break; 435: /* 436: * Make a unique symbol correction. 437: * Like an insertion but a different message. 438: */ 439: case CUNIQUE: 440: setpfx('E'); 441: yerror("Expected %s%s", tokname(&ACtok)); 442: yytshifts--; 443: i = 0; 444: if (ccost == 0 || yyunique) 445: yyshifts = 0; 446: else 447: yyshifts = -1; 448: break; 449: /* 450: * Change an identifier's type 451: * to make it work. 452: */ 453: case CCHIDENT: 454: copy(&Y, &OY, sizeof Y); 455: #ifdef PI 456: i = 1 << yyrwant; 457: #endif 458: if (yyrhave == NIL) { 459: yerror("Undefined %s", classes[yyrwant]); 460: #ifdef PI 461: i |= ISUNDEF; 462: #endif 463: } else 464: /* old... 465: yerror("Replaced %s id with a %s id", classes[yyrhave], classes[yyrwant]); 466: * ... replaced with new... */ 467: yerror("Expected %s (%s is a %s)", classes[yyrwant], yylval, classes[yyrhave]); 468: #ifdef PI 469: yybaduse(yypv[0], yyeline, i); 470: #endif 471: yypv[0] = nullsem(YID); 472: i = 0; 473: yyshifts = 0; 474: break; 475: } 476: 477: /* 478: * Restore the desired portion of the lookahead, 479: * and possibly the inserted or unique inserted token. 480: */ 481: for (yCcnt--; yCcnt >= i; yCcnt--) 482: unyylex(&YC[yCcnt]); 483: if (cact == CINSERT || cact == CUNIQUE) 484: unyylex(&ACtok); 485: 486: /* 487: * Put the scanner back in sync. 488: */ 489: yychar = yylex(); 490: 491: /* 492: * We succeeded if we didn't "panic". 493: */ 494: Recovery = 0; 495: Ps = Ps0; 496: return (cact != CPANIC); 497: } 498: 499: yyexeof() 500: { 501: 502: yerror("End-of-file expected - QUIT"); 503: pexit(ERRS); 504: } 505: 506: yyunexeof() 507: { 508: 509: yerror("Unexpected end-of-file - QUIT"); 510: pexit(ERRS); 511: } 512: 513: /* 514: * Try corrections with the state at Ps0. 515: * Flag is 0 if this is the top of stack state, 516: * 1 if it is the state below. 517: */ 518: trystate(Ps0, Pv0, flag, insmult, delmult, repmult) 519: int *Ps0, *Pv0, flag; 520: char *insmult, *delmult, *repmult; 521: { 522: /* 523: * C is a working cost, ap a pointer into the action 524: * table for looking at feasible alternatives. 525: */ 526: register int c, *ap; 527: int i, *actions; 528: 529: #ifdef DEBUG 530: Eprintf("Trying state %d\n", *Ps0); 531: #endif 532: /* 533: * Try deletion. 534: * Correct returns a cost. 535: */ 536: #ifdef DEBUG 537: Tprintf(" Try Delete %s%s cost=%d\n", tokname(&YC[0]), delcost(YC[0].Yychar)); 538: #endif 539: c = delcost(YC[0].Yychar); 540: #ifndef DEBUG 541: if (c < ccost) { 542: #endif 543: c = correct(NOCHAR, 1, c, delmult, Ps0, Pv0); 544: #ifdef DEBUG 545: if (c < CPRLIMIT || fulltrace) 546: Eprintf("Cost %2d Delete %s%s\n", c, tokname(&YC[0])); 547: #endif 548: if (c < ccost) 549: cact = CDELETE, ccost = c, cflag = flag; 550: #ifndef DEBUG 551: } 552: #endif 553: 554: /* 555: * Look at the inputs to this state 556: * which will cause parse action shift. 557: */ 558: aclval = NIL; 559: ap = &yyact[yypact[*Ps0 + 1]]; 560: 561: /* 562: * Skip action on error to 563: * detect true unique inputs. 564: * Error action is always first. 565: */ 566: if (*ap == -ERROR) 567: ap+= 2; 568: 569: /* 570: * Loop through the test actions 571: * for this state. 572: */ 573: for (actions = ap; *ap <= 0; ap += 2) { 574: /* 575: * Extract the token of this action 576: */ 577: acchar = -*ap; 578: 579: /* 580: * Try insertion 581: */ 582: #ifdef DEBUG 583: Tprintf(" Try Insert %s%s cost=%d\n", charname(acchar), inscost(acchar)); 584: #endif 585: c = inscost(acchar, YC[0].Yychar); 586: #ifndef DEBUG 587: if (c < ccost) { 588: #endif 589: if (c == 0) { 590: c = correct(acchar, 0, 1, insmult + 1, Ps0, Pv0); 591: #ifdef DEBUG 592: Eprintf("Cost %2d Freebie %s%s\n", c, charname(acchar)); 593: #endif 594: if (c < ccost) 595: cact = CUNIQUE, ccost = 0, cchar = acchar, cflag = flag; 596: } else { 597: c = correct(acchar, 0, c, insmult, Ps0, Pv0); 598: #ifdef DEBUG 599: if (c < CPRLIMIT || fulltrace) 600: Eprintf("Cost %2d Insert %s%s\n", c, charname(acchar)); 601: #endif 602: if (c < ccost) 603: cact = CINSERT, ccost = c, cchar = acchar, cflag = flag; 604: } 605: #ifndef DEBUG 606: } 607: #endif 608: 609: /* 610: * Try replacement 611: */ 612: #ifdef DEBUG 613: Tprintf(" Try Replace %s%s with %s%s cost=%d\n", 614: tokname(&YC[0]), charname(acchar), repcost(YC[0].Yychar, acchar)); 615: #endif 616: c = repcost(YC[0].Yychar, acchar); 617: #ifndef DEBUG 618: if (c < ccost) { 619: #endif 620: c = correct(acchar, 1, repcost(YC[0].Yychar, acchar), repmult, Ps0, Pv0); 621: #ifdef DEBUG 622: if (c < CPRLIMIT || fulltrace) 623: Eprintf("Cost %2d Replace %s%s with %s%s\n", c, tokname(&YC[0]), tokname(&ACtok)); 624: #endif 625: if (c < ccost) 626: cact = CREPLACE, ccost = c, cchar = acchar, cflag = flag; 627: #ifndef DEBUG 628: } 629: #endif 630: } 631: } 632: 633: int *yCpv; 634: char yyredfail; 635: 636: /* 637: * The ntok structure is used to build a 638: * scanner structure for tokens inserted 639: * from the argument "fchar" to "correct" below. 640: */ 641: static struct yytok ntok; 642: 643: /* 644: * Compute the cost of a correction 645: * C is the base cost for it. 646: * Fchar is the first input character from 647: * the current state, NOCHAR if none. 648: * The rest of the inputs come from the array 649: * YC, starting at origin and continuing to the 650: * last character there, YC[yCcnt - 1].Yychar. 651: * 652: * The cost returned is INFINITE if this correction 653: * allows no shifts, otherwise is weighted based 654: * on the number of shifts this allows against the 655: * maximum number possible with the available lookahead. 656: */ 657: correct(fchar, origin, c, multvec, Ps0, Pv0) 658: register int fchar, c; 659: int origin; 660: char *multvec; 661: int *Ps0, *Pv0; 662: { 663: register char *mv; 664: 665: /* 666: * Ps is the top of the parse stack after the most 667: * recent local correctness check. Loccor returns 668: * NIL when we cannot shift. 669: */ 670: register int *ps; 671: 672: yyredfail = 0; 673: /* 674: * Initialize the tip parse and semantic stacks. 675: */ 676: ps = Ps0; 677: yytips[0] = *ps; 678: ps--; 679: yytipv[0] = Pv0[0]; 680: yCpv = Pv0 - 1; 681: yytipct = 1; 682: 683: /* 684: * Shift while possible. 685: * Adjust cost as necessary. 686: */ 687: mv = multvec; 688: do { 689: if (fchar != NOCHAR) { 690: copy(&ntok, &YC[0], sizeof ntok); 691: ntok.Yychar = fchar, ntok.Yylval = nullsem(fchar); 692: fchar = NOCHAR; 693: ps = loccor(ps, &ntok); 694: } else 695: ps = loccor(ps, &YC[origin++]); 696: if (ps == NIL) { 697: if (yyredfail && mv > multvec) 698: mv--; 699: c *= *mv; 700: break; 701: } 702: mv++; 703: } while (*mv != 1); 704: return (c); 705: } 706: 707: extern int yygo[], yypgo[], yyr1[], yyr2[]; 708: /* 709: * Local syntactic correctness check. 710: * The arguments to this routine are a 711: * top of stack pointer, ps, and an input 712: * token tok. Also, implicitly, the contents 713: * of the yytips array which contains the tip 714: * of the stack, and into which the new top 715: * state on the stack will be placed if we shift. 716: * 717: * If we succeed, we return a new top of stack 718: * pointer, else we return NIL. 719: */ 720: loccor(ps, ntok) 721: int *ps; 722: struct yytok *ntok; 723: { 724: register int *p, n; 725: register int nchar; 726: int i; 727: 728: if (ps == NIL) 729: return (NIL); 730: nchar = ntok->Yychar; 731: yyeline = ntok->Yyeline; 732: #ifdef DEBUG 733: Tprintf(" Stack "); 734: for (i = yytipct - 1; i >= 0; i--) 735: Tprintf("%d ", yytips[i]); 736: Tprintf("| %d, Input %s%s\n", *ps, charname(nchar)); 737: #endif 738: /* 739: * As in the yacc parser yyparse, 740: * p traces through the action list 741: * and "n" is the information associated 742: * with the action. 743: */ 744: newstate: 745: p = &yyact[ yypact[yytips[yytipct - 1]+1] ]; 746: 747: actn: 748: /* 749: * Search the parse actions table 750: * for something useful to do. 751: * While n is non-positive, it is the 752: * arithmetic inverse of the token to be tested. 753: * This allows a fast check. 754: */ 755: while ((n = *p++) <= 0) 756: if ((n += nchar) != 0) 757: p++; 758: switch (n >> 12) { 759: /* 760: * SHIFT 761: */ 762: case 2: 763: n &= 07777; 764: yyredfail = 0; 765: if (nchar == YID) 766: yyredfail++; 767: if (yytipct == YYTIPSIZ) { 768: tipover: 769: #ifdef DEBUG 770: Tprintf("\tTIP OVFLO\n"); 771: #endif 772: return (NIL); 773: } 774: yytips[yytipct] = n; 775: yytipv[yytipct] = ntok->Yylval; 776: yytipct++; 777: #ifdef DEBUG 778: Tprintf("\tShift to state %d\n", n); 779: #endif 780: return (ps); 781: /* 782: * REDUCE 783: */ 784: case 3: 785: n &= 07777; 786: if (yyEactr(n, yytipv[yytipct - 1]) == 0) { 787: #ifdef DEBUG 788: Tprintf("\tYyEactr objects: have %s id, want %s id\n", classes[yyidhave], classes[yyidwant]); 789: #endif 790: return (NIL); 791: } 792: yyredfail = 0; 793: i = yyr2[n]; 794: #ifdef DEBUG 795: Tprintf("\tReduce, length %d,", i); 796: #endif 797: if (i > yytipct) { 798: i -= yytipct; 799: yytipct = 0; 800: ps -= i; 801: yCpv -= i; 802: } else 803: yytipct -= i; 804: if (yytipct >= YYTIPSIZ) 805: goto tipover; 806: /* 807: * Use goto table to find next state 808: */ 809: p = &yygo[yypgo[yyr1[n]]]; 810: i = yytipct ? yytips[yytipct - 1] : *ps; 811: while (*p != i && *p >= 0) 812: p += 2; 813: #ifdef DEBUG 814: Tprintf(" new state %d\n", p[1]); 815: #endif 816: yytips[yytipct] = p[1]; 817: yytipct++; 818: goto newstate; 819: /* 820: * ACCEPT 821: */ 822: case 4: 823: #ifdef DEBUG 824: Tprintf("\tAccept\n"); 825: #endif 826: return (ps); 827: /* 828: * ERROR 829: */ 830: case 1: 831: #ifdef DEBUG 832: Tprintf("\tError\n"); 833: #endif 834: return (0); 835: } 836: panic("loccor"); 837: }