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