BSD 3 development
[unix-history] / usr / src / cmd / pi / yycosts.c
CommitLineData
eadd54c1
CH
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 \f
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 */
76inscost(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\f
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 */
138repcost(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\f
176/*
177 * Deletion costs
178 */
179delcost(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\f
212/*
213 * Routine to print out costs with "-C" option.
214 */
215char yysyms[] ";,:=*+/-|&()[]<>~^";
216
217
218yycosts()
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
233yydocost(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