|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: */ ! 6: ! 7: #ifndef lint ! 8: static char sccsid[] = "@(#)yycosts.c 5.2 (Berkeley) 4/6/87"; ! 9: #endif not lint ! 10: ! 11: #include "whoami.h" ! 12: #include "0.h" ! 13: #include "tree_ty.h" /* must be included for yy.h */ ! 14: #include "yy.h" ! 15: ! 16: /* ! 17: * Symbol costs for Pascal. ! 18: * ! 19: * Cost strategy of August 14, 1977. ! 20: * ! 21: * The costs determined by the routines in this file are used by ! 22: * the recovery in choosing appropriate corrections. ! 23: * The cost vectors and the error productions in the grammar ! 24: * work together to define the corrective capacity of the grammar. ! 25: * ! 26: * The costs here largely derive from those given in Steve Rhode's ! 27: * thesis for the Pascal-I error correcting parser which he implemented. ! 28: * Some minor changes have been made to adjust for the fact that ! 29: * the current error recovery is not as "smart", both because of the ! 30: * limited forward move and because of the lack of any type information ! 31: * about identifiers. ! 32: * ! 33: * These adjustments largely take the form of increased costs for certain ! 34: * tokens, noticeably keywords which are major brackets such as "begin" ! 35: * "label", "procedure", etc. ! 36: * ! 37: * The overall weighting strategy is still similar to Rhodes' strategy. ! 38: * The costs can be considered: ! 39: * ! 40: * LOW <= 3 ! 41: * MEDIUM 4 or 5 ! 42: * HIGH >= 6 ! 43: */ ! 44: ! 45: /* ! 46: * Insertion costs ! 47: * ! 48: * In addition to the normal symbol insertion costs, ! 49: * there are zero cost insertions here. ! 50: * The current error recovery system treats symbols ! 51: * which have zero insertion cost in a special way, ! 52: * inserting them but suppressing diagnostics. ! 53: * This allows the system to hold of on bracketing ! 54: * error diagnostics about missing end's until the ! 55: * reduction occurs which knows the line number of the ! 56: * corresponding "begin", "repeat", etc. ! 57: * A more intelligent and useful diagnostic can then ! 58: * be printed. ! 59: * ! 60: * Although this routine never allows the insertion ! 61: * of the keyword begin, it can be inserted after a ! 62: * procedure or function body starts, if it was omitted ! 63: * by a special case in the panic routine, which notices ! 64: * the keywords in the statement body of the procedure ! 65: * and inserts the begin to recover. ! 66: * ! 67: * Similarly, we do not insert end-of-file, but ! 68: * the fact that end-of-file is the unique input ! 69: * is noticed by the recovery routines as a special ! 70: * case and handled there. ! 71: */ ! 72: inscost(sy, before) ! 73: register int sy, before; ! 74: { ! 75: ! 76: switch (before) { ! 77: case YEND: ! 78: if (sy == YEND) ! 79: break; ! 80: case YPROCEDURE: ! 81: case YFUNCTION: ! 82: if (sy == YUNTIL || sy == YEND) ! 83: return (0); ! 84: } ! 85: switch (sy) { ! 86: case ';': ! 87: return (1); ! 88: case ',': ! 89: case ':': ! 90: case YOF: ! 91: case YDO: ! 92: return (2); ! 93: case YARRAY: ! 94: case '+': ! 95: case '*': ! 96: return (3); ! 97: default: ! 98: return (4); ! 99: case '^': ! 100: case YNOT: ! 101: case YLABEL: ! 102: case YCONST: ! 103: case YTYPE: ! 104: case YVAR: ! 105: case YUNTIL: ! 106: case '(': ! 107: case '[': ! 108: case YWHILE: ! 109: case YWITH: ! 110: return (5); ! 111: case YPROCEDURE: ! 112: case YFUNCTION: ! 113: case YCASE: ! 114: return (6); ! 115: case YEND: ! 116: return (8); ! 117: case YBEGIN: ! 118: case YEOF: ! 119: case YREPEAT: ! 120: case YRECORD: ! 121: return (INFINITY); ! 122: } ! 123: } ! 124: ! 125: /* ! 126: * Replacement costs ! 127: * ! 128: * Most replacement costs are the same as an insertion ! 129: * plus a deletion cost. One special case is the replacement ! 130: * of a large number of keywords by an identifier. ! 131: * These are given lower costs, especially the keyword "to". ! 132: */ ! 133: repcost(what, with) ! 134: register int what, with; ! 135: { ! 136: register int c; ! 137: ! 138: if (with == what) ! 139: return (INFINITY); ! 140: if (with == YID && what > ERROR) ! 141: switch (what) { ! 142: case YID: ! 143: case YDOTDOT: ! 144: case YINT: ! 145: case YBINT: ! 146: case YSTRING: ! 147: case YNUMB: ! 148: break; ! 149: case YTO: ! 150: return (3); ! 151: default: ! 152: return (5); ! 153: case YRECORD: ! 154: case YTHEN: ! 155: return (6); ! 156: case YBEGIN: ! 157: break; ! 158: } ! 159: if (what == YID && with == YFORWARD) ! 160: return(5); ! 161: if (what == ';' && (with == ',' || with == '.')) ! 162: return (CLIMIT - 1); ! 163: c = delcost(what) + inscost(with, what); ! 164: /* ! 165: * It costs extra to replace something which has ! 166: * semantics by something which doesn't. ! 167: */ ! 168: if (nullsem(what) == NIL && nullsem(with) != NIL) ! 169: c += 4; ! 170: return (c); ! 171: } ! 172: ! 173: /* ! 174: * Deletion costs ! 175: */ ! 176: delcost(what) ! 177: int what; ! 178: { ! 179: ! 180: switch (what) { ! 181: case '.': ! 182: case ':': ! 183: case ',': ! 184: case '=': ! 185: case '(': ! 186: return (3); ! 187: case YELSE: ! 188: case YTHEN: ! 189: return (4); ! 190: default: ! 191: return (5); ! 192: case YLABEL: ! 193: case YCONST: ! 194: case YTYPE: ! 195: case YVAR: ! 196: return (10); ! 197: case YPROCEDURE: ! 198: case YFUNCTION: ! 199: case YBEGIN: ! 200: case YEND: ! 201: return ((CLIMIT * 3) / 4); ! 202: case ';': ! 203: case YEOF: ! 204: return (INFINITY); ! 205: } ! 206: } ! 207: #ifdef DEBUG ! 208: ! 209: /* ! 210: * Routine to print out costs with "-K" option. ! 211: */ ! 212: char yysyms[] = ";,:=*+/-|&()[]<>~^"; ! 213: ! 214: ! 215: yycosts() ! 216: { ! 217: register int c; ! 218: register char *cp; ! 219: ! 220: printf("Insert\tDelete\tRep(ID)\tSymbol\n"); ! 221: for (cp = yysyms; *cp; cp++) ! 222: yydocost(*cp); ! 223: for (c = ERROR + 1; c < YLAST; c++) ! 224: yydocost(c); ! 225: #ifdef PXP ! 226: flush(); ! 227: #endif ! 228: } ! 229: ! 230: yydocost(c) ! 231: int c; ! 232: { ! 233: ! 234: printf("%4d\t", inscost(c, -1)); ! 235: printf("%4d\t", delcost(c)); ! 236: if (repcost(c, YID) != inscost(YID, c) + delcost(c)) ! 237: printf("%4d", repcost(c, YID)); ! 238: printf("\t%s\n", charname(c,1)); ! 239: } ! 240: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.