1 |
|
---|
2 | #include "defs.h"
|
---|
3 |
|
---|
4 | extern short *itemset;
|
---|
5 | extern short *itemsetend;
|
---|
6 | extern unsigned *ruleset;
|
---|
7 |
|
---|
8 | int nstates;
|
---|
9 | core *first_state;
|
---|
10 | shifts *first_shift;
|
---|
11 | reductions *first_reduction;
|
---|
12 |
|
---|
13 | int get_state();
|
---|
14 | core *new_state();
|
---|
15 |
|
---|
16 | static core **state_set;
|
---|
17 | static core *this_state;
|
---|
18 | static core *last_state;
|
---|
19 | static shifts *last_shift;
|
---|
20 | static reductions *last_reduction;
|
---|
21 |
|
---|
22 | static int nshifts;
|
---|
23 | static short *shift_symbol;
|
---|
24 |
|
---|
25 | static short *redset;
|
---|
26 | static short *shiftset;
|
---|
27 |
|
---|
28 | static short **kernel_base;
|
---|
29 | static short **kernel_end;
|
---|
30 | static short *kernel_items;
|
---|
31 |
|
---|
32 |
|
---|
33 | allocate_itemsets()
|
---|
34 | {
|
---|
35 | register short *itemp;
|
---|
36 | register short *item_end;
|
---|
37 | register int symbol;
|
---|
38 | register int i;
|
---|
39 | register int count;
|
---|
40 | register int max;
|
---|
41 | register short *symbol_count;
|
---|
42 |
|
---|
43 | count = 0;
|
---|
44 | symbol_count = NEW2(nsyms, short);
|
---|
45 |
|
---|
46 | item_end = ritem + nitems;
|
---|
47 | for (itemp = ritem; itemp < item_end; itemp++)
|
---|
48 | {
|
---|
49 | symbol = *itemp;
|
---|
50 | if (symbol >= 0)
|
---|
51 | {
|
---|
52 | count++;
|
---|
53 | symbol_count[symbol]++;
|
---|
54 | }
|
---|
55 | }
|
---|
56 |
|
---|
57 | kernel_base = NEW2(nsyms, short *);
|
---|
58 | kernel_items = NEW2(count, short);
|
---|
59 |
|
---|
60 | count = 0;
|
---|
61 | max = 0;
|
---|
62 | for (i = 0; i < nsyms; i++)
|
---|
63 | {
|
---|
64 | kernel_base[i] = kernel_items + count;
|
---|
65 | count += symbol_count[i];
|
---|
66 | if (max < symbol_count[i])
|
---|
67 | max = symbol_count[i];
|
---|
68 | }
|
---|
69 |
|
---|
70 | shift_symbol = symbol_count;
|
---|
71 | kernel_end = NEW2(nsyms, short *);
|
---|
72 | }
|
---|
73 |
|
---|
74 |
|
---|
75 | allocate_storage()
|
---|
76 | {
|
---|
77 | allocate_itemsets();
|
---|
78 | shiftset = NEW2(nsyms, short);
|
---|
79 | redset = NEW2(nrules + 1, short);
|
---|
80 | state_set = NEW2(nitems, core *);
|
---|
81 | }
|
---|
82 |
|
---|
83 |
|
---|
84 | append_states()
|
---|
85 | {
|
---|
86 | register int i;
|
---|
87 | register int j;
|
---|
88 | register int symbol;
|
---|
89 |
|
---|
90 | #ifdef TRACE
|
---|
91 | fprintf(stderr, "Entering append_states()\n");
|
---|
92 | #endif
|
---|
93 | for (i = 1; i < nshifts; i++)
|
---|
94 | {
|
---|
95 | symbol = shift_symbol[i];
|
---|
96 | j = i;
|
---|
97 | while (j > 0 && shift_symbol[j - 1] > symbol)
|
---|
98 | {
|
---|
99 | shift_symbol[j] = shift_symbol[j - 1];
|
---|
100 | j--;
|
---|
101 | }
|
---|
102 | shift_symbol[j] = symbol;
|
---|
103 | }
|
---|
104 |
|
---|
105 | for (i = 0; i < nshifts; i++)
|
---|
106 | {
|
---|
107 | symbol = shift_symbol[i];
|
---|
108 | shiftset[i] = get_state(symbol);
|
---|
109 | }
|
---|
110 | }
|
---|
111 |
|
---|
112 |
|
---|
113 | free_storage()
|
---|
114 | {
|
---|
115 | FREE(shift_symbol);
|
---|
116 | FREE(redset);
|
---|
117 | FREE(shiftset);
|
---|
118 | FREE(kernel_base);
|
---|
119 | FREE(kernel_end);
|
---|
120 | FREE(kernel_items);
|
---|
121 | FREE(state_set);
|
---|
122 | }
|
---|
123 |
|
---|
124 |
|
---|
125 |
|
---|
126 | generate_states()
|
---|
127 | {
|
---|
128 | allocate_storage();
|
---|
129 | itemset = NEW2(nitems, short);
|
---|
130 | ruleset = NEW2(WORDSIZE(nrules), unsigned);
|
---|
131 | set_first_derives();
|
---|
132 | initialize_states();
|
---|
133 |
|
---|
134 | while (this_state)
|
---|
135 | {
|
---|
136 | closure(this_state->items, this_state->nitems);
|
---|
137 | save_reductions();
|
---|
138 | new_itemsets();
|
---|
139 | append_states();
|
---|
140 |
|
---|
141 | if (nshifts > 0)
|
---|
142 | save_shifts();
|
---|
143 |
|
---|
144 | this_state = this_state->next;
|
---|
145 | }
|
---|
146 |
|
---|
147 | finalize_closure();
|
---|
148 | free_storage();
|
---|
149 | }
|
---|
150 |
|
---|
151 |
|
---|
152 |
|
---|
153 | int
|
---|
154 | get_state(symbol)
|
---|
155 | int symbol;
|
---|
156 | {
|
---|
157 | register int key;
|
---|
158 | register short *isp1;
|
---|
159 | register short *isp2;
|
---|
160 | register short *iend;
|
---|
161 | register core *sp;
|
---|
162 | register int found;
|
---|
163 | register int n;
|
---|
164 |
|
---|
165 | #ifdef TRACE
|
---|
166 | fprintf(stderr, "Entering get_state(%d)\n", symbol);
|
---|
167 | #endif
|
---|
168 |
|
---|
169 | isp1 = kernel_base[symbol];
|
---|
170 | iend = kernel_end[symbol];
|
---|
171 | n = iend - isp1;
|
---|
172 |
|
---|
173 | key = *isp1;
|
---|
174 | assert(0 <= key && key < nitems);
|
---|
175 | sp = state_set[key];
|
---|
176 | if (sp)
|
---|
177 | {
|
---|
178 | found = 0;
|
---|
179 | while (!found)
|
---|
180 | {
|
---|
181 | if (sp->nitems == n)
|
---|
182 | {
|
---|
183 | found = 1;
|
---|
184 | isp1 = kernel_base[symbol];
|
---|
185 | isp2 = sp->items;
|
---|
186 |
|
---|
187 | while (found && isp1 < iend)
|
---|
188 | {
|
---|
189 | if (*isp1++ != *isp2++)
|
---|
190 | found = 0;
|
---|
191 | }
|
---|
192 | }
|
---|
193 |
|
---|
194 | if (!found)
|
---|
195 | {
|
---|
196 | if (sp->link)
|
---|
197 | {
|
---|
198 | sp = sp->link;
|
---|
199 | }
|
---|
200 | else
|
---|
201 | {
|
---|
202 | sp = sp->link = new_state(symbol);
|
---|
203 | found = 1;
|
---|
204 | }
|
---|
205 | }
|
---|
206 | }
|
---|
207 | }
|
---|
208 | else
|
---|
209 | {
|
---|
210 | state_set[key] = sp = new_state(symbol);
|
---|
211 | }
|
---|
212 |
|
---|
213 | return (sp->number);
|
---|
214 | }
|
---|
215 |
|
---|
216 |
|
---|
217 |
|
---|
218 | initialize_states()
|
---|
219 | {
|
---|
220 | register int i;
|
---|
221 | register short *start_derives;
|
---|
222 | register core *p;
|
---|
223 |
|
---|
224 | start_derives = derives[start_symbol];
|
---|
225 | for (i = 0; start_derives[i] >= 0; ++i)
|
---|
226 | continue;
|
---|
227 |
|
---|
228 | p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
|
---|
229 | if (p == 0) no_space();
|
---|
230 |
|
---|
231 | p->next = 0;
|
---|
232 | p->link = 0;
|
---|
233 | p->number = 0;
|
---|
234 | p->accessing_symbol = 0;
|
---|
235 | p->nitems = i;
|
---|
236 |
|
---|
237 | for (i = 0; start_derives[i] >= 0; ++i)
|
---|
238 | p->items[i] = rrhs[start_derives[i]];
|
---|
239 |
|
---|
240 | first_state = last_state = this_state = p;
|
---|
241 | nstates = 1;
|
---|
242 | }
|
---|
243 |
|
---|
244 |
|
---|
245 | new_itemsets()
|
---|
246 | {
|
---|
247 | register int i;
|
---|
248 | register int shiftcount;
|
---|
249 | register short *isp;
|
---|
250 | register short *ksp;
|
---|
251 | register int symbol;
|
---|
252 |
|
---|
253 | for (i = 0; i < nsyms; i++)
|
---|
254 | kernel_end[i] = 0;
|
---|
255 |
|
---|
256 | shiftcount = 0;
|
---|
257 | isp = itemset;
|
---|
258 | while (isp < itemsetend)
|
---|
259 | {
|
---|
260 | i = *isp++;
|
---|
261 | symbol = ritem[i];
|
---|
262 | if (symbol > 0)
|
---|
263 | {
|
---|
264 | ksp = kernel_end[symbol];
|
---|
265 | if (!ksp)
|
---|
266 | {
|
---|
267 | shift_symbol[shiftcount++] = symbol;
|
---|
268 | ksp = kernel_base[symbol];
|
---|
269 | }
|
---|
270 |
|
---|
271 | *ksp++ = i + 1;
|
---|
272 | kernel_end[symbol] = ksp;
|
---|
273 | }
|
---|
274 | }
|
---|
275 |
|
---|
276 | nshifts = shiftcount;
|
---|
277 | }
|
---|
278 |
|
---|
279 |
|
---|
280 |
|
---|
281 | core *
|
---|
282 | new_state(symbol)
|
---|
283 | int symbol;
|
---|
284 | {
|
---|
285 | register int n;
|
---|
286 | register core *p;
|
---|
287 | register short *isp1;
|
---|
288 | register short *isp2;
|
---|
289 | register short *iend;
|
---|
290 |
|
---|
291 | #ifdef TRACE
|
---|
292 | fprintf(stderr, "Entering new_state(%d)\n", symbol);
|
---|
293 | #endif
|
---|
294 |
|
---|
295 | if (nstates >= MAXSHORT)
|
---|
296 | fatal("too many states");
|
---|
297 |
|
---|
298 | isp1 = kernel_base[symbol];
|
---|
299 | iend = kernel_end[symbol];
|
---|
300 | n = iend - isp1;
|
---|
301 |
|
---|
302 | p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
|
---|
303 | p->accessing_symbol = symbol;
|
---|
304 | p->number = nstates;
|
---|
305 | p->nitems = n;
|
---|
306 |
|
---|
307 | isp2 = p->items;
|
---|
308 | while (isp1 < iend)
|
---|
309 | *isp2++ = *isp1++;
|
---|
310 |
|
---|
311 | last_state->next = p;
|
---|
312 | last_state = p;
|
---|
313 |
|
---|
314 | nstates++;
|
---|
315 |
|
---|
316 | return (p);
|
---|
317 | }
|
---|
318 |
|
---|
319 |
|
---|
320 | /* show_cores is used for debugging */
|
---|
321 |
|
---|
322 | show_cores()
|
---|
323 | {
|
---|
324 | core *p;
|
---|
325 | int i, j, k, n;
|
---|
326 | int itemno;
|
---|
327 |
|
---|
328 | k = 0;
|
---|
329 | for (p = first_state; p; ++k, p = p->next)
|
---|
330 | {
|
---|
331 | if (k) printf("\n");
|
---|
332 | printf("state %d, number = %d, accessing symbol = %s\n",
|
---|
333 | k, p->number, symbol_name[p->accessing_symbol]);
|
---|
334 | n = p->nitems;
|
---|
335 | for (i = 0; i < n; ++i)
|
---|
336 | {
|
---|
337 | itemno = p->items[i];
|
---|
338 | printf("%4d ", itemno);
|
---|
339 | j = itemno;
|
---|
340 | while (ritem[j] >= 0) ++j;
|
---|
341 | printf("%s :", symbol_name[rlhs[-ritem[j]]]);
|
---|
342 | j = rrhs[-ritem[j]];
|
---|
343 | while (j < itemno)
|
---|
344 | printf(" %s", symbol_name[ritem[j++]]);
|
---|
345 | printf(" .");
|
---|
346 | while (ritem[j] >= 0)
|
---|
347 | printf(" %s", symbol_name[ritem[j++]]);
|
---|
348 | printf("\n");
|
---|
349 | fflush(stdout);
|
---|
350 | }
|
---|
351 | }
|
---|
352 | }
|
---|
353 |
|
---|
354 |
|
---|
355 | /* show_ritems is used for debugging */
|
---|
356 |
|
---|
357 | show_ritems()
|
---|
358 | {
|
---|
359 | int i;
|
---|
360 |
|
---|
361 | for (i = 0; i < nitems; ++i)
|
---|
362 | printf("ritem[%d] = %d\n", i, ritem[i]);
|
---|
363 | }
|
---|
364 |
|
---|
365 |
|
---|
366 | /* show_rrhs is used for debugging */
|
---|
367 | show_rrhs()
|
---|
368 | {
|
---|
369 | int i;
|
---|
370 |
|
---|
371 | for (i = 0; i < nrules; ++i)
|
---|
372 | printf("rrhs[%d] = %d\n", i, rrhs[i]);
|
---|
373 | }
|
---|
374 |
|
---|
375 |
|
---|
376 | /* show_shifts is used for debugging */
|
---|
377 |
|
---|
378 | show_shifts()
|
---|
379 | {
|
---|
380 | shifts *p;
|
---|
381 | int i, j, k;
|
---|
382 |
|
---|
383 | k = 0;
|
---|
384 | for (p = first_shift; p; ++k, p = p->next)
|
---|
385 | {
|
---|
386 | if (k) printf("\n");
|
---|
387 | printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
|
---|
388 | p->nshifts);
|
---|
389 | j = p->nshifts;
|
---|
390 | for (i = 0; i < j; ++i)
|
---|
391 | printf("\t%d\n", p->shift[i]);
|
---|
392 | }
|
---|
393 | }
|
---|
394 |
|
---|
395 |
|
---|
396 | save_shifts()
|
---|
397 | {
|
---|
398 | register shifts *p;
|
---|
399 | register short *sp1;
|
---|
400 | register short *sp2;
|
---|
401 | register short *send;
|
---|
402 |
|
---|
403 | p = (shifts *) allocate((unsigned) (sizeof(shifts) +
|
---|
404 | (nshifts - 1) * sizeof(short)));
|
---|
405 |
|
---|
406 | p->number = this_state->number;
|
---|
407 | p->nshifts = nshifts;
|
---|
408 |
|
---|
409 | sp1 = shiftset;
|
---|
410 | sp2 = p->shift;
|
---|
411 | send = shiftset + nshifts;
|
---|
412 |
|
---|
413 | while (sp1 < send)
|
---|
414 | *sp2++ = *sp1++;
|
---|
415 |
|
---|
416 | if (last_shift)
|
---|
417 | {
|
---|
418 | last_shift->next = p;
|
---|
419 | last_shift = p;
|
---|
420 | }
|
---|
421 | else
|
---|
422 | {
|
---|
423 | first_shift = p;
|
---|
424 | last_shift = p;
|
---|
425 | }
|
---|
426 | }
|
---|
427 |
|
---|
428 |
|
---|
429 |
|
---|
430 | save_reductions()
|
---|
431 | {
|
---|
432 | register short *isp;
|
---|
433 | register short *rp1;
|
---|
434 | register short *rp2;
|
---|
435 | register int item;
|
---|
436 | register int count;
|
---|
437 | register reductions *p;
|
---|
438 | register short *rend;
|
---|
439 |
|
---|
440 | count = 0;
|
---|
441 | for (isp = itemset; isp < itemsetend; isp++)
|
---|
442 | {
|
---|
443 | item = ritem[*isp];
|
---|
444 | if (item < 0)
|
---|
445 | {
|
---|
446 | redset[count++] = -item;
|
---|
447 | }
|
---|
448 | }
|
---|
449 |
|
---|
450 | if (count)
|
---|
451 | {
|
---|
452 | p = (reductions *) allocate((unsigned) (sizeof(reductions) +
|
---|
453 | (count - 1) * sizeof(short)));
|
---|
454 |
|
---|
455 | p->number = this_state->number;
|
---|
456 | p->nreds = count;
|
---|
457 |
|
---|
458 | rp1 = redset;
|
---|
459 | rp2 = p->rules;
|
---|
460 | rend = rp1 + count;
|
---|
461 |
|
---|
462 | while (rp1 < rend)
|
---|
463 | *rp2++ = *rp1++;
|
---|
464 |
|
---|
465 | if (last_reduction)
|
---|
466 | {
|
---|
467 | last_reduction->next = p;
|
---|
468 | last_reduction = p;
|
---|
469 | }
|
---|
470 | else
|
---|
471 | {
|
---|
472 | first_reduction = p;
|
---|
473 | last_reduction = p;
|
---|
474 | }
|
---|
475 | }
|
---|
476 | }
|
---|
477 |
|
---|
478 |
|
---|
479 | set_derives()
|
---|
480 | {
|
---|
481 | register int i, k;
|
---|
482 | register int lhs;
|
---|
483 | register short *rules;
|
---|
484 |
|
---|
485 | derives = NEW2(nsyms, short *);
|
---|
486 | rules = NEW2(nvars + nrules, short);
|
---|
487 |
|
---|
488 | k = 0;
|
---|
489 | for (lhs = start_symbol; lhs < nsyms; lhs++)
|
---|
490 | {
|
---|
491 | derives[lhs] = rules + k;
|
---|
492 | for (i = 0; i < nrules; i++)
|
---|
493 | {
|
---|
494 | if (rlhs[i] == lhs)
|
---|
495 | {
|
---|
496 | rules[k] = i;
|
---|
497 | k++;
|
---|
498 | }
|
---|
499 | }
|
---|
500 | rules[k] = -1;
|
---|
501 | k++;
|
---|
502 | }
|
---|
503 |
|
---|
504 | #ifdef DEBUG
|
---|
505 | print_derives();
|
---|
506 | #endif
|
---|
507 | }
|
---|
508 |
|
---|
509 | free_derives()
|
---|
510 | {
|
---|
511 | FREE(derives[start_symbol]);
|
---|
512 | FREE(derives);
|
---|
513 | }
|
---|
514 |
|
---|
515 | #ifdef DEBUG
|
---|
516 | print_derives()
|
---|
517 | {
|
---|
518 | register int i;
|
---|
519 | register short *sp;
|
---|
520 |
|
---|
521 | printf("\nDERIVES\n\n");
|
---|
522 |
|
---|
523 | for (i = start_symbol; i < nsyms; i++)
|
---|
524 | {
|
---|
525 | printf("%s derives ", symbol_name[i]);
|
---|
526 | for (sp = derives[i]; *sp >= 0; sp++)
|
---|
527 | {
|
---|
528 | printf(" %d", *sp);
|
---|
529 | }
|
---|
530 | putchar('\n');
|
---|
531 | }
|
---|
532 |
|
---|
533 | putchar('\n');
|
---|
534 | }
|
---|
535 | #endif
|
---|
536 |
|
---|
537 |
|
---|
538 | set_nullable()
|
---|
539 | {
|
---|
540 | register int i, j;
|
---|
541 | register int empty;
|
---|
542 | int done;
|
---|
543 |
|
---|
544 | nullable = MALLOC(nsyms);
|
---|
545 | if (nullable == 0) no_space();
|
---|
546 |
|
---|
547 | for (i = 0; i < nsyms; ++i)
|
---|
548 | nullable[i] = 0;
|
---|
549 |
|
---|
550 | done = 0;
|
---|
551 | while (!done)
|
---|
552 | {
|
---|
553 | done = 1;
|
---|
554 | for (i = 1; i < nitems; i++)
|
---|
555 | {
|
---|
556 | empty = 1;
|
---|
557 | while ((j = ritem[i]) >= 0)
|
---|
558 | {
|
---|
559 | if (!nullable[j])
|
---|
560 | empty = 0;
|
---|
561 | ++i;
|
---|
562 | }
|
---|
563 | if (empty)
|
---|
564 | {
|
---|
565 | j = rlhs[-j];
|
---|
566 | if (!nullable[j])
|
---|
567 | {
|
---|
568 | nullable[j] = 1;
|
---|
569 | done = 0;
|
---|
570 | }
|
---|
571 | }
|
---|
572 | }
|
---|
573 | }
|
---|
574 |
|
---|
575 | #ifdef DEBUG
|
---|
576 | for (i = 0; i < nsyms; i++)
|
---|
577 | {
|
---|
578 | if (nullable[i])
|
---|
579 | printf("%s is nullable\n", symbol_name[i]);
|
---|
580 | else
|
---|
581 | printf("%s is not nullable\n", symbol_name[i]);
|
---|
582 | }
|
---|
583 | #endif
|
---|
584 | }
|
---|
585 |
|
---|
586 |
|
---|
587 | free_nullable()
|
---|
588 | {
|
---|
589 | FREE(nullable);
|
---|
590 | }
|
---|
591 |
|
---|
592 |
|
---|
593 | lr0()
|
---|
594 | {
|
---|
595 | set_derives();
|
---|
596 | set_nullable();
|
---|
597 | generate_states();
|
---|
598 | }
|
---|