1790Speter /* Copyright (c) 1979 Regents of the University of California */ 2790Speter 3*6359Speter static char sccsid[] = "@(#)yypanic.c 1.3 03/29/82"; 4790Speter 5790Speter #include "whoami.h" 6790Speter #include "0.h" 7790Speter #include "yy.h" 8790Speter 9790Speter struct yytok oldpos; 10790Speter /* 11790Speter * The routine yyPerror coordinates the panic when 12790Speter * the correction routines fail. Three types of panics 13790Speter * are possible - those in a declaration part, those 14790Speter * in a statement part, and those in an expression. 15790Speter * 16790Speter * Declaration part panics consider insertion of "begin", 17790Speter * expression part panics will stop on more symbols. 18790Speter * The panics are otherwise the same. 19790Speter * 20790Speter * ERROR MESSAGE SUPPRESSION STRATEGY: August 11, 1977 21790Speter * 22790Speter * If the parser has not made at least 2 moves since the last point of 23790Speter * error then we want to suppress the supplied error message. 24790Speter * Otherwise we print it. 25790Speter * We then skip input up to the next solid symbol. 26790Speter */ 27790Speter yyPerror(cp, kind) 28790Speter char *cp; 29790Speter register int kind; 30790Speter { 31790Speter register int ishifts, brlev; 32790Speter 33790Speter copy(&oldpos, &Y, sizeof oldpos); 34790Speter brlev = 0; 35790Speter if (yychar < 0) 36790Speter yychar = yylex(); 37790Speter for (ishifts = yyshifts; ; yychar = yylex(), yyshifts++) 38790Speter switch (yychar) { 39790Speter case YILLCH: 40790Speter yerror("Illegal character"); 41790Speter if (ishifts == yyshifts) 42790Speter yyOshifts = 0; 43790Speter continue; 44790Speter case YEOF: 45*6359Speter if (kind == PDECL) { 46*6359Speter /* 47*6359Speter * we have paniced to end of file 48*6359Speter * during declarations. Separately 49*6359Speter * compiled segments can syntactically 50*6359Speter * exit without any error message, so 51*6359Speter * we force one here. 52*6359Speter */ 53*6359Speter yerror(cp); 54*6359Speter continuation(); 55*6359Speter yyunexeof(); 56*6359Speter } 57790Speter goto quiet; 58790Speter case ';': 59790Speter if (kind == PPROG) 60790Speter continue; 61790Speter if (kind == PDECL) 62790Speter yychar = yylex(); 63790Speter goto resume; 64790Speter case YEND: 65790Speter if (kind == PPROG) 66790Speter continue; 67790Speter case YPROCEDURE: 68790Speter case YFUNCTION: 69790Speter goto resume; 70790Speter case YLABEL: 71790Speter case YTYPE: 72790Speter case YCONST: 73790Speter case YVAR: 74790Speter if (kind == PSTAT) { 75790Speter yerror("Declaration found when statement expected"); 76790Speter goto quiet; 77790Speter } 78790Speter case YBEGIN: 79790Speter goto resume; 80790Speter case YFOR: 81790Speter case YREPEAT: 82790Speter case YWHILE: 83790Speter case YGOTO: 84790Speter case YIF: 85790Speter if (kind != PDECL) 86790Speter goto resume; 87790Speter yerror("Expected keyword begin after declarations, before statements"); 88790Speter unyylex(&Y); 89790Speter yychar = YBEGIN; 90790Speter yylval = nullsem(YBEGIN); 91790Speter goto quiet; 92790Speter case YTHEN: 93790Speter case YELSE: 94790Speter case YDO: 95790Speter if (kind == PSTAT) { 96790Speter yychar = yylex(); 97790Speter goto resume; 98790Speter } 99790Speter if (kind == PEXPR) 100790Speter goto resume; 101790Speter continue; 102790Speter case ')': 103790Speter case ']': 104790Speter if (kind != PEXPR) 105790Speter continue; 106790Speter if (brlev == 0) 107790Speter goto resume; 108790Speter if (brlev > 0) 109790Speter brlev--; 110790Speter continue; 111790Speter case '(': 112790Speter case '[': 113790Speter brlev++; 114790Speter continue; 115790Speter case ',': 116790Speter if (brlev != 0) 117790Speter continue; 118790Speter case YOF: 119790Speter case YTO: 120790Speter case YDOWNTO: 121790Speter if (kind == PEXPR) 122790Speter goto resume; 123790Speter continue; 124790Speter #ifdef PI 125790Speter /* 126790Speter * A rough approximation for now 127790Speter * Should be much more lenient on suppressing 128790Speter * warnings. 129790Speter */ 130790Speter case YID: 1313086Smckusic syneflg = TRUE; 132790Speter continue; 133790Speter #endif 134790Speter } 135790Speter resume: 136790Speter if (yyOshifts >= 2) { 137790Speter if (yychar != -1) 138790Speter unyylex(&Y); 139790Speter copy(&Y, &oldpos, sizeof Y); 140790Speter yerror(cp); 141790Speter yychar = yylex(); 142790Speter } 143790Speter quiet: 144790Speter if (yyshifts - ishifts > 2 && opt('r')) { 145790Speter setpfx('r'); 146790Speter yerror("Parsing resumes"); 147790Speter } 148790Speter /* 149790Speter * If we paniced in the statement part, 150790Speter * and didn't stop at a ';', then we insert 151790Speter * a ';' to prevent the recovery from immediately 152790Speter * inserting one and complaining about it. 153790Speter */ 154790Speter if (kind == PSTAT && yychar != ';') { 155790Speter unyylex(&Y); 156790Speter yyshifts--; 157790Speter yytshifts--; 158790Speter yychar = ';'; 159790Speter yylval = nullsem(';'); 160790Speter } 161790Speter } 162