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