Commit | Line | Data |
---|---|---|
ffcc53a7 CH |
1 | # |
2 | /* | |
3 | * pi - Pascal interpreter code translator | |
4 | * | |
5 | * Charles Haley, Bill Joy UCB | |
6 | * Version 1.0 August 1977 | |
7 | * | |
8 | * | |
9 | * pxp - Pascal execution profiler | |
10 | * | |
11 | * Bill Joy UCB | |
12 | * Version 1.0 August 1977 | |
13 | */ | |
14 | ||
15 | #include "whoami" | |
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 | */ | |
75 | inscost(sy, before) | |
76 | int sy, before; | |
77 | { | |
78 | ||
79 | switch (before) { | |
80 | case YPROCEDURE: | |
81 | case YFUNCTION: | |
82 | case YEND: | |
83 | switch (sy) { | |
84 | case YEND: | |
85 | if (before == YEND) | |
86 | break; | |
87 | case YUNTIL: | |
88 | return (0); | |
89 | } | |
90 | } | |
91 | switch (sy) { | |
92 | case ';': | |
93 | return (1); | |
94 | case ',': | |
95 | case ':': | |
96 | case YOF: | |
97 | case YDO: | |
98 | return (2); | |
99 | case YARRAY: | |
100 | case '+': | |
101 | case '*': | |
102 | return (3); | |
103 | default: | |
104 | return (4); | |
105 | case '^': | |
106 | case YNOT: | |
107 | case YLABEL: | |
108 | case YCONST: | |
109 | case YTYPE: | |
110 | case YVAR: | |
111 | case YUNTIL: | |
112 | case '(': | |
113 | case '[': | |
114 | case YWHILE: | |
115 | case YWITH: | |
116 | case YASSERT: | |
117 | return (5); | |
118 | case YPROCEDURE: | |
119 | case YFUNCTION: | |
120 | case YCASE: | |
121 | return (6); | |
122 | case YEND: | |
123 | return (8); | |
124 | case YBEGIN: | |
125 | case YEOF: | |
126 | case YREPEAT: | |
127 | case YRECORD: | |
128 | return (INFINITY); | |
129 | } | |
130 | } | |
131 | \f | |
132 | /* | |
133 | * Replacement costs | |
134 | * | |
135 | * Most replacement costs are the same as an insertion | |
136 | * plus a deletion cost. One special case is the replacement | |
137 | * of a large number of keywords by an identifier. | |
138 | * These are given lower costs, especially the keyword "to". | |
139 | */ | |
140 | repcost(what, with) | |
141 | int what, with; | |
142 | { | |
143 | register int c; | |
144 | ||
145 | if (with == what) | |
146 | return (INFINITY); | |
147 | if (with == YID && what > ERROR) | |
148 | switch (what) { | |
149 | case YID: | |
150 | case YDOTDOT: | |
151 | case YINT: | |
152 | case YBINT: | |
153 | case YSTRING: | |
154 | case YNUMB: | |
155 | break; | |
156 | case YTO: | |
157 | return (3); | |
158 | default: | |
159 | return (5); | |
160 | case YRECORD: | |
161 | case YTHEN: | |
162 | return (6); | |
163 | case YBEGIN: | |
164 | break; | |
165 | } | |
166 | if (what == ';') | |
167 | switch (with) { | |
168 | case ',': | |
169 | case '.': | |
170 | return (CLIMIT - 1); | |
171 | } | |
172 | c = delcost(what) + inscost(with); | |
173 | /* | |
174 | * It costs extra to replace something which has | |
175 | * semantics by something which doesn't. | |
176 | */ | |
177 | if (nullsem(what) == NIL && nullsem(with) != NIL) | |
178 | c =+ 4; | |
179 | return (c); | |
180 | } | |
181 | \f | |
182 | /* | |
183 | * Deletion costs | |
184 | */ | |
185 | delcost(what) | |
186 | int what; | |
187 | { | |
188 | ||
189 | switch (what) { | |
190 | case '.': | |
191 | case ':': | |
192 | case ',': | |
193 | case '=': | |
194 | case '(': | |
195 | return (3); | |
196 | case YELSE: | |
197 | case YTHEN: | |
198 | return (4); | |
199 | default: | |
200 | return (5); | |
201 | case YLABEL: | |
202 | case YCONST: | |
203 | case YTYPE: | |
204 | case YVAR: | |
205 | return (10); | |
206 | case YPROCEDURE: | |
207 | case YFUNCTION: | |
208 | case YBEGIN: | |
209 | case YEND: | |
210 | return ((CLIMIT * 3) / 4); | |
211 | case ';': | |
212 | case YEOF: | |
213 | return (INFINITY); | |
214 | } | |
215 | } | |
216 | #ifdef DEBUG | |
217 | \f | |
218 | /* | |
219 | * Routine to print out costs with "-C" option. | |
220 | */ | |
221 | char yysyms[] ";,:=*+/-|&()[]<>~^"; | |
222 | ||
223 | ||
224 | yycosts() | |
225 | { | |
226 | register int c; | |
227 | register char *cp; | |
228 | ||
229 | printf("Insert\tDelete\tRep(ID)\tSymbol\n"); | |
230 | for (cp = yysyms; *cp; cp++) | |
231 | yydocost(*cp); | |
232 | for (c = ERROR + 1; c < YLAST; c++) | |
233 | yydocost(c); | |
234 | #ifdef PXP | |
235 | flush(); | |
236 | #endif | |
237 | } | |
238 | ||
239 | yydocost(c) | |
240 | int c; | |
241 | { | |
242 | ||
243 | printf("%4d\t", inscost(c, -1)); | |
244 | printf("%4d\t", delcost(c)); | |
245 | if (repcost(c, YID) != inscost(YID) + delcost(c)) | |
246 | printf("%4d", repcost(c, YID)); | |
247 | printf("\t%s%s\n", charname(c)); | |
248 | } | |
249 | #endif |