# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/src/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

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

#### Defined functions

correct defined in line 691; used 5 times

- in line 271, 559, 611, 620, 649

loccor defined in line 755; used 3 times

- in line 698, 728-730(2)

trystate defined in line 532; used 2 times

- in line 285, 294

yyexeof defined in line 513; used 4 times

- in line 341, 420, 441
- in /usr/src/ucb/PORT/pascal/src/yyparse.c line 207

yyrecover defined in line 192; used 1 times

- in /usr/src/ucb/PORT/pascal/src/yyparse.c line 166

yyunexeof defined in line 520; used 2 times

- in /usr/src/ucb/PORT/pascal/src/yypanic.c line 62
- in /usr/src/ucb/PORT/pascal/src/yyparse.c line 205

#### Defined variables

ACtok defined in line 183; used 14 times

- in line 185-186(2), 368(2), 426-428(3), 444-445(2), 457-458(2), 498, 656-657(2)

YC defined in line 160; used 36 times

- in line 202, 226, 238-241(4), 292-297(4), 314, 368, 409-410(2), 424-428(4), 496, 551-555(4), 563-564(2), 604-606(2), 639-655(7), 725-730(2)

YC0 defined in line 159; used 1 times

- in line 202

cact defined in line 176; used 12 times

- in line 231, 279, 332, 343, 373, 497(2), 510, 567, 618, 628, 660

cchar defined in line 176; used 10 times

- in line 279, 339-347(5), 369, 618, 628, 660

ccost defined in line 176; used 16 times

- in line 231, 278-279(2), 408, 461, 557, 566-567(2), 608, 617-618(2), 627-628(2), 647, 659-660(2)

cflag defined in line 176; used 6 times

- in line 231, 296, 567, 618, 628, 660

delmult defined in line 126; used 5 times

- in line 285, 294, 532-534(2), 559

insmult defined in line 124; used 6 times

- in line 285, 294, 532-534(2), 611, 620

ntok defined in line 675; used 10 times

- in line 725-728(5), 756-758(2), 766-767(2), 814

repmult defined in line 125; used 6 times

- in line 271, 285, 295, 532-534(2), 649

sccsid defined in line 8; never used
yCcnt defined in line 158; used 11 times

- in line 236-241(6), 304, 495-496(4)

yCpv defined in line 667; used 2 times

- in line 715, 840

yyTshifts defined in line 169; used 2 times

- in line 342, 356

yyact defined in line 137; used 3 times

- in line 335, 577, 783

yypact defined in line 137; used 3 times

- in line 335, 577, 783

yypv defined in line 136; used 11 times

- in line 269-273(4), 285, 294-299(2), 384, 390, 483-485(2)

yyredfail defined in line 668; used 5 times

- in line 707, 732, 803-805(2), 831

yytipct defined in line 148; used 17 times

- in line 716, 770, 783, 806, 813-815(3), 825, 836-843(5), 849(2), 855-856(2)

yytips defined in line 148; used 6 times

- in line 712, 771, 783, 813, 849, 855

yytipv defined in line 149; used 3 times

- in line 714, 814, 825

#### Defined macros

CCHIDCOST defined in line 122; used 2 times

- in line 261, 271

CCHIDENT defined in line 87; used 1 times

- in line 279

CDELETE defined in line 83; used 1 times

- in line 567

CINSERT defined in line 85; used 2 times

- in line 497, 628

CPANIC defined in line 82; used 3 times

- in line 231, 332, 510

CPRLIMIT defined in line 121; used 4 times

- in line 275, 561, 622, 651

CREPLACE defined in line 84; used 1 times

- in line 660

CUNIQUE defined in line 86; used 3 times

- in line 343, 497, 618

Eprintf defined in line 130; used 9 times

- in line 240-245(2), 276, 345, 543, 562, 613, 623, 652

NOCHAR defined in line 128; used 4 times

- in line 271, 559, 724-727(2)

Tprintf defined in line 131; used 14 times

- in line 260, 550, 601, 638, 769-772(3), 809, 817, 827, 834, 853, 863, 871

YCSIZ defined in line 156; used 2 times

- in line 159, 236

YYTIPSIZ defined in line 147; used 4 times

- in line 148-149(2), 806, 843

acchar defined in line 185; used 26 times

- in line 369-370(2), 419-421(2), 440-442(2), 595, 602-628(12), 641-649(6), 660

aclval defined in line 186; used 4 times

- in line 370-371(2), 422, 576

Last modified: 1985-06-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2293 |