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