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