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