1783Speter /* Copyright (c) 1979 Regents of the University of California */ 2783Speter 3*7999Smckusick static char sccsid[] = "@(#)yycosts.c 1.4 08/30/82"; 4783Speter 5783Speter #include "whoami.h" 6783Speter #include "0.h" 7783Speter #include "yy.h" 8783Speter 9783Speter /* 10783Speter * Symbol costs for Pascal. 11783Speter * 12783Speter * Cost strategy of August 14, 1977. 13783Speter * 14783Speter * The costs determined by the routines in this file are used by 15783Speter * the recovery in choosing appropriate corrections. 16783Speter * The cost vectors and the error productions in the grammar 17783Speter * work together to define the corrective capacity of the grammar. 18783Speter * 19783Speter * The costs here largely derive from those given in Steve Rhode's 20783Speter * thesis for the Pascal-I error correcting parser which he implemented. 21783Speter * Some minor changes have been made to adjust for the fact that 22783Speter * the current error recovery is not as "smart", both because of the 23783Speter * limited forward move and because of the lack of any type information 24783Speter * about identifiers. 25783Speter * 26783Speter * These adjustments largely take the form of increased costs for certain 27783Speter * tokens, noticeably keywords which are major brackets such as "begin" 28783Speter * "label", "procedure", etc. 29783Speter * 30783Speter * The overall weighting strategy is still similar to Rhodes' strategy. 31783Speter * The costs can be considered: 32783Speter * 33783Speter * LOW <= 3 34783Speter * MEDIUM 4 or 5 35783Speter * HIGH >= 6 36783Speter */ 37783Speter 38783Speter /* 39783Speter * Insertion costs 40783Speter * 41783Speter * In addition to the normal symbol insertion costs, 42783Speter * there are zero cost insertions here. 43783Speter * The current error recovery system treats symbols 44783Speter * which have zero insertion cost in a special way, 45783Speter * inserting them but suppressing diagnostics. 46783Speter * This allows the system to hold of on bracketing 47783Speter * error diagnostics about missing end's until the 48783Speter * reduction occurs which knows the line number of the 49783Speter * corresponding "begin", "repeat", etc. 50783Speter * A more intelligent and useful diagnostic can then 51783Speter * be printed. 52783Speter * 53783Speter * Although this routine never allows the insertion 54783Speter * of the keyword begin, it can be inserted after a 55783Speter * procedure or function body starts, if it was omitted 56783Speter * by a special case in the panic routine, which notices 57783Speter * the keywords in the statement body of the procedure 58783Speter * and inserts the begin to recover. 59783Speter * 60783Speter * Similarly, we do not insert end-of-file, but 61783Speter * the fact that end-of-file is the unique input 62783Speter * is noticed by the recovery routines as a special 63783Speter * case and handled there. 64783Speter */ 65783Speter inscost(sy, before) 66783Speter register int sy, before; 67783Speter { 68783Speter 69783Speter switch (before) { 70783Speter case YEND: 71783Speter if (sy == YEND) 72783Speter break; 73783Speter case YPROCEDURE: 74783Speter case YFUNCTION: 75783Speter if (sy == YUNTIL || sy == YEND) 76783Speter return (0); 77783Speter } 78783Speter switch (sy) { 79783Speter case ';': 80783Speter return (1); 81783Speter case ',': 82783Speter case ':': 83783Speter case YOF: 84783Speter case YDO: 85783Speter return (2); 86783Speter case YARRAY: 87783Speter case '+': 88783Speter case '*': 89783Speter return (3); 90783Speter default: 91783Speter return (4); 92783Speter case '^': 93783Speter case YNOT: 94783Speter case YLABEL: 95783Speter case YCONST: 96783Speter case YTYPE: 97783Speter case YVAR: 98783Speter case YUNTIL: 99783Speter case '(': 100783Speter case '[': 101783Speter case YWHILE: 102783Speter case YWITH: 103783Speter return (5); 104783Speter case YPROCEDURE: 105783Speter case YFUNCTION: 106783Speter case YCASE: 107783Speter return (6); 108783Speter case YEND: 109783Speter return (8); 110783Speter case YBEGIN: 111783Speter case YEOF: 112783Speter case YREPEAT: 113783Speter case YRECORD: 114783Speter return (INFINITY); 115783Speter } 116783Speter } 117783Speter 118783Speter /* 119783Speter * Replacement costs 120783Speter * 121783Speter * Most replacement costs are the same as an insertion 122783Speter * plus a deletion cost. One special case is the replacement 123783Speter * of a large number of keywords by an identifier. 124783Speter * These are given lower costs, especially the keyword "to". 125783Speter */ 126783Speter repcost(what, with) 127783Speter register int what, with; 128783Speter { 129783Speter register int c; 130783Speter 131783Speter if (with == what) 132783Speter return (INFINITY); 133783Speter if (with == YID && what > ERROR) 134783Speter switch (what) { 135783Speter case YID: 136783Speter case YDOTDOT: 137783Speter case YINT: 138783Speter case YBINT: 139783Speter case YSTRING: 140783Speter case YNUMB: 141783Speter break; 142783Speter case YTO: 143783Speter return (3); 144783Speter default: 145783Speter return (5); 146783Speter case YRECORD: 147783Speter case YTHEN: 148783Speter return (6); 149783Speter case YBEGIN: 150783Speter break; 151783Speter } 152*7999Smckusick if (what == YID && with == YFORWARD) 153*7999Smckusick return(5); 154783Speter if (what == ';' && (with == ',' || with == '.')) 155783Speter return (CLIMIT - 1); 156783Speter c = delcost(what) + inscost(with); 157783Speter /* 158783Speter * It costs extra to replace something which has 159783Speter * semantics by something which doesn't. 160783Speter */ 161783Speter if (nullsem(what) == NIL && nullsem(with) != NIL) 1623084Smckusic c += 4; 163783Speter return (c); 164783Speter } 165783Speter 166783Speter /* 167783Speter * Deletion costs 168783Speter */ 169783Speter delcost(what) 170783Speter int what; 171783Speter { 172783Speter 173783Speter switch (what) { 174783Speter case '.': 175783Speter case ':': 176783Speter case ',': 177783Speter case '=': 178783Speter case '(': 179783Speter return (3); 180783Speter case YELSE: 181783Speter case YTHEN: 182783Speter return (4); 183783Speter default: 184783Speter return (5); 185783Speter case YLABEL: 186783Speter case YCONST: 187783Speter case YTYPE: 188783Speter case YVAR: 189783Speter return (10); 190783Speter case YPROCEDURE: 191783Speter case YFUNCTION: 192783Speter case YBEGIN: 193783Speter case YEND: 194783Speter return ((CLIMIT * 3) / 4); 195783Speter case ';': 196783Speter case YEOF: 197783Speter return (INFINITY); 198783Speter } 199783Speter } 200783Speter #ifdef DEBUG 201783Speter 202783Speter /* 203783Speter * Routine to print out costs with "-K" option. 204783Speter */ 2053084Smckusic char yysyms[] = ";,:=*+/-|&()[]<>~^"; 206783Speter 207783Speter 208783Speter yycosts() 209783Speter { 210783Speter register int c; 211783Speter register char *cp; 212783Speter 213783Speter printf("Insert\tDelete\tRep(ID)\tSymbol\n"); 214783Speter for (cp = yysyms; *cp; cp++) 215783Speter yydocost(*cp); 216783Speter for (c = ERROR + 1; c < YLAST; c++) 217783Speter yydocost(c); 218783Speter #ifdef PXP 219783Speter flush(); 220783Speter #endif 221783Speter } 222783Speter 223783Speter yydocost(c) 224783Speter int c; 225783Speter { 226783Speter 227783Speter printf("%4d\t", inscost(c, -1)); 228783Speter printf("%4d\t", delcost(c)); 229783Speter if (repcost(c, YID) != inscost(YID) + delcost(c)) 230783Speter printf("%4d", repcost(c, YID)); 231783Speter printf("\t%s%s\n", charname(c)); 232783Speter } 233783Speter #endif 234