1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)yypanic.c 1.1 08/27/80"; 4 5 #include "whoami.h" 6 #include "0.h" 7 #include "yy.h" 8 9 struct yytok oldpos; 10 /* 11 * The routine yyPerror coordinates the panic when 12 * the correction routines fail. Three types of panics 13 * are possible - those in a declaration part, those 14 * in a statement part, and those in an expression. 15 * 16 * Declaration part panics consider insertion of "begin", 17 * expression part panics will stop on more symbols. 18 * The panics are otherwise the same. 19 * 20 * ERROR MESSAGE SUPPRESSION STRATEGY: August 11, 1977 21 * 22 * If the parser has not made at least 2 moves since the last point of 23 * error then we want to suppress the supplied error message. 24 * Otherwise we print it. 25 * We then skip input up to the next solid symbol. 26 */ 27 yyPerror(cp, kind) 28 char *cp; 29 register int kind; 30 { 31 register int ishifts, brlev; 32 33 copy(&oldpos, &Y, sizeof oldpos); 34 brlev = 0; 35 if (yychar < 0) 36 yychar = yylex(); 37 for (ishifts = yyshifts; ; yychar = yylex(), yyshifts++) 38 switch (yychar) { 39 case YILLCH: 40 yerror("Illegal character"); 41 if (ishifts == yyshifts) 42 yyOshifts = 0; 43 continue; 44 case YEOF: 45 goto quiet; 46 case ';': 47 if (kind == PPROG) 48 continue; 49 if (kind == PDECL) 50 yychar = yylex(); 51 goto resume; 52 case YEND: 53 if (kind == PPROG) 54 continue; 55 case YPROCEDURE: 56 case YFUNCTION: 57 goto resume; 58 case YLABEL: 59 case YTYPE: 60 case YCONST: 61 case YVAR: 62 if (kind == PSTAT) { 63 yerror("Declaration found when statement expected"); 64 goto quiet; 65 } 66 case YBEGIN: 67 goto resume; 68 case YFOR: 69 case YREPEAT: 70 case YWHILE: 71 case YGOTO: 72 case YIF: 73 if (kind != PDECL) 74 goto resume; 75 yerror("Expected keyword begin after declarations, before statements"); 76 unyylex(&Y); 77 yychar = YBEGIN; 78 yylval = nullsem(YBEGIN); 79 goto quiet; 80 case YTHEN: 81 case YELSE: 82 case YDO: 83 if (kind == PSTAT) { 84 yychar = yylex(); 85 goto resume; 86 } 87 if (kind == PEXPR) 88 goto resume; 89 continue; 90 case ')': 91 case ']': 92 if (kind != PEXPR) 93 continue; 94 if (brlev == 0) 95 goto resume; 96 if (brlev > 0) 97 brlev--; 98 continue; 99 case '(': 100 case '[': 101 brlev++; 102 continue; 103 case ',': 104 if (brlev != 0) 105 continue; 106 case YOF: 107 case YTO: 108 case YDOWNTO: 109 if (kind == PEXPR) 110 goto resume; 111 continue; 112 #ifdef PI 113 /* 114 * A rough approximation for now 115 * Should be much more lenient on suppressing 116 * warnings. 117 */ 118 case YID: 119 syneflg++; 120 continue; 121 #endif 122 } 123 resume: 124 if (yyOshifts >= 2) { 125 if (yychar != -1) 126 unyylex(&Y); 127 copy(&Y, &oldpos, sizeof Y); 128 yerror(cp); 129 yychar = yylex(); 130 } 131 quiet: 132 if (yyshifts - ishifts > 2 && opt('r')) { 133 setpfx('r'); 134 yerror("Parsing resumes"); 135 } 136 /* 137 * If we paniced in the statement part, 138 * and didn't stop at a ';', then we insert 139 * a ';' to prevent the recovery from immediately 140 * inserting one and complaining about it. 141 */ 142 if (kind == PSTAT && yychar != ';') { 143 unyylex(&Y); 144 yyshifts--; 145 yytshifts--; 146 yychar = ';'; 147 yylval = nullsem(';'); 148 } 149 } 150