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