Start development on BSD 2
[unix-history] / .ref-BSD-1 / pxp / yyrecover.c
CommitLineData
0a078d30
CH
1#
2/*
3 * pi - Pascal interpreter code translator
4 *
5 * Charles Haley, Bill Joy UCB
6 * Version 1.0 August 1977
7 *
8 *
9 * pxp - Pascal execution profiler
10 *
11 * Bill Joy UCB
12 * Version 1.0 August 1977
13 */
14
15#include "whoami"
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\f
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 4
126
127char insmult[8] INFINITY, INFINITY, INFINITY, 15, 8, 6, 3, 1;
128char repmult[7] INFINITY, INFINITY, INFINITY, 8, 6, 3, 1;
129char delmult[6] INFINITY, INFINITY, INFINITY, 6, 3, 1;
130\f
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 */
139int 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
150int yytips[YYTIPSIZ], yytipct;
151int 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
160int yCcnt;
161struct yytok YC0[YCSIZ + 1];
162struct yytok *YC;
163
164/*
165 * YCps gives the top of stack at
166 * the point of error.
167 */
168
169char yyunique 1;
170
171STATIC unsigned yyTshifts;
172\f
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 */
178int cact, ccost, cchar, cflag;
179
180/*
181 * ACtok holds the token under
182 * consideration when examining
183 * the lookaheads in a state.
184 */
185struct 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 */
194yyrecover(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));
214 }
215
216#endif
217 /*
218 * We first save the current input token
219 * and its associated semantic information.
220 */
221 if (yychar < 0)
222 yychar = yylex();
223 copy(&YC[0], &Y, sizeof Y);
224
225 /*
226 * Set the default action and cost
227 */
228 cact = CPANIC, ccost = CLIMIT, cflag = 0;
229
230 /*
231 * Peek ahead
232 */
233 for (yCcnt = 1; yCcnt < YCSIZ; yCcnt++) {
234 yychar = yylex();
235 copy(&YC[yCcnt], &Y, sizeof YC[0]);
236#ifdef DEBUG
237 Eprintf(" | %s%s", tokname(&YC[yCcnt]));
238#endif
239 }
240#ifdef DEBUG
241 Eprintf("\n");
242#endif
243
244 /*
245 * If we are here because a reduction failed, try
246 * correcting that.
247 */
248 if (idfail) {
249 /*
250 * Save the particulars about
251 * the kind of identifier we want/have.
252 */
253 yyrwant = yyidwant;
254 yyrhave = yyidhave;
255#ifdef DEBUG
256 Tprintf(" Try Replace %s identifier with %s identifier cost=%d\n",
257 classes[yyidhave], classes[yyidwant], CCHIDCOST);
258#endif
259
260 /*
261 * Save the semantics of the ID on the
262 * stack, and null them out to free
263 * up the reduction in question.
264 */
265 i = yypv[0];
266 yypv[0] = nullsem(YID);
267 c = correct(NOCHAR, 0, CCHIDCOST, &repmult[2], Ps0, yypv);
268 yypv[0] = i;
269#ifdef DEBUG
270 if (c < CPRLIMIT || fulltrace)
271 Eprintf("Cost %2d Replace %s identifier with %s identifier\n", c, classes[yyrhave], classes[yyrwant]);
272#endif
273 if (c < ccost)
274 cact = CCHIDENT, ccost = c, cchar = YID;
275 }
276
277 /*
278 * First try correcting the state we are in
279 */
280 trystate(Ps0, yypv, 0, &insmult[1], &delmult[1], &repmult[1]);
281
282 /*
283 * Now, if we just shifted over a terminal, try
284 * correcting it.
285 */
286 if (OY.Yychar != -1 && OY.Yylval != nullsem(OY.Yychar)) {
287 YC--;
288 copy(&YC[0], &OY, sizeof YC[0]);
289 trystate(Ps0 - 1, yypv - 1, 1, insmult, delmult, repmult);
290 if (cflag == 0)
291 YC++;
292 else {
293 yypv--;
294#ifdef PXP
295 yypw--;
296#endif
297 Ps0--;
298 yCcnt++;
299 }
300 }
301
302 /*
303 * Restoring the first look ahead into
304 * the scanner token allows the error message
305 * routine to print the error message with the text
306 * of the correct line.
307 */
308 copy(&Y, &YC[0], sizeof Y);
309
310 /*
311 * Unique symbol insertion.
312 *
313 * If there was no reasonable correction found,
314 * but only one input to the parser is acceptable
315 * we report that, and try it.
316 *
317 * Special precautions here to prevent looping.
318 * The number of true inputs shifted over at the point
319 * of the last unique insertion is recorded in the
320 * variable yyTshifts. If this is not less than
321 * the current number in yytshifts, we do not insert.
322 * Thus, after one unique insertion, no more unique
323 * insertions will be made until an input is shifted
324 * over. This guarantees termination.
325 */
326 if (cact == CPANIC && !idfail) {
327 register int *ap;
328
329 ap = &yyact[yypact[*Ps0 + 1]];
330 if (*ap == -ERROR)
331 ap =+ 2;
332 if (ap[0] <= 0 && ap[2] > 0) {
333 cchar = -ap[0];
334 if (cchar == YEOF)
335 yyexeof();
336 if (cchar != ERROR && yyTshifts < yytshifts) {
337 cact = CUNIQUE;
338#ifdef DEBUG
339 Eprintf("Unique symbol %s%s\n", charname(cchar));
340#endif
341 /*
342 * Note that the inserted symbol
343 * will not be counted as a true input
344 * (i.e. the "yytshifts--" below)
345 * so that a true shift will be needed
346 * to make yytshifts > yyTshifts.
347 */
348 yyTshifts = yytshifts;
349 }
350 }
351 }
352
353 /*
354 * Set up to perform the correction.
355 * Build a token appropriate for replacement
356 * or insertion in the yytok structure ACchar
357 * having the attributes of the input at the
358 * point of error.
359 */
360 copy(&ACtok, &YC[0], sizeof ACtok);
361 acchar = cchar;
362 aclval = nullsem(acchar);
363 if (aclval != NIL)
364 recovered();
365 switch (cact) {
366 /*
367 * Panic, just restore the
368 * lookahead and return.
369 */
370 case CPANIC:
371 setpfx('E');
372 if (idfail) {
373 copy(&Y, &OY, sizeof Y);
374 if (yyrhave == NIL) {
375#ifdef PI
376 if (yybaduse(yypv[0], yyeline, ISUNDEF) == NIL)
377#endif
378 yerror("Undefined identifier");
379 } else {
380 yerror("Improper %s identifier", classes[yyrhave]);
381#ifdef PI
382 yybaduse(yypv[0], yyeline, NIL);
383#endif
384 }
385 /*
386 * Suppress message from panic routine
387 */
388 yyshifts = 1;
389 }
390 i = 0;
391 /* Note that on one path we dont touch yyshifts ! */
392 break;
393 /*
394 * Delete the input.
395 * Mark this as a shift over true input.
396 * Restore the lookahead starting at
397 * the second token.
398 */
399 case CDELETE:
400 if (ccost != 0)
401 yerror("Deleted %s%s", tokname(&YC[0]));
402 yytshifts++;
403 i = 1;
404 yyshifts = 0;
405 break;
406 /*
407 * Replace the input with a new token.
408 */
409 case CREPLACE:
410 if (acchar == YEOF)
411 yyexeof();
412 if (acchar == YEND)
413 aclval = NIL;
414 yerror("Replaced %s%s with a %s%s",
415 tokname(&YC[0]), tokname(&ACtok));
416 copy(&YC[0], &ACtok, sizeof YC[0]);
417 i = 0;
418 yyshifts = 0;
419 break;
420 /*
421 * Insert a token.
422 * Don't count this token as a true input shift.
423 * For inserted "end"s pas.y is responsible
424 * for the error message later so suppress it.
425 * Restore all the lookahead.
426 */
427 case CINSERT:
428 if (acchar == YEOF)
429 yyexeof();
430 if (acchar != YEND)
431 yerror("Inserted %s%s", tokname(&ACtok));
432 yytshifts--;
433 i = 0;
434 yyshifts = 0;
435 break;
436 /*
437 * Make a unique symbol correction.
438 * Like an insertion but a different message.
439 */
440 case CUNIQUE:
441 setpfx('E');
442 yerror("Expected %s%s", tokname(&ACtok));
443 yytshifts--;
444 i = 0;
445 if (ccost == 0 || yyunique)
446 yyshifts = 0;
447 else
448 yyshifts = -1;
449 break;
450 /*
451 * Change an identifier's type
452 * to make it work.
453 */
454 case CCHIDENT:
455 copy(&Y, &OY, sizeof Y);
456#ifdef PI
457 i = 1 << yyrwant;
458#endif
459 if (yyrhave == NIL) {
460 yerror("Undefined %s", classes[yyrwant]);
461#ifdef PI
462 i =| ISUNDEF;
463#endif
464 } else
465 yerror("Replaced %s id with a %s id", classes[yyrhave], classes[yyrwant]);
466#ifdef PI
467 yybaduse(yypv[0], yyeline, i);
468#endif
469 yypv[0] = nullsem(YID);
470 i = 0;
471 yyshifts = 0;
472 break;
473 }
474
475 /*
476 * Restore the desired portion of the lookahead,
477 * and possibly the inserted or unique inserted token.
478 */
479 for (yCcnt--; yCcnt >= i; yCcnt--)
480 unyylex(&YC[yCcnt]);
481 if (cact == CINSERT || cact == CUNIQUE)
482 unyylex(&ACtok);
483
484 /*
485 * Put the scanner back in sync.
486 */
487 yychar = yylex();
488
489 /*
490 * We succeeded if we didn't "panic".
491 */
492 Recovery = 0;
493 Ps = Ps0;
494 return (cact != CPANIC);
495}
496
497yyexeof()
498{
499
500 yerror("End-of-file expected - QUIT");
501 pexit(ERRS);
502}
503
504yyunexeof()
505{
506
507 yerror("Unexpected end-of-file - QUIT");
508 pexit(ERRS);
509}
510\f
511/*
512 * Try corrections with the state at Ps0.
513 * Flag is 0 if this is the top of stack state,
514 * 1 if it is the state below.
515 */
516trystate(Ps0, Pv0, flag, insmult, delmult, repmult)
517 int *Ps0, *Pv0, flag;
518 char *insmult, *delmult, *repmult;
519{
520 /*
521 * C is a working cost, ap a pointer into the action
522 * table for looking at feasible alternatives.
523 */
524 register int c, *ap;
525 int i, *actions;
526
527#ifdef DEBUG
528 Eprintf("Trying state %d\n", *Ps0);
529#endif
530 /*
531 * Try deletion.
532 * Correct returns a cost.
533 */
534#ifdef DEBUG
535 Tprintf(" Try Delete %s%s cost=%d\n", tokname(&YC[0]), delcost(YC[0].Yychar));
536#endif
537 c = delcost(YC[0].Yychar);
538#ifndef DEBUG
539 if (c < ccost) {
540#endif
541 c = correct(NOCHAR, 1, c, delmult, Ps0, Pv0);
542#ifdef DEBUG
543 if (c < CPRLIMIT || fulltrace)
544 Eprintf("Cost %2d Delete %s%s\n", c, tokname(&YC[0]));
545#endif
546 if (c < ccost)
547 cact = CDELETE, ccost = c, cflag = flag;
548#ifndef DEBUG
549 }
550#endif
551
552 /*
553 * Look at the inputs to this state
554 * which will cause parse action shift.
555 */
556 aclval = NIL;
557 ap = &yyact[yypact[*Ps0 + 1]];
558
559 /*
560 * Skip action on error to
561 * detect true unique inputs.
562 * Error action is always first.
563 */
564 if (*ap == -ERROR)
565 ap=+ 2;
566
567 /*
568 * Loop through the test actions
569 * for this state.
570 */
571 for (actions = ap; *ap <= 0; ap =+ 2) {
572 /*
573 * Extract the token of this action
574 */
575 acchar = -*ap;
576
577 /*
578 * Try insertion
579 */
580#ifdef DEBUG
581 Tprintf(" Try Insert %s%s cost=%d\n", charname(acchar), inscost(acchar));
582#endif
583 c = inscost(acchar, YC[0].Yychar);
584#ifndef DEBUG
585 if (c < ccost) {
586#endif
587 if (c == 0) {
588 c = correct(acchar, 0, 1, insmult + 1, Ps0, Pv0);
589#ifdef DEBUG
590 Eprintf("Cost %2d Freebie %s%s\n", c, charname(acchar));
591#endif
592 if (c < ccost)
593 cact = CUNIQUE, ccost = 0, cchar = acchar, cflag = flag;
594 } else {
595 c = correct(acchar, 0, c, insmult, Ps0, Pv0);
596#ifdef DEBUG
597 if (c < CPRLIMIT || fulltrace)
598 Eprintf("Cost %2d Insert %s%s\n", c, charname(acchar));
599#endif
600 if (c < ccost)
601 cact = CINSERT, ccost = c, cchar = acchar, cflag = flag;
602 }
603#ifndef DEBUG
604 }
605#endif
606
607 /*
608 * Try replacement
609 */
610#ifdef DEBUG
611 Tprintf(" Try Replace %s%s with %s%s cost=%d\n",
612 tokname(&YC[0]), charname(acchar), repcost(YC[0].Yychar, acchar));
613#endif
614 c = repcost(YC[0].Yychar, acchar);
615#ifndef DEBUG
616 if (c < ccost) {
617#endif
618 c = correct(acchar, 1, repcost(YC[0].Yychar, acchar), repmult, Ps0, Pv0);
619#ifdef DEBUG
620 if (c < CPRLIMIT || fulltrace)
621 Eprintf("Cost %2d Replace %s%s with %s%s\n", c, tokname(&YC[0]), tokname(&ACtok));
622#endif
623 if (c < ccost)
624 cact = CREPLACE, ccost = c, cchar = acchar, cflag = flag;
625#ifndef DEBUG
626 }
627#endif
628 }
629}
630\f
631int *yCpv;
632char yyredfail;
633/*
634 * Compute the cost of a correction
635 * C is the base cost for it.
636 * Fchar is the first input character from
637 * the current state, NOCHAR if none.
638 * The rest of the inputs come from the array
639 * YC, starting at origin and continuing to the
640 * last character there, YC[yCcnt - 1].Yychar.
641 *
642 * The cost returned is INFINITE if this correction
643 * allows no shifts, otherwise is weighted based
644 * on the number of shifts this allows against the
645 * maximum number possible with the available lookahead.
646 */
647correct(fchar, origin, c, multvec, Ps0, Pv0)
648 int fchar, origin, c;
649 char *multvec;
650 int *Ps0, *Pv0;
651{
652 /*
653 * The ntok structure is used to build a
654 * scanner structure for tokens inserted
655 * from the argument fchar.
656 */
657 struct yytok ntok;
658 register char *mv;
659
660 /*
661 * Ps is the top of the parse stack after the most
662 * recent local correctness check. Loccor returns
663 * NIL when we cannot shift.
664 */
665 register int *ps;
666
667 yyredfail = 0;
668 /*
669 * Initialize the tip parse and semantic stacks.
670 */
671 ps = Ps0;
672 yytips[0] = *ps;
673 ps--;
674 yytipv[0] = Pv0[0];
675 yCpv = Pv0 - 1;
676 yytipct = 1;
677
678 /*
679 * Shift while possible.
680 * Adjust cost as necessary.
681 */
682 mv = multvec;
683 do {
684 if (fchar != NOCHAR) {
685 copy(&ntok, &YC[0], sizeof ntok);
686 ntok.Yychar = fchar, ntok.Yylval = nullsem(fchar);
687 fchar = NOCHAR;
688 ps = loccor(ps, &ntok);
689 } else
690 ps = loccor(ps, &YC[origin++]);
691 if (ps == NIL) {
692 if (yyredfail && mv > multvec)
693 mv--;
694 c =* *mv;
695 break;
696 }
697 mv++;
698 } while (*mv != 1);
699 return (c);
700}
701\f
702extern int yygo[], yypgo[], yyr1[], yyr2[];
703/*
704 * Local syntactic correctness check.
705 * The arguments to this routine are a
706 * top of stack pointer, ps, and an input
707 * token tok. Also, implicitly, the contents
708 * of the yytips array which contains the tip
709 * of the stack, and into which the new top
710 * state on the stack will be placed if we shift.
711 *
712 * If we succeed, we return a new top of stack
713 * pointer, else we return NIL.
714 */
715loccor(ps, ntok)
716 int *ps;
717 struct yytok *ntok;
718{
719 register int *p, n;
720 register int nchar;
721 int i;
722
723 if (ps == NIL)
724 return (NIL);
725 nchar = ntok->Yychar;
726 yyeline = ntok->Yyeline;
727#ifdef DEBUG
728 Tprintf(" Stack ");
729 for (i = yytipct - 1; i >= 0; i--)
730 Tprintf("%d ", yytips[i]);
731 Tprintf("| %d, Input %s%s\n", *ps, charname(nchar));
732#endif
733 /*
734 * As in the yacc parser yyparse,
735 * p traces through the action list
736 * and "n" is the information associated
737 * with the action.
738 */
739newstate:
740 p = &yyact[ yypact[yytips[yytipct - 1]+1] ];
741
742actn:
743 /*
744 * Search the parse actions table
745 * for something useful to do.
746 * While n is non-positive, it is the
747 * arithmetic inverse of the token to be tested.
748 * This allows a fast check.
749 */
750 while ((n = *p++) <= 0)
751 if ((n =+ nchar) != 0)
752 p++;
753 switch (n >> 12) {
754 /*
755 * SHIFT
756 */
757 case 2:
758 n =& 07777;
759 yyredfail = 0;
760 if (nchar == YID)
761 yyredfail++;
762 if (yytipct == YYTIPSIZ) {
763tipover:
764#ifdef DEBUG
765 Tprintf("\tTIP OVFLO\n");
766#endif
767 return (NIL);
768 }
769 yytips[yytipct] = n;
770 yytipv[yytipct] = ntok->Yylval;
771 yytipct++;
772#ifdef DEBUG
773 Tprintf("\tShift to state %d\n", n);
774#endif
775 return (ps);
776 /*
777 * REDUCE
778 */
779 case 3:
780 n =& 07777;
781 if (yyEactr(n, yytipv[yytipct - 1]) == 0) {
782#ifdef DEBUG
783 Tprintf("\tYyEactr objects: have %s id, want %s id\n", classes[yyidhave], classes[yyidwant]);
784#endif
785 return (NIL);
786 }
787 yyredfail = 0;
788 i = yyr2[n];
789#ifdef DEBUG
790 Tprintf("\tReduce, length %d,", i);
791#endif
792 if (i > yytipct) {
793 i =- yytipct;
794 yytipct = 0;
795 ps =- i;
796 yCpv =- i;
797 } else
798 yytipct =- i;
799 if (yytipct >= YYTIPSIZ)
800 goto tipover;
801 /*
802 * Use goto table to find next state
803 */
804 p = &yygo[yypgo[yyr1[n]]];
805 i = yytipct ? yytips[yytipct - 1] : *ps;
806 while (*p != i && *p >= 0)
807 p =+ 2;
808#ifdef DEBUG
809 Tprintf(" new state %d\n", p[1]);
810#endif
811 yytips[yytipct] = p[1];
812 yytipct++;
813 goto newstate;
814 /*
815 * ACCEPT
816 */
817 case 4:
818#ifdef DEBUG
819 Tprintf("\tAccept\n");
820#endif
821 return (ps);
822 /*
823 * ERROR
824 */
825 case 1:
826#ifdef DEBUG
827 Tprintf("\tError\n");
828#endif
829 return (0);
830 }
831 panic("loccor");
832}