|
|
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 "whoami"
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: bool 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: pchr('\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"
343: , charname(cchar , 0 )
344: , charname(cchar , 1 ));
345: #endif
346: /*
347: * Note that the inserted symbol
348: * will not be counted as a true input
349: * (i.e. the "yytshifts--" below)
350: * so that a true shift will be needed
351: * to make yytshifts > yyTshifts.
352: */
353: yyTshifts = yytshifts;
354: }
355: }
356: }
357:
358: /*
359: * Set up to perform the correction.
360: * Build a token appropriate for replacement
361: * or insertion in the yytok structure ACchar
362: * having the attributes of the input at the
363: * point of error.
364: */
365: copy(&ACtok, &YC[0], sizeof ACtok);
366: acchar = cchar;
367: aclval = nullsem(acchar);
368: if (aclval != NIL)
369: recovered();
370: switch (cact) {
371: /*
372: * Panic, just restore the
373: * lookahead and return.
374: */
375: case CPANIC:
376: setpfx('E');
377: if (idfail) {
378: copy(&Y, &OY, sizeof Y);
379: if (yyrhave == NIL) {
380: #ifdef PI
381: if (yybaduse(yypv[0], yyeline, ISUNDEF) == NIL)
382: #endif
383: yerror("Undefined identifier");
384: } else {
385: yerror("Improper %s identifier", classes[yyrhave]);
386: #ifdef PI
387: yybaduse(yypv[0], yyeline, NIL);
388: #endif
389: }
390: /*
391: * Suppress message from panic routine
392: */
393: yyshifts = 1;
394: }
395: i = 0;
396: /* Note that on one path we dont touch yyshifts ! */
397: break;
398: /*
399: * Delete the input.
400: * Mark this as a shift over true input.
401: * Restore the lookahead starting at
402: * the second token.
403: */
404: case CDELETE:
405: if (ccost != 0)
406: yerror("Deleted %s%s", tokname(&YC[0] , 0 )
407: , tokname(&YC[0] , 1 ));
408: yytshifts++;
409: i = 1;
410: yyshifts = 0;
411: break;
412: /*
413: * Replace the input with a new token.
414: */
415: case CREPLACE:
416: if (acchar == YEOF)
417: yyexeof();
418: if (acchar == YEND)
419: aclval = NIL;
420: yerror("Replaced %s%s with a %s%s",
421: tokname(&YC[0] , 0 ),
422: tokname(&YC[0] , 1 ),
423: tokname(&ACtok , 0 ),
424: tokname(&ACtok , 1 ));
425: copy(&YC[0], &ACtok, sizeof YC[0]);
426: i = 0;
427: yyshifts = 0;
428: break;
429: /*
430: * Insert a token.
431: * Don't count this token as a true input shift.
432: * For inserted "end"s pas.y is responsible
433: * for the error message later so suppress it.
434: * Restore all the lookahead.
435: */
436: case CINSERT:
437: if (acchar == YEOF)
438: yyexeof();
439: if (acchar != YEND)
440: yerror("Inserted %s%s",
441: tokname(&ACtok , 0 ),
442: tokname(&ACtok , 1 ));
443: yytshifts--;
444: i = 0;
445: yyshifts = 0;
446: break;
447: /*
448: * Make a unique symbol correction.
449: * Like an insertion but a different message.
450: */
451: case CUNIQUE:
452: setpfx('E');
453: yerror("Expected %s%s",
454: tokname(&ACtok , 0 ),
455: tokname(&ACtok , 1 ));
456: yytshifts--;
457: i = 0;
458: if (ccost == 0 || yyunique)
459: yyshifts = 0;
460: else
461: yyshifts = -1;
462: break;
463: /*
464: * Change an identifier's type
465: * to make it work.
466: */
467: case CCHIDENT:
468: copy(&Y, &OY, sizeof Y);
469: #ifdef PI
470: i = 1 << yyrwant;
471: #endif
472: if (yyrhave == NIL) {
473: yerror("Undefined %s", classes[yyrwant]);
474: #ifdef PI
475: i =| ISUNDEF;
476: #endif
477: } else
478: yerror("Replaced %s id with a %s id", classes[yyrhave], classes[yyrwant]);
479: #ifdef PI
480: yybaduse(yypv[0], yyeline, i);
481: #endif
482: yypv[0] = nullsem(YID);
483: i = 0;
484: yyshifts = 0;
485: break;
486: }
487:
488: /*
489: * Restore the desired portion of the lookahead,
490: * and possibly the inserted or unique inserted token.
491: */
492: for (yCcnt--; yCcnt >= i; yCcnt--)
493: unyylex(&YC[yCcnt]);
494: if (cact == CINSERT || cact == CUNIQUE)
495: unyylex(&ACtok);
496:
497: /*
498: * Put the scanner back in sync.
499: */
500: yychar = yylex();
501:
502: /*
503: * We succeeded if we didn't "panic".
504: */
505: Recovery = 0;
506: Ps = Ps0;
507: return (cact != CPANIC);
508: }
509:
510: yyexeof()
511: {
512:
513: yerror("End-of-file expected - QUIT");
514: pexit(ERRS);
515: }
516:
517: yyunexeof()
518: {
519:
520: yerror("Unexpected end-of-file - QUIT");
521: pexit(ERRS);
522: }
523:
524: /*
525: * Try corrections with the state at Ps0.
526: * Flag is 0 if this is the top of stack state,
527: * 1 if it is the state below.
528: */
529: trystate(Ps0, Pv0, flag, insmult, delmult, repmult)
530: int *Ps0, *Pv0, flag;
531: char *insmult, *delmult, *repmult;
532: {
533: /*
534: * C is a working cost, ap a pointer into the action
535: * table for looking at feasible alternatives.
536: */
537: register int c, *ap;
538: int i, *actions;
539:
540: #ifdef DEBUG
541: Eprintf("Trying state %d\n", *Ps0);
542: #endif
543: /*
544: * Try deletion.
545: * Correct returns a cost.
546: */
547: #ifdef DEBUG
548: Tprintf(" Try Delete %s%s cost=%d\n",
549: tokname(&YC[0] , 0 ),
550: tokname(&YC[0] , 1 ),
551: delcost(YC[0].Yychar));
552: #endif
553: c = delcost(YC[0].Yychar);
554: #ifndef DEBUG
555: if (c < ccost) {
556: #endif
557: c = correct(NOCHAR, 1, c, delmult, Ps0, Pv0);
558: #ifdef DEBUG
559: if (c < CPRLIMIT || fulltrace)
560: Eprintf("Cost %2d Delete %s%s\n", c,
561: tokname(&YC[0] , 0 ),
562: tokname(&YC[0] , 1 ));
563: #endif
564: if (c < ccost)
565: cact = CDELETE, ccost = c, cflag = flag;
566: #ifndef DEBUG
567: }
568: #endif
569:
570: /*
571: * Look at the inputs to this state
572: * which will cause parse action shift.
573: */
574: aclval = NIL;
575: ap = &yyact[yypact[*Ps0 + 1]];
576:
577: /*
578: * Skip action on error to
579: * detect true unique inputs.
580: * Error action is always first.
581: */
582: if (*ap == -ERROR)
583: ap=+ 2;
584:
585: /*
586: * Loop through the test actions
587: * for this state.
588: */
589: for (actions = ap; *ap <= 0; ap =+ 2) {
590: /*
591: * Extract the token of this action
592: */
593: acchar = -*ap;
594:
595: /*
596: * Try insertion
597: */
598: #ifdef DEBUG
599: Tprintf(" Try Insert %s%s cost=%d\n"
600: , charname(acchar , 0 )
601: , charname(acchar , 1 )
602: , inscost(acchar));
603: #endif
604: c = inscost(acchar, YC[0].Yychar);
605: #ifndef DEBUG
606: if (c < ccost) {
607: #endif
608: if (c == 0) {
609: c = correct(acchar, 0, 1, insmult + 1, Ps0, Pv0);
610: #ifdef DEBUG
611: Eprintf("Cost %2d Freebie %s%s\n", c
612: , charname(acchar , 0 )
613: , charname(acchar , 1 ));
614: #endif
615: if (c < ccost)
616: cact = CUNIQUE, ccost = 0, cchar = acchar, cflag = flag;
617: } else {
618: c = correct(acchar, 0, c, insmult, Ps0, Pv0);
619: #ifdef DEBUG
620: if (c < CPRLIMIT || fulltrace)
621: Eprintf("Cost %2d Insert %s%s\n", c
622: , charname(acchar , 0 )
623: , charname(acchar , 1 ));
624: #endif
625: if (c < ccost)
626: cact = CINSERT, ccost = c, cchar = acchar, cflag = flag;
627: }
628: #ifndef DEBUG
629: }
630: #endif
631:
632: /*
633: * Try replacement
634: */
635: #ifdef DEBUG
636: Tprintf(" Try Replace %s%s with %s%s cost=%d\n",
637: tokname(&YC[0] , 0 ),
638: tokname(&YC[0] , 1 ),
639: charname(acchar , 0 ),
640: charname(acchar , 1 ),
641: repcost(YC[0].Yychar, acchar));
642: #endif
643: c = repcost(YC[0].Yychar, acchar);
644: #ifndef DEBUG
645: if (c < ccost) {
646: #endif
647: c = correct(acchar, 1, repcost(YC[0].Yychar, acchar), repmult, Ps0, Pv0);
648: #ifdef DEBUG
649: if (c < CPRLIMIT || fulltrace)
650: Eprintf("Cost %2d Replace %s%s with %s%s\n",
651: c,
652: tokname(&YC[0] , 0 ),
653: tokname(&YC[0] , 1 ),
654: tokname(&ACtok , 0 ),
655: tokname(&ACtok , 1 ));
656: #endif
657: if (c < ccost)
658: cact = CREPLACE, ccost = c, cchar = acchar, cflag = flag;
659: #ifndef DEBUG
660: }
661: #endif
662: }
663: }
664:
665: int *yCpv;
666: char yyredfail;
667:
668: /*
669: * The ntok structure is used to build a
670: * scanner structure for tokens inserted
671: * from the argument "fchar" to "correct" below.
672: */
673: static struct yytok ntok;
674:
675: /*
676: * Compute the cost of a correction
677: * C is the base cost for it.
678: * Fchar is the first input character from
679: * the current state, NOCHAR if none.
680: * The rest of the inputs come from the array
681: * YC, starting at origin and continuing to the
682: * last character there, YC[yCcnt - 1].Yychar.
683: *
684: * The cost returned is INFINITE if this correction
685: * allows no shifts, otherwise is weighted based
686: * on the number of shifts this allows against the
687: * maximum number possible with the available lookahead.
688: */
689: correct(fchar, origin, c, multvec, Ps0, Pv0)
690: register int fchar, c;
691: int origin;
692: char *multvec;
693: int *Ps0, *Pv0;
694: {
695: register char *mv;
696:
697: /*
698: * Ps is the top of the parse stack after the most
699: * recent local correctness check. Loccor returns
700: * NIL when we cannot shift.
701: */
702: register int *ps;
703:
704: yyredfail = 0;
705: /*
706: * Initialize the tip parse and semantic stacks.
707: */
708: ps = Ps0;
709: yytips[0] = *ps;
710: ps--;
711: yytipv[0] = Pv0[0];
712: yCpv = Pv0 - 1;
713: yytipct = 1;
714:
715: /*
716: * Shift while possible.
717: * Adjust cost as necessary.
718: */
719: mv = multvec;
720: do {
721: if (fchar != NOCHAR) {
722: copy(&ntok, &YC[0], sizeof ntok);
723: ntok.Yychar = fchar, ntok.Yylval = nullsem(fchar);
724: fchar = NOCHAR;
725: ps = loccor(ps, &ntok);
726: } else
727: ps = loccor(ps, &YC[origin++]);
728: if (ps == NIL) {
729: if (yyredfail && mv > multvec)
730: mv--;
731: c =* *mv;
732: break;
733: }
734: mv++;
735: } while (*mv != 1);
736: return (c);
737: }
738:
739: extern int yygo[], yypgo[], yyr1[], yyr2[];
740: /*
741: * Local syntactic correctness check.
742: * The arguments to this routine are a
743: * top of stack pointer, ps, and an input
744: * token tok. Also, implicitly, the contents
745: * of the yytips array which contains the tip
746: * of the stack, and into which the new top
747: * state on the stack will be placed if we shift.
748: *
749: * If we succeed, we return a new top of stack
750: * pointer, else we return NIL.
751: */
752: loccor(ps, ntok)
753: int *ps;
754: struct yytok *ntok;
755: {
756: register int *p, n;
757: register int nchar;
758: int i;
759:
760: if (ps == NIL)
761: return (NIL);
762: nchar = ntok->Yychar;
763: yyeline = ntok->Yyeline;
764: #ifdef DEBUG
765: Tprintf(" Stack ");
766: for (i = yytipct - 1; i >= 0; i--)
767: Tprintf("%d ", yytips[i]);
768: Tprintf("| %d, Input %s%s\n", *ps
769: , charname(nchar , 0 )
770: , charname(nchar , 1 ));
771: #endif
772: /*
773: * As in the yacc parser yyparse,
774: * p traces through the action list
775: * and "n" is the information associated
776: * with the action.
777: */
778: newstate:
779: p = &yyact[ yypact[yytips[yytipct - 1]+1] ];
780:
781: actn:
782: /*
783: * Search the parse actions table
784: * for something useful to do.
785: * While n is non-positive, it is the
786: * arithmetic inverse of the token to be tested.
787: * This allows a fast check.
788: */
789: while ((n = *p++) <= 0)
790: if ((n =+ nchar) != 0)
791: p++;
792: switch (n >> 12) {
793: /*
794: * SHIFT
795: */
796: case 2:
797: n =& 07777;
798: yyredfail = 0;
799: if (nchar == YID)
800: yyredfail++;
801: if (yytipct == YYTIPSIZ) {
802: tipover:
803: #ifdef DEBUG
804: Tprintf("\tTIP OVFLO\n");
805: #endif
806: return (NIL);
807: }
808: yytips[yytipct] = n;
809: yytipv[yytipct] = ntok->Yylval;
810: yytipct++;
811: #ifdef DEBUG
812: Tprintf("\tShift to state %d\n", n);
813: #endif
814: return (ps);
815: /*
816: * REDUCE
817: */
818: case 3:
819: n =& 07777;
820: if (yyEactr(n, yytipv[yytipct - 1]) == 0) {
821: #ifdef DEBUG
822: Tprintf("\tYyEactr objects: have %s id, want %s id\n", classes[yyidhave], classes[yyidwant]);
823: #endif
824: return (NIL);
825: }
826: yyredfail = 0;
827: i = yyr2[n];
828: #ifdef DEBUG
829: Tprintf("\tReduce, length %d,", i);
830: #endif
831: if (i > yytipct) {
832: i =- yytipct;
833: yytipct = 0;
834: ps =- i;
835: yCpv =- i;
836: } else
837: yytipct =- i;
838: if (yytipct >= YYTIPSIZ)
839: goto tipover;
840: /*
841: * Use goto table to find next state
842: */
843: p = &yygo[yypgo[yyr1[n]]];
844: i = yytipct ? yytips[yytipct - 1] : *ps;
845: while (*p != i && *p >= 0)
846: p =+ 2;
847: #ifdef DEBUG
848: Tprintf(" new state %d\n", p[1]);
849: #endif
850: yytips[yytipct] = p[1];
851: yytipct++;
852: goto newstate;
853: /*
854: * ACCEPT
855: */
856: case 4:
857: #ifdef DEBUG
858: Tprintf("\tAccept\n");
859: #endif
860: return (ps);
861: /*
862: * ERROR
863: */
864: case 1:
865: #ifdef DEBUG
866: Tprintf("\tError\n");
867: #endif
868: return (0);
869: }
870: panic("loccor");
871: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.