]> git.saurik.com Git - bison.git/blame - src/LR0.c
* src/LR0.c (new_state, get_state): Complete TRACE code.
[bison.git] / src / LR0.c
CommitLineData
40675e7c 1/* Generate the nondeterministic finite state machine for bison,
aa7815f5 2 Copyright 1984, 1986, 1989, 2000 Free Software Foundation, Inc.
40675e7c 3
2fa6973e 4 This file is part of Bison, the GNU Compiler Compiler.
40675e7c 5
2fa6973e
AD
6 Bison is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
40675e7c 10
2fa6973e
AD
11 Bison is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
40675e7c 15
2fa6973e
AD
16 You should have received a copy of the GNU General Public License
17 along with Bison; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
40675e7c
DM
20
21
22/* See comments in state.h for the data structures that represent it.
23 The entry point is generate_states. */
24
40675e7c 25#include "system.h"
40675e7c
DM
26#include "gram.h"
27#include "state.h"
a0f6b076 28#include "complain.h"
2fa6973e 29#include "closure.h"
403b315b 30#include "LR0.h"
40675e7c 31
40675e7c 32
40675e7c
DM
33int nstates;
34int final_state;
342b8b6e
AD
35core *first_state = NULL;
36shifts *first_shift = NULL;
37reductions *first_reduction = NULL;
40675e7c 38
342b8b6e
AD
39static core *this_state = NULL;
40static core *last_state = NULL;
41static shifts *last_shift = NULL;
42static reductions *last_reduction = NULL;
40675e7c
DM
43
44static int nshifts;
342b8b6e 45static short *shift_symbol = NULL;
40675e7c 46
342b8b6e
AD
47static short *redset = NULL;
48static short *shiftset = NULL;
40675e7c 49
342b8b6e
AD
50static short **kernel_base = NULL;
51static short **kernel_end = NULL;
52static short *kernel_items = NULL;
40675e7c
DM
53
54/* hash table for states, to recognize equivalent ones. */
55
56#define STATE_TABLE_SIZE 1009
342b8b6e 57static core **state_table = NULL;
40675e7c 58
2fa6973e 59\f
4a120d45 60static void
d2729d44 61allocate_itemsets (void)
40675e7c 62{
342b8b6e 63 short *itemp = NULL;
2fa6973e
AD
64 int symbol;
65 int i;
66 int count;
342b8b6e 67 short *symbol_count = NULL;
40675e7c
DM
68
69 count = 0;
d7913476 70 symbol_count = XCALLOC (short, nsyms);
40675e7c
DM
71
72 itemp = ritem;
73 symbol = *itemp++;
74 while (symbol)
75 {
76 if (symbol > 0)
77 {
78 count++;
79 symbol_count[symbol]++;
80 }
81 symbol = *itemp++;
82 }
83
2fa6973e
AD
84 /* See comments before new_itemsets. All the vectors of items
85 live inside KERNEL_ITEMS. The number of active items after
40675e7c
DM
86 some symbol cannot be more than the number of times that symbol
87 appears as an item, which is symbol_count[symbol].
88 We allocate that much space for each symbol. */
89
d7913476 90 kernel_base = XCALLOC (short *, nsyms);
342b8b6e
AD
91 if (count)
92 kernel_items = XCALLOC (short, count);
40675e7c
DM
93
94 count = 0;
95 for (i = 0; i < nsyms; i++)
96 {
97 kernel_base[i] = kernel_items + count;
98 count += symbol_count[i];
99 }
100
101 shift_symbol = symbol_count;
d7913476 102 kernel_end = XCALLOC (short *, nsyms);
40675e7c
DM
103}
104
105
4a120d45 106static void
d2729d44 107allocate_storage (void)
40675e7c 108{
2fa6973e 109 allocate_itemsets ();
40675e7c 110
d7913476
AD
111 shiftset = XCALLOC (short, nsyms);
112 redset = XCALLOC (short, nrules + 1);
113 state_table = XCALLOC (core *, STATE_TABLE_SIZE);
40675e7c
DM
114}
115
116
4a120d45 117static void
d2729d44 118free_storage (void)
40675e7c 119{
d7913476
AD
120 XFREE (shift_symbol);
121 XFREE (redset);
122 XFREE (shiftset);
123 XFREE (kernel_base);
124 XFREE (kernel_end);
125 XFREE (kernel_items);
126 XFREE (state_table);
40675e7c
DM
127}
128
129
130
40675e7c 131
2fa6973e
AD
132/*----------------------------------------------------------------.
133| Find which symbols can be shifted in the current state, and for |
134| each one record which items would be active after that shift. |
135| Uses the contents of itemset. |
136| |
137| shift_symbol is set to a vector of the symbols that can be |
138| shifted. For each symbol in the grammar, kernel_base[symbol] |
139| points to a vector of item numbers activated if that symbol is |
140| shifted, and kernel_end[symbol] points after the end of that |
141| vector. |
142`----------------------------------------------------------------*/
40675e7c 143
4a120d45 144static void
d2729d44 145new_itemsets (void)
40675e7c 146{
2fa6973e
AD
147 int i;
148 int shiftcount;
149 short *isp;
150 short *ksp;
151 int symbol;
152
153#if TRACE
f59c437a
AD
154 fprintf (stderr, "Entering new_itemsets, state = %d\n",
155 this_state->number);
40675e7c
DM
156#endif
157
158 for (i = 0; i < nsyms; i++)
159 kernel_end[i] = NULL;
160
161 shiftcount = 0;
162
163 isp = itemset;
164
165 while (isp < itemsetend)
166 {
167 i = *isp++;
168 symbol = ritem[i];
169 if (symbol > 0)
170 {
2fa6973e 171 ksp = kernel_end[symbol];
40675e7c 172
2fa6973e 173 if (!ksp)
40675e7c
DM
174 {
175 shift_symbol[shiftcount++] = symbol;
176 ksp = kernel_base[symbol];
177 }
178
2fa6973e
AD
179 *ksp++ = i + 1;
180 kernel_end[symbol] = ksp;
40675e7c
DM
181 }
182 }
183
184 nshifts = shiftcount;
185}
186
187
188
2fa6973e
AD
189/*-----------------------------------------------------------------.
190| Subroutine of get_state. Create a new state for those items, if |
191| necessary. |
192`-----------------------------------------------------------------*/
40675e7c 193
2fa6973e
AD
194static core *
195new_state (int symbol)
40675e7c 196{
2fa6973e
AD
197 int n;
198 core *p;
40675e7c 199
2fa6973e 200#if TRACE
2c5f66ed
AD
201 fprintf (stderr, "Entering new_state, state = %d, symbol = %d\n",
202 nstates, symbol);
40675e7c
DM
203#endif
204
2fa6973e
AD
205 if (nstates >= MAXSHORT)
206 fatal (_("too many states (max %d)"), MAXSHORT);
40675e7c 207
300f275f 208 n = kernel_end[symbol] - kernel_base[symbol];
40675e7c 209
f59c437a 210 p = CORE_ALLOC (n);
2fa6973e
AD
211 p->accessing_symbol = symbol;
212 p->number = nstates;
213 p->nitems = n;
214
300f275f 215 shortcpy (p->items, kernel_base[symbol], n);
2fa6973e
AD
216
217 last_state->next = p;
218 last_state = p;
40675e7c 219
2fa6973e 220 nstates++;
40675e7c 221
2fa6973e
AD
222 return p;
223}
40675e7c 224
2fa6973e
AD
225
226/*--------------------------------------------------------------.
227| Find the state number for the state we would get to (from the |
228| current state) by shifting symbol. Create a new state if no |
229| equivalent one exists already. Used by append_states. |
230`--------------------------------------------------------------*/
40675e7c 231
4a120d45 232static int
d2729d44 233get_state (int symbol)
40675e7c 234{
2fa6973e
AD
235 int key;
236 short *isp1;
237 short *isp2;
238 short *iend;
239 core *sp;
240 int found;
40675e7c
DM
241
242 int n;
243
2fa6973e 244#if TRACE
2c5f66ed
AD
245 fprintf (stderr, "Entering get_state, state = %d, symbol = %d\n",
246 nstates, symbol);
40675e7c
DM
247#endif
248
249 isp1 = kernel_base[symbol];
250 iend = kernel_end[symbol];
251 n = iend - isp1;
252
253 /* add up the target state's active item numbers to get a hash key */
254 key = 0;
255 while (isp1 < iend)
256 key += *isp1++;
257
258 key = key % STATE_TABLE_SIZE;
259
260 sp = state_table[key];
261
262 if (sp)
263 {
264 found = 0;
265 while (!found)
266 {
267 if (sp->nitems == n)
268 {
269 found = 1;
270 isp1 = kernel_base[symbol];
271 isp2 = sp->items;
272
273 while (found && isp1 < iend)
274 {
275 if (*isp1++ != *isp2++)
276 found = 0;
277 }
278 }
279
280 if (!found)
281 {
282 if (sp->link)
283 {
284 sp = sp->link;
285 }
2fa6973e 286 else /* bucket exhausted and no match */
40675e7c 287 {
2fa6973e 288 sp = sp->link = new_state (symbol);
40675e7c
DM
289 found = 1;
290 }
291 }
292 }
293 }
2fa6973e 294 else /* bucket is empty */
40675e7c 295 {
2fa6973e 296 state_table[key] = sp = new_state (symbol);
40675e7c
DM
297 }
298
36281465 299 return sp->number;
40675e7c
DM
300}
301
2fa6973e
AD
302/*------------------------------------------------------------------.
303| Use the information computed by new_itemsets to find the state |
304| numbers reached by each shift transition from the current state. |
305| |
306| shiftset is set up as a vector of state numbers of those states. |
307`------------------------------------------------------------------*/
40675e7c 308
2fa6973e
AD
309static void
310append_states (void)
40675e7c 311{
2fa6973e
AD
312 int i;
313 int j;
314 int symbol;
40675e7c 315
2fa6973e
AD
316#if TRACE
317 fprintf (stderr, "Entering append_states\n");
318#endif
40675e7c 319
2fa6973e 320 /* first sort shift_symbol into increasing order */
40675e7c 321
2fa6973e
AD
322 for (i = 1; i < nshifts; i++)
323 {
324 symbol = shift_symbol[i];
325 j = i;
326 while (j > 0 && shift_symbol[j - 1] > symbol)
327 {
328 shift_symbol[j] = shift_symbol[j - 1];
329 j--;
330 }
331 shift_symbol[j] = symbol;
332 }
40675e7c 333
2fa6973e
AD
334 for (i = 0; i < nshifts; i++)
335 {
336 symbol = shift_symbol[i];
337 shiftset[i] = get_state (symbol);
338 }
40675e7c
DM
339}
340
341
4a120d45 342static void
2fa6973e 343new_states (void)
40675e7c 344{
2fa6973e 345 core *p;
40675e7c 346
f59c437a 347 p = CORE_ALLOC (0);
40675e7c
DM
348 first_state = last_state = this_state = p;
349 nstates = 1;
350}
351
352
4a120d45 353static void
d2729d44 354save_shifts (void)
40675e7c 355{
2fa6973e 356 shifts *p;
40675e7c 357
f59c437a 358 p = SHIFTS_ALLOC (nshifts);
40675e7c
DM
359
360 p->number = this_state->number;
361 p->nshifts = nshifts;
362
300f275f 363 shortcpy (p->shifts, shiftset, nshifts);
40675e7c
DM
364
365 if (last_shift)
366 {
367 last_shift->next = p;
368 last_shift = p;
369 }
370 else
371 {
372 first_shift = p;
373 last_shift = p;
374 }
375}
376
377
2fa6973e
AD
378/*------------------------------------------------------------------.
379| Subroutine of augment_automaton. Create the next-to-final state, |
380| to which a shift has already been made in the initial state. |
381`------------------------------------------------------------------*/
40675e7c 382
4a120d45 383static void
2fa6973e 384insert_start_shift (void)
40675e7c 385{
2fa6973e
AD
386 core *statep;
387 shifts *sp;
40675e7c 388
f59c437a 389 statep = CORE_ALLOC (0);
2fa6973e
AD
390 statep->number = nstates;
391 statep->accessing_symbol = start_symbol;
40675e7c 392
2fa6973e
AD
393 last_state->next = statep;
394 last_state = statep;
40675e7c 395
2fa6973e 396 /* Make a shift from this state to (what will be) the final state. */
f59c437a 397 sp = SHIFTS_ALLOC (1);
2fa6973e
AD
398 sp->number = nstates++;
399 sp->nshifts = 1;
400 sp->shifts[0] = nstates;
40675e7c 401
2fa6973e
AD
402 last_shift->next = sp;
403 last_shift = sp;
40675e7c
DM
404}
405
406
2fa6973e
AD
407/*------------------------------------------------------------------.
408| Make sure that the initial state has a shift that accepts the |
409| grammar's start symbol and goes to the next-to-final state, which |
410| has a shift going to the final state, which has a shift to the |
411| termination state. Create such states and shifts if they don't |
412| happen to exist already. |
413`------------------------------------------------------------------*/
40675e7c 414
4a120d45 415static void
d2729d44 416augment_automaton (void)
40675e7c 417{
2fa6973e
AD
418 int i;
419 int k;
420 core *statep;
421 shifts *sp;
422 shifts *sp2;
423 shifts *sp1 = NULL;
40675e7c
DM
424
425 sp = first_shift;
426
427 if (sp)
428 {
429 if (sp->number == 0)
430 {
431 k = sp->nshifts;
432 statep = first_state->next;
433
434 /* The states reached by shifts from first_state are numbered 1...K.
435 Look for one reached by start_symbol. */
436 while (statep->accessing_symbol < start_symbol
2fa6973e 437 && statep->number < k)
40675e7c
DM
438 statep = statep->next;
439
440 if (statep->accessing_symbol == start_symbol)
441 {
442 /* We already have a next-to-final state.
2fa6973e 443 Make sure it has a shift to what will be the final state. */
40675e7c
DM
444 k = statep->number;
445
446 while (sp && sp->number < k)
447 {
448 sp1 = sp;
449 sp = sp->next;
450 }
451
452 if (sp && sp->number == k)
453 {
f59c437a 454 sp2 = SHIFTS_ALLOC (sp->nshifts + 1);
40675e7c
DM
455 sp2->number = k;
456 sp2->nshifts = sp->nshifts + 1;
457 sp2->shifts[0] = nstates;
458 for (i = sp->nshifts; i > 0; i--)
459 sp2->shifts[i] = sp->shifts[i - 1];
460
461 /* Patch sp2 into the chain of shifts in place of sp,
462 following sp1. */
463 sp2->next = sp->next;
464 sp1->next = sp2;
465 if (sp == last_shift)
466 last_shift = sp2;
d7913476 467 XFREE (sp);
40675e7c
DM
468 }
469 else
470 {
f59c437a 471 sp2 = SHIFTS_ALLOC (1);
40675e7c
DM
472 sp2->number = k;
473 sp2->nshifts = 1;
474 sp2->shifts[0] = nstates;
475
476 /* Patch sp2 into the chain of shifts between sp1 and sp. */
477 sp2->next = sp;
478 sp1->next = sp2;
479 if (sp == 0)
480 last_shift = sp2;
481 }
482 }
483 else
484 {
485 /* There is no next-to-final state as yet. */
486 /* Add one more shift in first_shift,
2fa6973e 487 going to the next-to-final state (yet to be made). */
40675e7c
DM
488 sp = first_shift;
489
f59c437a 490 sp2 = SHIFTS_ALLOC (sp->nshifts + 1);
40675e7c
DM
491 sp2->nshifts = sp->nshifts + 1;
492
493 /* Stick this shift into the vector at the proper place. */
494 statep = first_state->next;
495 for (k = 0, i = 0; i < sp->nshifts; k++, i++)
496 {
497 if (statep->accessing_symbol > start_symbol && i == k)
498 sp2->shifts[k++] = nstates;
499 sp2->shifts[k] = sp->shifts[i];
500 statep = statep->next;
501 }
502 if (i == k)
503 sp2->shifts[k++] = nstates;
504
505 /* Patch sp2 into the chain of shifts
2fa6973e 506 in place of sp, at the beginning. */
40675e7c
DM
507 sp2->next = sp->next;
508 first_shift = sp2;
509 if (last_shift == sp)
510 last_shift = sp2;
511
d7913476 512 XFREE (sp);
40675e7c
DM
513
514 /* Create the next-to-final state, with shift to
2fa6973e
AD
515 what will be the final state. */
516 insert_start_shift ();
40675e7c
DM
517 }
518 }
519 else
520 {
521 /* The initial state didn't even have any shifts.
522 Give it one shift, to the next-to-final state. */
f59c437a 523 sp = SHIFTS_ALLOC (1);
40675e7c
DM
524 sp->nshifts = 1;
525 sp->shifts[0] = nstates;
526
527 /* Patch sp into the chain of shifts at the beginning. */
528 sp->next = first_shift;
529 first_shift = sp;
530
531 /* Create the next-to-final state, with shift to
532 what will be the final state. */
2fa6973e 533 insert_start_shift ();
40675e7c
DM
534 }
535 }
536 else
537 {
538 /* There are no shifts for any state.
2fa6973e 539 Make one shift, from the initial state to the next-to-final state. */
40675e7c 540
f59c437a 541 sp = SHIFTS_ALLOC (1);
40675e7c
DM
542 sp->nshifts = 1;
543 sp->shifts[0] = nstates;
544
545 /* Initialize the chain of shifts with sp. */
546 first_shift = sp;
547 last_shift = sp;
548
549 /* Create the next-to-final state, with shift to
2fa6973e
AD
550 what will be the final state. */
551 insert_start_shift ();
40675e7c
DM
552 }
553
554 /* Make the final state--the one that follows a shift from the
555 next-to-final state.
556 The symbol for that shift is 0 (end-of-file). */
f59c437a 557 statep = CORE_ALLOC (0);
40675e7c
DM
558 statep->number = nstates;
559 last_state->next = statep;
560 last_state = statep;
561
562 /* Make the shift from the final state to the termination state. */
f59c437a 563 sp = SHIFTS_ALLOC (1);
40675e7c
DM
564 sp->number = nstates++;
565 sp->nshifts = 1;
566 sp->shifts[0] = nstates;
567 last_shift->next = sp;
568 last_shift = sp;
569
570 /* Note that the variable `final_state' refers to what we sometimes call
571 the termination state. */
572 final_state = nstates;
573
574 /* Make the termination state. */
f59c437a 575 statep = CORE_ALLOC (0);
40675e7c
DM
576 statep->number = nstates++;
577 last_state->next = statep;
578 last_state = statep;
579}
580
581
2fa6973e
AD
582/*----------------------------------------------------------------.
583| Find which rules can be used for reduction transitions from the |
584| current state and make a reductions structure for the state to |
585| record their rule numbers. |
586`----------------------------------------------------------------*/
587
4a120d45 588static void
2fa6973e 589save_reductions (void)
40675e7c 590{
2fa6973e 591 short *isp;
2fa6973e
AD
592 int item;
593 int count;
594 reductions *p;
40675e7c 595
2fa6973e 596 short *rend;
40675e7c 597
2fa6973e 598 /* Find and count the active items that represent ends of rules. */
40675e7c 599
2fa6973e
AD
600 count = 0;
601 for (isp = itemset; isp < itemsetend; isp++)
602 {
603 item = ritem[*isp];
604 if (item < 0)
605 redset[count++] = -item;
606 }
40675e7c 607
2fa6973e
AD
608 /* Make a reductions structure and copy the data into it. */
609
610 if (count)
611 {
f59c437a 612 p = REDUCTIONS_ALLOC (count);
2fa6973e
AD
613
614 p->number = this_state->number;
615 p->nreds = count;
616
300f275f 617 shortcpy (p->rules, redset, count);
2fa6973e
AD
618
619 if (last_reduction)
620 {
621 last_reduction->next = p;
622 last_reduction = p;
623 }
624 else
625 {
626 first_reduction = p;
627 last_reduction = p;
628 }
629 }
630}
631
632\f
633/*-------------------------------------------------------------------.
634| Compute the nondeterministic finite state machine (see state.h for |
635| details) from the grammar. |
636`-------------------------------------------------------------------*/
637
638void
639generate_states (void)
640{
641 allocate_storage ();
642 new_closure (nitems);
643 new_states ();
644
645 while (this_state)
646 {
647 /* Set up ruleset and itemset for the transitions out of this
648 state. ruleset gets a 1 bit for each rule that could reduce
649 now. itemset gets a vector of all the items that could be
650 accepted next. */
651 closure (this_state->items, this_state->nitems);
652 /* record the reductions allowed out of this state */
653 save_reductions ();
654 /* find the itemsets of the states that shifts can reach */
655 new_itemsets ();
656 /* find or create the core structures for those states */
657 append_states ();
658
659 /* create the shifts structures for the shifts to those states,
660 now that the state numbers transitioning to are known */
661 if (nshifts > 0)
662 save_shifts ();
663
664 /* states are queued when they are created; process them all */
665 this_state = this_state->next;
666 }
667
668 /* discard various storage */
669 free_closure ();
670 free_storage ();
671
672 /* set up initial and final states as parser wants them */
673 augment_automaton ();
40675e7c 674}