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: }

Defined functions

correct defined in line 657; used 5 times
loccor defined in line 720; used 2 times
trystate defined in line 518; used 2 times
yyexeof defined in line 499; used 4 times
yyrecover defined in line 193; used 1 times
yyunexeof defined in line 506; used 1 times

Defined variables

ACtok defined in line 184; used 10 times
YC defined in line 161; used 28 times
YC0 defined in line 160; used 1 times
cact defined in line 177; used 12 times
cchar defined in line 177; used 9 times
ccost defined in line 177; used 16 times
cflag defined in line 177; used 6 times
delmult defined in line 128; used 5 times
insmult defined in line 126; used 6 times
ntok defined in line 641; used 10 times
repmult defined in line 127; used 6 times
yCcnt defined in line 159; used 10 times
yCpv defined in line 633; used 2 times
yyTshifts defined in line 170; used 2 times
yyact defined in line 138; used 3 times
yypact defined in line 138; used 3 times
yypv defined in line 138; used 11 times
yyredfail defined in line 634; used 5 times
yytipct defined in line 149; used 17 times
yytips defined in line 149; used 6 times
yytipv defined in line 150; used 3 times
yyunique defined in line 168; used 1 times

Defined macros

CCHIDCOST defined in line 124; used 2 times
CCHIDENT defined in line 89; used 1 times
CDELETE defined in line 85; used 1 times
CINSERT defined in line 87; used 2 times
CPANIC defined in line 84; used 3 times
CPRLIMIT defined in line 123; used 4 times
CREPLACE defined in line 86; used 1 times
CUNIQUE defined in line 88; used 3 times
Eprintf defined in line 132; used 9 times
NOCHAR defined in line 130; used 4 times
Tprintf defined in line 133; used 14 times
YCSIZ defined in line 157; used 2 times
YYTIPSIZ defined in line 148; used 4 times
acchar defined in line 186; used 22 times
aclval defined in line 187; used 4 times
Last modified: 1986-06-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4440
Valid CSS Valid XHTML 1.0 Strict