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