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