1 /* Copyright (c) 1979 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)yypanic.c 1.3 03/29/82"; 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 if (kind == PDECL) { 46 /* 47 * we have paniced to end of file 48 * during declarations. Separately 49 * compiled segments can syntactically 50 * exit without any error message, so 51 * we force one here. 52 */ 53 yerror(cp); 54 continuation(); 55 yyunexeof(); 56 } 57 goto quiet; 58 case ';': 59 if (kind == PPROG) 60 continue; 61 if (kind == PDECL) 62 yychar = yylex(); 63 goto resume; 64 case YEND: 65 if (kind == PPROG) 66 continue; 67 case YPROCEDURE: 68 case YFUNCTION: 69 goto resume; 70 case YLABEL: 71 case YTYPE: 72 case YCONST: 73 case YVAR: 74 if (kind == PSTAT) { 75 yerror("Declaration found when statement expected"); 76 goto quiet; 77 } 78 case YBEGIN: 79 goto resume; 80 case YFOR: 81 case YREPEAT: 82 case YWHILE: 83 case YGOTO: 84 case YIF: 85 if (kind != PDECL) 86 goto resume; 87 yerror("Expected keyword begin after declarations, before statements"); 88 unyylex(&Y); 89 yychar = YBEGIN; 90 yylval = nullsem(YBEGIN); 91 goto quiet; 92 case YTHEN: 93 case YELSE: 94 case YDO: 95 if (kind == PSTAT) { 96 yychar = yylex(); 97 goto resume; 98 } 99 if (kind == PEXPR) 100 goto resume; 101 continue; 102 case ')': 103 case ']': 104 if (kind != PEXPR) 105 continue; 106 if (brlev == 0) 107 goto resume; 108 if (brlev > 0) 109 brlev--; 110 continue; 111 case '(': 112 case '[': 113 brlev++; 114 continue; 115 case ',': 116 if (brlev != 0) 117 continue; 118 case YOF: 119 case YTO: 120 case YDOWNTO: 121 if (kind == PEXPR) 122 goto resume; 123 continue; 124 #ifdef PI 125 /* 126 * A rough approximation for now 127 * Should be much more lenient on suppressing 128 * warnings. 129 */ 130 case YID: 131 syneflg = TRUE; 132 continue; 133 #endif 134 } 135 resume: 136 if (yyOshifts >= 2) { 137 if (yychar != -1) 138 unyylex(&Y); 139 copy(&Y, &oldpos, sizeof Y); 140 yerror(cp); 141 yychar = yylex(); 142 } 143 quiet: 144 if (yyshifts - ishifts > 2 && opt('r')) { 145 setpfx('r'); 146 yerror("Parsing resumes"); 147 } 148 /* 149 * If we paniced in the statement part, 150 * and didn't stop at a ';', then we insert 151 * a ';' to prevent the recovery from immediately 152 * inserting one and complaining about it. 153 */ 154 if (kind == PSTAT && yychar != ';') { 155 unyylex(&Y); 156 yyshifts--; 157 yytshifts--; 158 yychar = ';'; 159 yylval = nullsem(';'); 160 } 161 } 162