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