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