]>
git.saurik.com Git - bison.git/blob - src/LR0.c
1 /* Generate the nondeterministic finite state machine for bison,
2 Copyright (C) 1984, 1986, 1989 Free Software Foundation, Inc.
4 This file is part of Bison, the GNU Compiler Compiler.
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)
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.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* See comments in state.h for the data structures that represent it.
22 The entry point is generate_states. */
32 extern char *nullable
;
33 extern short *itemset
;
34 extern short *itemsetend
;
41 reductions
*first_reduction
;
43 int get_state
PARAMS((int));
44 core
*new_state
PARAMS((int));
46 void allocate_itemsets
PARAMS((void));
47 void allocate_storage
PARAMS((void));
48 void free_storage
PARAMS((void));
49 void generate_states
PARAMS((void));
50 void new_itemsets
PARAMS((void));
51 void append_states
PARAMS((void));
52 void initialize_states
PARAMS((void));
53 void save_shifts
PARAMS((void));
54 void save_reductions
PARAMS((void));
55 void augment_automaton
PARAMS((void));
56 void insert_start_shift
PARAMS((void));
57 extern void initialize_closure
PARAMS((int));
58 extern void closure
PARAMS((short *, int));
59 extern void finalize_closure
PARAMS((void));
60 extern void toomany
PARAMS((char *));
62 static core
*this_state
;
63 static core
*last_state
;
64 static shifts
*last_shift
;
65 static reductions
*last_reduction
;
68 static short *shift_symbol
;
71 static short *shiftset
;
73 static short **kernel_base
;
74 static short **kernel_end
;
75 static short *kernel_items
;
77 /* hash table for states, to recognize equivalent ones. */
79 #define STATE_TABLE_SIZE 1009
80 static core
**state_table
;
85 allocate_itemsets (void)
87 register short *itemp
;
91 register short *symbol_count
;
94 symbol_count
= NEW2(nsyms
, short);
103 symbol_count
[symbol
]++;
108 /* see comments before new_itemsets. All the vectors of items
109 live inside kernel_items. The number of active items after
110 some symbol cannot be more than the number of times that symbol
111 appears as an item, which is symbol_count[symbol].
112 We allocate that much space for each symbol. */
114 kernel_base
= NEW2(nsyms
, short *);
115 kernel_items
= NEW2(count
, short);
118 for (i
= 0; i
< nsyms
; i
++)
120 kernel_base
[i
] = kernel_items
+ count
;
121 count
+= symbol_count
[i
];
124 shift_symbol
= symbol_count
;
125 kernel_end
= NEW2(nsyms
, short *);
130 allocate_storage (void)
134 shiftset
= NEW2(nsyms
, short);
135 redset
= NEW2(nrules
+ 1, short);
136 state_table
= NEW2(STATE_TABLE_SIZE
, core
*);
154 /* compute the nondeterministic finite state machine (see state.h for details)
157 generate_states (void)
160 initialize_closure(nitems
);
165 /* Set up ruleset and itemset for the transitions out of this state.
166 ruleset gets a 1 bit for each rule that could reduce now.
167 itemset gets a vector of all the items that could be accepted next. */
168 closure(this_state
->items
, this_state
->nitems
);
169 /* record the reductions allowed out of this state */
171 /* find the itemsets of the states that shifts can reach */
173 /* find or create the core structures for those states */
176 /* create the shifts structures for the shifts to those states,
177 now that the state numbers transitioning to are known */
181 /* states are queued when they are created; process them all */
182 this_state
= this_state
->next
;
185 /* discard various storage */
189 /* set up initial and final states as parser wants them */
195 /* Find which symbols can be shifted in the current state,
196 and for each one record which items would be active after that shift.
197 Uses the contents of itemset.
198 shift_symbol is set to a vector of the symbols that can be shifted.
199 For each symbol in the grammar, kernel_base[symbol] points to
200 a vector of item numbers activated if that symbol is shifted,
201 and kernel_end[symbol] points after the end of that vector. */
206 register int shiftcount
;
212 fprintf(stderr
, "Entering new_itemsets\n");
215 for (i
= 0; i
< nsyms
; i
++)
216 kernel_end
[i
] = NULL
;
222 while (isp
< itemsetend
)
228 ksp
= kernel_end
[symbol
];
232 shift_symbol
[shiftcount
++] = symbol
;
233 ksp
= kernel_base
[symbol
];
237 kernel_end
[symbol
] = ksp
;
241 nshifts
= shiftcount
;
246 /* Use the information computed by new_itemsets to find the state numbers
247 reached by each shift transition from the current state.
249 shiftset is set up as a vector of state numbers of those states. */
258 fprintf(stderr
, "Entering append_states\n");
261 /* first sort shift_symbol into increasing order */
263 for (i
= 1; i
< nshifts
; i
++)
265 symbol
= shift_symbol
[i
];
267 while (j
> 0 && shift_symbol
[j
- 1] > symbol
)
269 shift_symbol
[j
] = shift_symbol
[j
- 1];
272 shift_symbol
[j
] = symbol
;
275 for (i
= 0; i
< nshifts
; i
++)
277 symbol
= shift_symbol
[i
];
278 shiftset
[i
] = get_state(symbol
);
284 /* find the state number for the state we would get to
285 (from the current state) by shifting symbol.
286 Create a new state if no equivalent one exists already.
287 Used by append_states */
290 get_state (int symbol
)
293 register short *isp1
;
294 register short *isp2
;
295 register short *iend
;
302 fprintf(stderr
, "Entering get_state, symbol = %d\n", symbol
);
305 isp1
= kernel_base
[symbol
];
306 iend
= kernel_end
[symbol
];
309 /* add up the target state's active item numbers to get a hash key */
314 key
= key
% STATE_TABLE_SIZE
;
316 sp
= state_table
[key
];
326 isp1
= kernel_base
[symbol
];
329 while (found
&& isp1
< iend
)
331 if (*isp1
++ != *isp2
++)
342 else /* bucket exhausted and no match */
344 sp
= sp
->link
= new_state(symbol
);
350 else /* bucket is empty */
352 state_table
[key
] = sp
= new_state(symbol
);
360 /* subroutine of get_state. create a new state for those items, if necessary. */
363 new_state (int symbol
)
367 register short *isp1
;
368 register short *isp2
;
369 register short *iend
;
372 fprintf(stderr
, "Entering new_state, symbol = %d\n", symbol
);
375 if (nstates
>= MAXSHORT
)
378 isp1
= kernel_base
[symbol
];
379 iend
= kernel_end
[symbol
];
382 p
= (core
*) xmalloc((unsigned) (sizeof(core
) + (n
- 1) * sizeof(short)));
383 p
->accessing_symbol
= symbol
;
391 last_state
->next
= p
;
401 initialize_states (void)
404 /* register unsigned *rp1; JF unused */
405 /* register unsigned *rp2; JF unused */
406 /* register unsigned *rend; JF unused */
408 p
= (core
*) xmalloc((unsigned) (sizeof(core
) - sizeof(short)));
409 first_state
= last_state
= this_state
= p
;
420 register short *send
;
422 p
= (shifts
*) xmalloc((unsigned) (sizeof(shifts
) +
423 (nshifts
- 1) * sizeof(short)));
425 p
->number
= this_state
->number
;
426 p
->nshifts
= nshifts
;
430 send
= shiftset
+ nshifts
;
437 last_shift
->next
= p
;
449 /* find which rules can be used for reduction transitions from the current state
450 and make a reductions structure for the state to record their rule numbers. */
452 save_reductions (void)
459 register reductions
*p
;
463 /* find and count the active items that represent ends of rules */
466 for (isp
= itemset
; isp
< itemsetend
; isp
++)
471 redset
[count
++] = -item
;
475 /* make a reductions structure and copy the data into it. */
479 p
= (reductions
*) xmalloc((unsigned) (sizeof(reductions
) +
480 (count
- 1) * sizeof(short)));
482 p
->number
= this_state
->number
;
494 last_reduction
->next
= p
;
507 /* Make sure that the initial state has a shift that accepts the
508 grammar's start symbol and goes to the next-to-final state,
509 which has a shift going to the final state, which has a shift
510 to the termination state.
511 Create such states and shifts if they don't happen to exist already. */
513 augment_automaton (void)
517 /* register int found; JF unused */
518 register core
*statep
;
520 register shifts
*sp2
;
521 register shifts
*sp1
;
530 statep
= first_state
->next
;
532 /* The states reached by shifts from first_state are numbered 1...K.
533 Look for one reached by start_symbol. */
534 while (statep
->accessing_symbol
< start_symbol
535 && statep
->number
< k
)
536 statep
= statep
->next
;
538 if (statep
->accessing_symbol
== start_symbol
)
540 /* We already have a next-to-final state.
541 Make sure it has a shift to what will be the final state. */
544 while (sp
&& sp
->number
< k
)
550 if (sp
&& sp
->number
== k
)
552 sp2
= (shifts
*) xmalloc((unsigned) (sizeof(shifts
)
553 + sp
->nshifts
* sizeof(short)));
555 sp2
->nshifts
= sp
->nshifts
+ 1;
556 sp2
->shifts
[0] = nstates
;
557 for (i
= sp
->nshifts
; i
> 0; i
--)
558 sp2
->shifts
[i
] = sp
->shifts
[i
- 1];
560 /* Patch sp2 into the chain of shifts in place of sp,
562 sp2
->next
= sp
->next
;
564 if (sp
== last_shift
)
573 sp2
->shifts
[0] = nstates
;
575 /* Patch sp2 into the chain of shifts between sp1 and sp. */
584 /* There is no next-to-final state as yet. */
585 /* Add one more shift in first_shift,
586 going to the next-to-final state (yet to be made). */
589 sp2
= (shifts
*) xmalloc(sizeof(shifts
)
590 + sp
->nshifts
* sizeof(short));
591 sp2
->nshifts
= sp
->nshifts
+ 1;
593 /* Stick this shift into the vector at the proper place. */
594 statep
= first_state
->next
;
595 for (k
= 0, i
= 0; i
< sp
->nshifts
; k
++, i
++)
597 if (statep
->accessing_symbol
> start_symbol
&& i
== k
)
598 sp2
->shifts
[k
++] = nstates
;
599 sp2
->shifts
[k
] = sp
->shifts
[i
];
600 statep
= statep
->next
;
603 sp2
->shifts
[k
++] = nstates
;
605 /* Patch sp2 into the chain of shifts
606 in place of sp, at the beginning. */
607 sp2
->next
= sp
->next
;
609 if (last_shift
== sp
)
614 /* Create the next-to-final state, with shift to
615 what will be the final state. */
616 insert_start_shift();
621 /* The initial state didn't even have any shifts.
622 Give it one shift, to the next-to-final state. */
625 sp
->shifts
[0] = nstates
;
627 /* Patch sp into the chain of shifts at the beginning. */
628 sp
->next
= first_shift
;
631 /* Create the next-to-final state, with shift to
632 what will be the final state. */
633 insert_start_shift();
638 /* There are no shifts for any state.
639 Make one shift, from the initial state to the next-to-final state. */
643 sp
->shifts
[0] = nstates
;
645 /* Initialize the chain of shifts with sp. */
649 /* Create the next-to-final state, with shift to
650 what will be the final state. */
651 insert_start_shift();
654 /* Make the final state--the one that follows a shift from the
656 The symbol for that shift is 0 (end-of-file). */
657 statep
= (core
*) xmalloc((unsigned) (sizeof(core
) - sizeof(short)));
658 statep
->number
= nstates
;
659 last_state
->next
= statep
;
662 /* Make the shift from the final state to the termination state. */
664 sp
->number
= nstates
++;
666 sp
->shifts
[0] = nstates
;
667 last_shift
->next
= sp
;
670 /* Note that the variable `final_state' refers to what we sometimes call
671 the termination state. */
672 final_state
= nstates
;
674 /* Make the termination state. */
675 statep
= (core
*) xmalloc((unsigned) (sizeof(core
) - sizeof(short)));
676 statep
->number
= nstates
++;
677 last_state
->next
= statep
;
682 /* subroutine of augment_automaton.
683 Create the next-to-final state, to which a shift has already been made in
684 the initial state. */
686 insert_start_shift (void)
688 register core
*statep
;
691 statep
= (core
*) xmalloc((unsigned) (sizeof(core
) - sizeof(short)));
692 statep
->number
= nstates
;
693 statep
->accessing_symbol
= start_symbol
;
695 last_state
->next
= statep
;
698 /* Make a shift from this state to (what will be) the final state. */
700 sp
->number
= nstates
++;
702 sp
->shifts
[0] = nstates
;
704 last_shift
->next
= sp
;