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