# 2.11BSD#431 - /usr/src/ucb/pascal/pxp/yyrecover.c

##### Functions

    correct           X
    loccor            X
    trystate          X
    yyexeof           X
    yyrecover         X
    yyunexeof         X

##### Variables

    ACtok             X
    YC                X
    YC0               X
    cact              X
    cchar             X
    ccost             X
    cflag             X
    delmult           X
    insmult           X
    repmult           X
    yCcnt             X
    yCpv              X
    yyTshifts         X
    yyact             X
    yypact            X
    yypv              X
    yyredfail         X
    yytipct           X
    yytips            X
    yytipv            X
    yyunique          X

##### Macros

    CCHIDCOST         X
    CCHIDENT          X
    CDELETE           X
    CINSERT           X
    CPANIC            X
    CPRLIMIT          X
    CREPLACE          X
    CUNIQUE           X
    Eprintf           X
    NOCHAR            X
    Tprintf           X
    YCSIZ             X
    YYTIPSIZ          X
    acchar            X
    aclval            X

       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

- in line 266, 543, 590, 597, 620

loccor defined in line 720; used 2 times

- in line 693-695(2)

trystate defined in line 518; used 2 times

- in line 279, 288

yyexeof defined in line 499; used 4 times

- in line 334, 410, 428
- in /usr/src/ucb/pascal/pxp/yyparse.c line 206

yyrecover defined in line 193; used 1 times

- in /usr/src/ucb/pascal/pxp/yyparse.c line 165

yyunexeof defined in line 506; used 1 times

- in /usr/src/ucb/pascal/pxp/yyparse.c line 204

#### Defined variables

ACtok defined in line 184; used 10 times

- in line 186-187(2), 359(2), 414-415(2), 430, 441, 484, 623

YC defined in line 161; used 28 times

- in line 203, 222, 234-236(3), 286-290(4), 307, 359, 400, 414-415(3), 482, 537-539(3), 546, 585, 614-623(5), 690-695(2)

YC0 defined in line 160; used 1 times

- in line 203

cact defined in line 177; used 12 times

- in line 227, 273, 325, 336, 364, 483(2), 496, 549, 595, 603, 626

cchar defined in line 177; used 9 times

- in line 273, 332-338(4), 360, 595, 603, 626

ccost defined in line 177; used 16 times

- in line 227, 272-273(2), 399, 444, 541, 548-549(2), 587, 594-595(2), 602-603(2), 618, 625-626(2)

cflag defined in line 177; used 6 times

- in line 227, 289, 549, 595, 603, 626

delmult defined in line 128; used 5 times

- in line 279, 288, 518-520(2), 543

insmult defined in line 126; used 6 times

- in line 279, 288, 518-520(2), 590, 597

ntok defined in line 641; used 10 times

- in line 690-693(5), 720-722(2), 730-731(2), 775

repmult defined in line 127; used 6 times

- in line 266, 279, 288, 518-520(2), 620

yCcnt defined in line 159; used 10 times

- in line 232-236(5), 297, 481-482(4)

yCpv defined in line 633; used 2 times

- in line 680, 801

yyTshifts defined in line 170; used 2 times

- in line 335, 347

yyact defined in line 138; used 3 times

- in line 328, 559, 745

yypact defined in line 138; used 3 times

- in line 328, 559, 745

yypv defined in line 138; used 11 times

- in line 264-267(4), 279, 288-292(2), 375, 381, 469-471(2)

yyredfail defined in line 634; used 5 times

- in line 672, 697, 764-766(2), 792

yytipct defined in line 149; used 17 times

- in line 681, 734, 745, 767, 774-776(3), 786, 797-804(5), 810(2), 816-817(2)

yytips defined in line 149; used 6 times

- in line 677, 735, 745, 774, 810, 816

yytipv defined in line 150; used 3 times

- in line 679, 775, 786

yyunique defined in line 168; used 1 times

- in line 444

#### Defined macros

CCHIDCOST defined in line 124; used 2 times

- in line 256, 266

CCHIDENT defined in line 89; used 1 times

- in line 273

CDELETE defined in line 85; used 1 times

- in line 549

CINSERT defined in line 87; used 2 times

- in line 483, 603

CPANIC defined in line 84; used 3 times

- in line 227, 325, 496

CPRLIMIT defined in line 123; used 4 times

- in line 269, 545, 599, 622

CREPLACE defined in line 86; used 1 times

- in line 626

CUNIQUE defined in line 88; used 3 times

- in line 336, 483, 595

Eprintf defined in line 132; used 9 times

- in line 236-240(2), 270, 338, 530, 546, 592, 600, 623

NOCHAR defined in line 130; used 4 times

- in line 266, 543, 689-692(2)

Tprintf defined in line 133; used 14 times

- in line 255, 537, 583, 613, 733-736(3), 770, 778, 788, 795, 814, 824, 832

YCSIZ defined in line 157; used 2 times

- in line 160, 232

YYTIPSIZ defined in line 148; used 4 times

- in line 149-150(2), 767, 804

acchar defined in line 186; used 22 times

- in line 360-361(2), 409-411(2), 427-429(2), 577, 583-603(9), 614-620(5), 626

aclval defined in line 187; used 4 times

- in line 361-362(2), 412, 558

Last modified: 1986-06-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2198 |