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

#### Defined functions

correct defined in line 690; used 5 times

- in line 271, 558, 610, 619, 648

loccor defined in line 753; used 2 times

- in line 726-728(2)

trystate defined in line 530; used 2 times

- in line 284, 293

yyexeof defined in line 511; used 4 times

- in line 339, 418, 439
- in /usr/src/ucb/pascal/pi/yyparse.c line 209

yyrecover defined in line 196; used 1 times

- in /usr/src/ucb/pascal/pi/yyparse.c line 168

yyunexeof defined in line 518; used 1 times

- in /usr/src/ucb/pascal/pi/yyparse.c line 207

#### Defined variables

ACtok defined in line 187; used 14 times

- in line 189-190(2), 366(2), 424-426(3), 442-443(2), 455-456(2), 496, 655-656(2)

YC defined in line 164; used 35 times

- in line 206, 226, 238-241(4), 291-295(4), 312, 366, 407-408(2), 422-426(4), 494, 550-554(4), 562-563(2), 605, 638-654(7), 723-728(2)

YC0 defined in line 163; used 1 times

- in line 206

cact defined in line 180; used 12 times

- in line 231, 278, 330, 341, 371, 495(2), 508, 566, 617, 627, 659

cchar defined in line 180; used 10 times

- in line 278, 337-345(5), 367, 617, 627, 659

ccost defined in line 180; used 16 times

- in line 231, 277-278(2), 406, 459, 556, 565-566(2), 607, 616-617(2), 626-627(2), 646, 658-659(2)

cflag defined in line 180; used 6 times

- in line 231, 294, 566, 617, 627, 659

delmult defined in line 131; used 5 times

- in line 284, 293, 530-532(2), 558

insmult defined in line 129; used 6 times

- in line 284, 293, 530-532(2), 610, 619

ntok defined in line 674; used 10 times

- in line 723-726(5), 753-755(2), 763-764(2), 810

repmult defined in line 130; used 6 times

- in line 271, 284, 293, 530-532(2), 648

yCcnt defined in line 162; used 11 times

- in line 236-241(6), 302, 493-494(4)

yCpv defined in line 666; used 2 times

- in line 713, 836

yyTshifts defined in line 173; used 2 times

- in line 340, 354

yyact defined in line 141; used 3 times

- in line 333, 576, 780

yypact defined in line 141; used 3 times

- in line 333, 576, 780

yypv defined in line 141; used 11 times

- in line 269-272(4), 284, 293-297(2), 382, 388, 481-483(2)

yyredfail defined in line 667; used 5 times

- in line 705, 730, 799-801(2), 827

yytipct defined in line 152; used 17 times

- in line 714, 767, 780, 802, 809-811(3), 821, 832-839(5), 845(2), 851-852(2)

yytips defined in line 152; used 6 times

- in line 710, 768, 780, 809, 845, 851

yytipv defined in line 153; used 3 times

- in line 712, 810, 821

#### Defined macros

CCHIDCOST defined in line 127; used 2 times

- in line 261, 271

CCHIDENT defined in line 92; used 1 times

- in line 278

CDELETE defined in line 88; used 1 times

- in line 566

CINSERT defined in line 90; used 2 times

- in line 495, 627

CPANIC defined in line 87; used 3 times

- in line 231, 330, 508

CPRLIMIT defined in line 126; used 4 times

- in line 274, 560, 621, 650

CREPLACE defined in line 89; used 1 times

- in line 659

CUNIQUE defined in line 91; used 3 times

- in line 341, 495, 617

Eprintf defined in line 135; used 9 times

- in line 240-245(2), 275, 343, 542, 561, 612, 622, 651

NOCHAR defined in line 133; used 4 times

- in line 271, 558, 722-725(2)

Tprintf defined in line 136; used 14 times

- in line 260, 549, 600, 637, 766-769(3), 805, 813, 823, 830, 849, 859, 867

YCSIZ defined in line 160; used 2 times

- in line 163, 236

YYTIPSIZ defined in line 151; used 4 times

- in line 152-153(2), 802, 839

acchar defined in line 189; used 26 times

- in line 367-368(2), 417-419(2), 438-440(2), 594, 601-627(12), 640-648(6), 659

aclval defined in line 190; used 4 times

- in line 368-369(2), 420, 575

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