1790Speter /* Copyright (c) 1979 Regents of the University of California */ 2790Speter 3*3086Smckusic static char sccsid[] = "@(#)yypanic.c 1.2 03/08/81"; 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: 45790Speter goto quiet; 46790Speter case ';': 47790Speter if (kind == PPROG) 48790Speter continue; 49790Speter if (kind == PDECL) 50790Speter yychar = yylex(); 51790Speter goto resume; 52790Speter case YEND: 53790Speter if (kind == PPROG) 54790Speter continue; 55790Speter case YPROCEDURE: 56790Speter case YFUNCTION: 57790Speter goto resume; 58790Speter case YLABEL: 59790Speter case YTYPE: 60790Speter case YCONST: 61790Speter case YVAR: 62790Speter if (kind == PSTAT) { 63790Speter yerror("Declaration found when statement expected"); 64790Speter goto quiet; 65790Speter } 66790Speter case YBEGIN: 67790Speter goto resume; 68790Speter case YFOR: 69790Speter case YREPEAT: 70790Speter case YWHILE: 71790Speter case YGOTO: 72790Speter case YIF: 73790Speter if (kind != PDECL) 74790Speter goto resume; 75790Speter yerror("Expected keyword begin after declarations, before statements"); 76790Speter unyylex(&Y); 77790Speter yychar = YBEGIN; 78790Speter yylval = nullsem(YBEGIN); 79790Speter goto quiet; 80790Speter case YTHEN: 81790Speter case YELSE: 82790Speter case YDO: 83790Speter if (kind == PSTAT) { 84790Speter yychar = yylex(); 85790Speter goto resume; 86790Speter } 87790Speter if (kind == PEXPR) 88790Speter goto resume; 89790Speter continue; 90790Speter case ')': 91790Speter case ']': 92790Speter if (kind != PEXPR) 93790Speter continue; 94790Speter if (brlev == 0) 95790Speter goto resume; 96790Speter if (brlev > 0) 97790Speter brlev--; 98790Speter continue; 99790Speter case '(': 100790Speter case '[': 101790Speter brlev++; 102790Speter continue; 103790Speter case ',': 104790Speter if (brlev != 0) 105790Speter continue; 106790Speter case YOF: 107790Speter case YTO: 108790Speter case YDOWNTO: 109790Speter if (kind == PEXPR) 110790Speter goto resume; 111790Speter continue; 112790Speter #ifdef PI 113790Speter /* 114790Speter * A rough approximation for now 115790Speter * Should be much more lenient on suppressing 116790Speter * warnings. 117790Speter */ 118790Speter case YID: 119*3086Smckusic syneflg = TRUE; 120790Speter continue; 121790Speter #endif 122790Speter } 123790Speter resume: 124790Speter if (yyOshifts >= 2) { 125790Speter if (yychar != -1) 126790Speter unyylex(&Y); 127790Speter copy(&Y, &oldpos, sizeof Y); 128790Speter yerror(cp); 129790Speter yychar = yylex(); 130790Speter } 131790Speter quiet: 132790Speter if (yyshifts - ishifts > 2 && opt('r')) { 133790Speter setpfx('r'); 134790Speter yerror("Parsing resumes"); 135790Speter } 136790Speter /* 137790Speter * If we paniced in the statement part, 138790Speter * and didn't stop at a ';', then we insert 139790Speter * a ';' to prevent the recovery from immediately 140790Speter * inserting one and complaining about it. 141790Speter */ 142790Speter if (kind == PSTAT && yychar != ';') { 143790Speter unyylex(&Y); 144790Speter yyshifts--; 145790Speter yytshifts--; 146790Speter yychar = ';'; 147790Speter yylval = nullsem(';'); 148790Speter } 149790Speter } 150