date and time created 80/08/27 22:28:03 by peter
[unix-history] / usr / src / usr.bin / pascal / src / yycosts.c
CommitLineData
ad36cbfe
PK
1/* Copyright (c) 1979 Regents of the University of California */
2
3static char sccsid[] = "@(#)yycosts.c 1.1 %G%";
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 \f
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 */
65inscost(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\f
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 */
127repcost(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\f
165/*
166 * Deletion costs
167 */
168delcost(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\f
201/*
202 * Routine to print out costs with "-K" option.
203 */
204char yysyms[] ";,:=*+/-|&()[]<>~^";
205
206
207yycosts()
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
222yydocost(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