|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2:
3: static char sccsid[] = "@(#)yycosts.c 1.1 8/27/80";
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: case YASSERT:
104: return (5);
105: case YPROCEDURE:
106: case YFUNCTION:
107: case YCASE:
108: return (6);
109: case YEND:
110: return (8);
111: case YBEGIN:
112: case YEOF:
113: case YREPEAT:
114: case YRECORD:
115: return (INFINITY);
116: }
117: }
118:
119: /*
120: * Replacement costs
121: *
122: * Most replacement costs are the same as an insertion
123: * plus a deletion cost. One special case is the replacement
124: * of a large number of keywords by an identifier.
125: * These are given lower costs, especially the keyword "to".
126: */
127: repcost(what, with)
128: register int what, with;
129: {
130: register int c;
131:
132: if (with == what)
133: return (INFINITY);
134: if (with == YID && what > ERROR)
135: switch (what) {
136: case YID:
137: case YDOTDOT:
138: case YINT:
139: case YBINT:
140: case YSTRING:
141: case YNUMB:
142: break;
143: case YTO:
144: return (3);
145: default:
146: return (5);
147: case YRECORD:
148: case YTHEN:
149: return (6);
150: case YBEGIN:
151: break;
152: }
153: if (what == ';' && (with == ',' || with == '.'))
154: return (CLIMIT - 1);
155: c = delcost(what) + inscost(with);
156: /*
157: * It costs extra to replace something which has
158: * semantics by something which doesn't.
159: */
160: if (nullsem(what) == NIL && nullsem(with) != NIL)
161: c =+ 4;
162: return (c);
163: }
164:
165: /*
166: * Deletion costs
167: */
168: delcost(what)
169: int what;
170: {
171:
172: switch (what) {
173: case '.':
174: case ':':
175: case ',':
176: case '=':
177: case '(':
178: return (3);
179: case YELSE:
180: case YTHEN:
181: return (4);
182: default:
183: return (5);
184: case YLABEL:
185: case YCONST:
186: case YTYPE:
187: case YVAR:
188: return (10);
189: case YPROCEDURE:
190: case YFUNCTION:
191: case YBEGIN:
192: case YEND:
193: return ((CLIMIT * 3) / 4);
194: case ';':
195: case YEOF:
196: return (INFINITY);
197: }
198: }
199: #ifdef DEBUG
200:
201: /*
202: * Routine to print out costs with "-K" option.
203: */
204: char yysyms[] ";,:=*+/-|&()[]<>~^";
205:
206:
207: yycosts()
208: {
209: register int c;
210: register char *cp;
211:
212: printf("Insert\tDelete\tRep(ID)\tSymbol\n");
213: for (cp = yysyms; *cp; cp++)
214: yydocost(*cp);
215: for (c = ERROR + 1; c < YLAST; c++)
216: yydocost(c);
217: #ifdef PXP
218: flush();
219: #endif
220: }
221:
222: yydocost(c)
223: int c;
224: {
225:
226: printf("%4d\t", inscost(c, -1));
227: printf("%4d\t", delcost(c));
228: if (repcost(c, YID) != inscost(YID) + delcost(c))
229: printf("%4d", repcost(c, YID));
230: printf("\t%s%s\n", charname(c));
231: }
232: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.