BSD 3 development
[unix-history] / usr / src / cmd / pxp / yycosts.c
CommitLineData
5ab61658
BJ
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 "0.h"
17#include "yy.h"
18
19/*
20 * Symbol costs for Pascal.
21 *
22 * Cost strategy of August 14, 1977.
23 *
24 * The costs determined by the routines in this file are used by
25 * the recovery in choosing appropriate corrections.
26 * The cost vectors and the error productions in the grammar
27 * work together to define the corrective capacity of the grammar.
28 *
29 * The costs here largely derive from those given in Steve Rhode's
30 * thesis for the Pascal-I error correcting parser which he implemented.
31 * Some minor changes have been made to adjust for the fact that
32 * the current error recovery is not as "smart", both because of the
33 * limited forward move and because of the lack of any type information
34 * about identifiers.
35 *
36 * These adjustments largely take the form of increased costs for certain
37 * tokens, noticeably keywords which are major brackets such as "begin"
38 * "label", "procedure", etc.
39 *
40 * The overall weighting strategy is still similar to Rhodes' strategy.
41 * The costs can be considered:
42 *
43 * LOW <= 3
44 * MEDIUM 4 or 5
45 * HIGH >= 6
46 */
47 \f
48/*
49 * Insertion costs
50 *
51 * In addition to the normal symbol insertion costs,
52 * there are zero cost insertions here.
53 * The current error recovery system treats symbols
54 * which have zero insertion cost in a special way,
55 * inserting them but suppressing diagnostics.
56 * This allows the system to hold of on bracketing
57 * error diagnostics about missing end's until the
58 * reduction occurs which knows the line number of the
59 * corresponding "begin", "repeat", etc.
60 * A more intelligent and useful diagnostic can then
61 * be printed.
62 *
63 * Although this routine never allows the insertion
64 * of the keyword begin, it can be inserted after a
65 * procedure or function body starts, if it was omitted
66 * by a special case in the panic routine, which notices
67 * the keywords in the statement body of the procedure
68 * and inserts the begin to recover.
69 *
70 * Similarly, we do not insert end-of-file, but
71 * the fact that end-of-file is the unique input
72 * is noticed by the recovery routines as a special
73 * case and handled there.
74 */
75inscost(sy, before)
76 register int sy, before;
77{
78
79 switch (before) {
80 case YEND:
81 if (sy == YEND)
82 break;
83 case YPROCEDURE:
84 case YFUNCTION:
85 if (sy == YUNTIL || sy == YEND)
86 return (0);
87 }
88 switch (sy) {
89 case ';':
90 return (1);
91 case ',':
92 case ':':
93 case YOF:
94 case YDO:
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\f
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 */
137repcost(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\f
175/*
176 * Deletion costs
177 */
178delcost(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\f
211/*
212 * Routine to print out costs with "-C" option.
213 */
214char yysyms[] ";,:=*+/-|&()[]<>~^";
215
216
217yycosts()
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
232yydocost(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