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