📄 yyrecover.c
字号:
tokname(&ACtok , 0 ), tokname(&ACtok , 1 )); copy((char *) (&YC[0]), (char *) (&ACtok), sizeof YC[0]); i = 0; yyshifts = 0; break; /* * Insert a token. * Don't count this token as a true input shift. * For inserted "end"s pas.y is responsible * for the error message later so suppress it. * Restore all the lookahead. */ case CINSERT: if (acchar == YEOF) yyexeof(); if (acchar != YEND) yerror("Inserted %s%s", tokname(&ACtok , 0 ), tokname(&ACtok , 1 )); yytshifts--; i = 0; yyshifts = 0; break; /* * Make a unique symbol correction. * Like an insertion but a different message. */ case CUNIQUE: setpfx('E'); yerror("Expected %s%s", tokname(&ACtok , 0 ), tokname(&ACtok , 1 )); yytshifts--; i = 0; if (ccost == 0 || yyunique) yyshifts = 0; else yyshifts = -1; break; /* * Change an identifier's type * to make it work. */ case CCHIDENT: copy((char *) (&Y), (char *) (&OY), sizeof Y);#ifdef PI i = 1 << yyrwant;#endif if (yyrhave == NIL) { yerror("Undefined %s", classes[yyrwant]);#ifdef PI i |= ISUNDEF;#endif } else yerror("Replaced %s id with a %s id", classes[yyrhave], classes[yyrwant]);#ifdef PI (void) yybaduse(yypv[0].cptr, yyeline, i);#endif yypv[0].i_entry = nullsem(YID); i = 0; yyshifts = 0; break; } /* * Restore the desired portion of the lookahead, * and possibly the inserted or unique inserted token. */ for (yCcnt--; yCcnt >= i; yCcnt--) unyylex(&YC[yCcnt]); if (cact == CINSERT || cact == CUNIQUE) unyylex(&ACtok); /* * Put the scanner back in sync. */ yychar = yylex(); /* * We succeeded if we didn't "panic". */ Recovery = FALSE; Ps = Ps0; return (cact != CPANIC);}yyexeof(){ yerror("End-of-file expected - QUIT"); pexit(ERRS);}yyunexeof(){ yerror("Unexpected end-of-file - QUIT"); pexit(ERRS);}/* * Try corrections with the state at Ps0. * Flag is 0 if this is the top of stack state, * 1 if it is the state below. */trystate(Ps0, Pv0, flag, insmult, delmult, repmult) int *Ps0, *Pv0, flag; char *insmult, *delmult, *repmult;{ /* * C is a working cost, ap a pointer into the action * table for looking at feasible alternatives. */ register int c, *ap;#ifdef DEBUG Eprintf("Trying state %d\n", *Ps0);#endif /* * Try deletion. * Correct returns a cost. */#ifdef DEBUG Tprintf(" Try Delete %s%s cost=%d\n", tokname(&YC[0] , 0 ), tokname(&YC[0] , 1 ), delcost(YC[0].Yychar));#endif c = delcost(YC[0].Yychar);#ifndef DEBUG if (c < ccost) {#endif c = correct(NOCHAR, 1, c, delmult, Ps0, Pv0);#ifdef DEBUG if (c < CPRLIMIT || fulltrace) Eprintf("Cost %2d Delete %s%s\n", c, tokname(&YC[0] , 0 ), tokname(&YC[0] , 1 ));#endif if (c < ccost) cact = CDELETE, ccost = c, cflag = flag;#ifndef DEBUG }#endif /* * Look at the inputs to this state * which will cause parse action shift. */ aclval = NIL; ap = &yyact[yypact[*Ps0 + 1]]; /* * Skip action on error to * detect true unique inputs. * Error action is always first. */ if (*ap == -ERROR) ap += 2; /* * Loop through the test actions * for this state. */ for (; *ap <= 0; ap += 2) { /* * Extract the token of this action */ acchar = -*ap; /* * Try insertion */#ifdef DEBUG Tprintf(" Try Insert %s%s cost=%d\n" , charname(acchar , 0 ) , charname(acchar , 1 ) , inscost(acchar, YC[0].Yychar));#endif c = inscost(acchar, YC[0].Yychar);#ifndef DEBUG if (c < ccost) {#endif if (c == 0) { c = correct(acchar, 0, 1, insmult + 1, Ps0, Pv0);#ifdef DEBUG Eprintf("Cost %2d Freebie %s%s\n", c , charname(acchar , 0 ) , charname(acchar , 1 ));#endif if (c < ccost) cact = CUNIQUE, ccost = 0, cchar = acchar, cflag = flag; } else { c = correct(acchar, 0, c, insmult, Ps0, Pv0);#ifdef DEBUG if (c < CPRLIMIT || fulltrace) Eprintf("Cost %2d Insert %s%s\n", c , charname(acchar , 0 ) , charname(acchar , 1 ));#endif if (c < ccost) cact = CINSERT, ccost = c, cchar = acchar, cflag = flag; }#ifndef DEBUG }#endif /* * Try replacement */#ifdef DEBUG Tprintf(" Try Replace %s%s with %s%s cost=%d\n", tokname(&YC[0] , 0 ), tokname(&YC[0] , 1 ), charname(acchar , 0 ), charname(acchar , 1 ), repcost(YC[0].Yychar, acchar));#endif c = repcost(YC[0].Yychar, acchar);#ifndef DEBUG if (c < ccost) {#endif c = correct(acchar, 1, repcost(YC[0].Yychar, acchar), repmult, Ps0, Pv0);#ifdef DEBUG if (c < CPRLIMIT || fulltrace) Eprintf("Cost %2d Replace %s%s with %s%s\n", c, tokname(&YC[0] , 0 ), tokname(&YC[0] , 1 ), tokname(&ACtok , 0 ), tokname(&ACtok , 1 ));#endif if (c < ccost) cact = CREPLACE, ccost = c, cchar = acchar, cflag = flag;#ifndef DEBUG }#endif }}int *yCpv;char yyredfail;/* * The ntok structure is used to build a * scanner structure for tokens inserted * from the argument "fchar" to "correct" below. */static struct yytok ntok;/* * Compute the cost of a correction * C is the base cost for it. * Fchar is the first input character from * the current state, NOCHAR if none. * The rest of the inputs come from the array * YC, starting at origin and continuing to the * last character there, YC[yCcnt - 1].Yychar. * * The cost returned is INFINITE if this correction * allows no shifts, otherwise is weighted based * on the number of shifts this allows against the * maximum number possible with the available lookahead. */correct(fchar, origin, c, multvec, Ps0, Pv0) register int fchar, c; int origin; char *multvec; int *Ps0, *Pv0;{ register char *mv; extern int *loccor(); /* * Ps is the top of the parse stack after the most * recent local correctness check. Loccor returns * NIL when we cannot shift. */ register int *ps; yyredfail = 0; /* * Initialize the tip parse and semantic stacks. */ ps = Ps0; yytips[0] = *ps; ps--; yytipv[0] = Pv0[0]; yCpv = Pv0 - 1; yytipct = 1; /* * Shift while possible. * Adjust cost as necessary. */ mv = multvec; do { if (fchar != NOCHAR) { copy((char *) (&ntok), (char *) (&YC[0]), sizeof ntok); ntok.Yychar = fchar, ntok.Yylval = nullsem(fchar); fchar = NOCHAR; ps = loccor(ps, &ntok); } else ps = loccor(ps, &YC[origin++]); if (ps == NIL) { if (yyredfail && mv > multvec) mv--; c *= *mv; break; } mv++; } while (*mv != 1); return (c);}extern int yygo[], yypgo[], yyr1[], yyr2[];/* * Local syntactic correctness check. * The arguments to this routine are a * top of stack pointer, ps, and an input * token tok. Also, implicitly, the contents * of the yytips array which contains the tip * of the stack, and into which the new top * state on the stack will be placed if we shift. * * If we succeed, we return a new top of stack * pointer, else we return NIL. */int *loccor(ps, ntok) int *ps; struct yytok *ntok;{ register int *p, n; register int nchar; int i; if (ps == NIL) return (NIL); nchar = ntok->Yychar; yyeline = ntok->Yyeline;#ifdef DEBUG Tprintf(" Stack "); for (i = yytipct - 1; i >= 0; i--) Tprintf("%d ", yytips[i]); Tprintf("| %d, Input %s%s\n", *ps , charname(nchar , 0 ) , charname(nchar , 1 ));#endif /* * As in the yacc parser yyparse, * p traces through the action list * and "n" is the information associated * with the action. */newstate: p = &yyact[ yypact[yytips[yytipct - 1]+1] ]; /* * Search the parse actions table * for something useful to do. * While n is non-positive, it is the * arithmetic inverse of the token to be tested. * This allows a fast check. */ while ((n = *p++) <= 0) if ((n += nchar) != 0) p++; switch (n >> 12) { /* * SHIFT */ default: panic("loccor"); case 2: n &= 07777; yyredfail = 0; if (nchar == YID) yyredfail++; if (yytipct == YYTIPSIZ) {tipover:#ifdef DEBUG Tprintf("\tTIP OVFLO\n");#endif return (NIL); } yytips[yytipct] = n; yytipv[yytipct] = ntok->Yylval; yytipct++;#ifdef DEBUG Tprintf("\tShift to state %d\n", n);#endif return (ps); /* * REDUCE */ case 3: n &= 07777; if (yyEactr(n, (char *) yytipv[yytipct - 1]) == 0) {#ifdef DEBUG Tprintf("\tYyEactr objects: have %s id, want %s id\n", classes[yyidhave], classes[yyidwant]);#endif return (NIL); } yyredfail = 0; i = yyr2[n];#ifdef DEBUG Tprintf("\tReduce, length %d,", i);#endif if (i > yytipct) { i -= yytipct; yytipct = 0; ps -= i; yCpv -= i; } else yytipct -= i; if (yytipct >= YYTIPSIZ) goto tipover; /* * Use goto table to find next state */ p = &yygo[yypgo[yyr1[n]]]; i = yytipct ? yytips[yytipct - 1] : *ps; while (*p != i && *p >= 0) p += 2;#ifdef DEBUG Tprintf(" new state %d\n", p[1]);#endif yytips[yytipct] = p[1]; yytipct++; goto newstate; /* * ACCEPT */ case 4:#ifdef DEBUG Tprintf("\tAccept\n");#endif return (ps); /* * ERROR */ case 1:#ifdef DEBUG Tprintf("\tError\n");#endif return (0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -