]>
git.saurik.com Git - bison.git/blob - src/LR0.c
   1 /* Generate the nondeterministic finite state machine for bison, 
   2    Copyright 1984, 1986, 1989, 2000, 2001  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, Inc., 59 Temple Place - Suite 330, 
  19    Boston, MA 02111-1307, USA.  */ 
  22 /* See comments in state.h for the data structures that represent it. 
  23    The entry point is generate_states.  */ 
  38 static state_t 
*first_state 
= NULL
; 
  40 static state_t 
*this_state 
= NULL
; 
  41 static state_t 
*last_state 
= NULL
; 
  44 static short *shift_symbol 
= NULL
; 
  46 static short *redset 
= NULL
; 
  47 static short *shiftset 
= NULL
; 
  49 static short **kernel_base 
= NULL
; 
  50 static int *kernel_size 
= NULL
; 
  51 static short *kernel_items 
= NULL
; 
  53 /* hash table for states, to recognize equivalent ones.  */ 
  55 #define STATE_HASH_SIZE 1009 
  56 static state_t 
**state_hash 
= NULL
; 
  60 allocate_itemsets (void) 
  64   /* Count the number of occurrences of all the symbols in RITEMS. 
  65      Note that useless productions (hence useless nonterminals) are 
  66      browsed too, hence we need to allocate room for _all_ the 
  69   short *symbol_count 
= XCALLOC (short, nsyms 
+ nuseless_nonterminals
); 
  71   for (i 
= 0; ritem
[i
]; ++i
) 
  75         symbol_count
[ritem
[i
]]++; 
  78   /* See comments before new_itemsets.  All the vectors of items 
  79      live inside KERNEL_ITEMS.  The number of active items after 
  80      some symbol cannot be more than the number of times that symbol 
  81      appears as an item, which is symbol_count[symbol]. 
  82      We allocate that much space for each symbol.  */ 
  84   kernel_base 
= XCALLOC (short *, nsyms
); 
  86     kernel_items 
= XCALLOC (short, count
); 
  89   for (i 
= 0; i 
< nsyms
; i
++) 
  91       kernel_base
[i
] = kernel_items 
+ count
; 
  92       count 
+= symbol_count
[i
]; 
  96   kernel_size 
= XCALLOC (int, nsyms
); 
 101 allocate_storage (void) 
 103   allocate_itemsets (); 
 105   shiftset 
= XCALLOC (short, nsyms
); 
 106   redset 
= XCALLOC (short, nrules 
+ 1); 
 107   state_hash 
= XCALLOC (state_t 
*, STATE_HASH_SIZE
); 
 119   XFREE (kernel_items
); 
 126 /*----------------------------------------------------------------. 
 127 | Find which symbols can be shifted in the current state, and for | 
 128 | each one record which items would be active after that shift.   | 
 129 | Uses the contents of itemset.                                   | 
 131 | shift_symbol is set to a vector of the symbols that can be      | 
 132 | shifted.  For each symbol in the grammar, kernel_base[symbol]   | 
 133 | points to a vector of item numbers activated if that symbol is  | 
 134 | shifted, and kernel_size[symbol] is their numbers.              | 
 135 `----------------------------------------------------------------*/ 
 143     fprintf (stderr
, "Entering new_itemsets, state = %d\n", 
 146   for (i 
= 0; i 
< nsyms
; i
++) 
 149   shift_symbol 
= XCALLOC (short, nsyms
); 
 152   for (i 
= 0; i 
< nitemset
; ++i
) 
 154       int symbol 
= ritem
[itemset
[i
]]; 
 157           if (!kernel_size
[symbol
]) 
 159               shift_symbol
[nshifts
] = symbol
; 
 163           kernel_base
[symbol
][kernel_size
[symbol
]] = itemset
[i
] + 1; 
 164           kernel_size
[symbol
]++; 
 171 /*-----------------------------------------------------------------. 
 172 | Subroutine of get_state.  Create a new state for those items, if | 
 174 `-----------------------------------------------------------------*/ 
 177 new_state (int symbol
) 
 182     fprintf (stderr
, "Entering new_state, state = %d, symbol = %d (%s)\n", 
 183              this_state
->number
, symbol
, tags
[symbol
]); 
 185   if (nstates 
>= MAXSHORT
) 
 186     fatal (_("too many states (max %d)"), MAXSHORT
); 
 188   p 
= STATE_ALLOC (kernel_size
[symbol
]); 
 189   p
->accessing_symbol 
= symbol
; 
 191   p
->nitems 
= kernel_size
[symbol
]; 
 193   shortcpy (p
->items
, kernel_base
[symbol
], kernel_size
[symbol
]); 
 195   last_state
->next 
= p
; 
 203 /*--------------------------------------------------------------. 
 204 | Find the state number for the state we would get to (from the | 
 205 | current state) by shifting symbol.  Create a new state if no  | 
 206 | equivalent one exists already.  Used by append_states.        | 
 207 `--------------------------------------------------------------*/ 
 210 get_state (int symbol
) 
 217     fprintf (stderr
, "Entering get_state, state = %d, symbol = %d (%s)\n", 
 218              this_state
->number
, symbol
, tags
[symbol
]); 
 220   /* Add up the target state's active item numbers to get a hash key. 
 223   for (i 
= 0; i 
< kernel_size
[symbol
]; ++i
) 
 224     key 
+= kernel_base
[symbol
][i
]; 
 225   key 
= key 
% STATE_HASH_SIZE
; 
 226   sp 
= state_hash
[key
]; 
 233           if (sp
->nitems 
== kernel_size
[symbol
]) 
 236               for (i 
= 0; i 
< kernel_size
[symbol
]; ++i
) 
 237                 if (kernel_base
[symbol
][i
] != sp
->items
[i
]) 
 247               else              /* bucket exhausted and no match */ 
 249                   sp 
= sp
->link 
= new_state (symbol
); 
 255   else                          /* bucket is empty */ 
 257       state_hash
[key
] = sp 
= new_state (symbol
); 
 261     fprintf (stderr
, "Exiting get_state => %d\n", sp
->number
); 
 266 /*------------------------------------------------------------------. 
 267 | Use the information computed by new_itemsets to find the state    | 
 268 | numbers reached by each shift transition from the current state.  | 
 270 | shiftset is set up as a vector of state numbers of those states.  | 
 271 `------------------------------------------------------------------*/ 
 281     fprintf (stderr
, "Entering append_states, state = %d\n", 
 284   /* first sort shift_symbol into increasing order */ 
 286   for (i 
= 1; i 
< nshifts
; i
++) 
 288       symbol 
= shift_symbol
[i
]; 
 290       while (j 
> 0 && shift_symbol
[j 
- 1] > symbol
) 
 292           shift_symbol
[j
] = shift_symbol
[j 
- 1]; 
 295       shift_symbol
[j
] = symbol
; 
 298   for (i 
= 0; i 
< nshifts
; i
++) 
 299     shiftset
[i
] = get_state (shift_symbol
[i
]); 
 306   first_state 
= last_state 
= this_state 
= STATE_ALLOC (0); 
 311 /*------------------------------------------------------------. 
 312 | Save the NSHIFTS of SHIFTSET into the current linked list.  | 
 313 `------------------------------------------------------------*/ 
 318   shifts 
*p 
= shifts_new (nshifts
); 
 319   shortcpy (p
->shifts
, shiftset
, nshifts
); 
 320   this_state
->shifts 
= p
; 
 324 /*------------------------------------------------------------------. 
 325 | Subroutine of augment_automaton.  Create the next-to-final state, | 
 326 | to which a shift has already been made in the initial state.      | 
 328 | The task of this state consists in shifting (actually, it's a     | 
 329 | goto, but shifts and gotos are both stored in SHIFTS) the start   | 
 330 | symbols, hence the name.                                          | 
 331 `------------------------------------------------------------------*/ 
 334 insert_start_shifting_state (void) 
 339   statep 
= STATE_ALLOC (0); 
 340   statep
->number 
= nstates
++; 
 342   /* The distinctive feature of this state from the 
 343      eof_shifting_state, is that it is labeled as post-start-symbol 
 344      shifting.  I fail to understand why this state, and the 
 345      post-start-start can't be merged into one.  But it does fail if 
 347   statep
->accessing_symbol 
= start_symbol
; 
 349   last_state
->next 
= statep
; 
 352   /* Make a shift from this state to (what will be) the final state.  */ 
 355   sp
->shifts
[0] = nstates
; 
 359 /*-----------------------------------------------------------------. 
 360 | Subroutine of augment_automaton.  Create the final state, which  | 
 361 | shifts `0', the end of file.  The initial state shifts the start | 
 362 | symbol, and goes to here.                                        | 
 363 `-----------------------------------------------------------------*/ 
 366 insert_eof_shifting_state (void) 
 371   /* Make the final state--the one that follows a shift from the 
 373      The symbol for that shift is 0 (end-of-file).  */ 
 374   statep 
= STATE_ALLOC (0); 
 375   statep
->number 
= nstates
++; 
 377   last_state
->next 
= statep
; 
 380   /* Make the shift from the final state to the termination state.  */ 
 383   sp
->shifts
[0] = nstates
; 
 387 /*---------------------------------------------------------------. 
 388 | Subroutine of augment_automaton.  Create the accepting state.  | 
 389 `---------------------------------------------------------------*/ 
 392 insert_accepting_state (void) 
 396    /* Note that the variable `final_state' refers to what we sometimes 
 397       call the termination state.  */ 
 398   final_state 
= nstates
; 
 400   /* Make the termination state.  */ 
 401   statep 
= STATE_ALLOC (0); 
 402   statep
->number 
= nstates
++; 
 403   last_state
->next 
= statep
; 
 411 /*------------------------------------------------------------------. 
 412 | Make sure that the initial state has a shift that accepts the     | 
 413 | grammar's start symbol and goes to the next-to-final state, which | 
 414 | has a shift going to the final state, which has a shift to the    | 
 415 | termination state.  Create such states and shifts if they don't   | 
 416 | happen to exist already.                                          | 
 417 `------------------------------------------------------------------*/ 
 420 augment_automaton (void) 
 422   if (!first_state
->shifts
->nshifts
) 
 424       /* The first state has no shifts.  Make one shift, from the 
 425          initial state to the next-to-final state.  */ 
 427       shifts 
*sp 
= shifts_new (1); 
 428       first_state
->shifts 
= sp
; 
 429       sp
->shifts
[0] = nstates
; 
 431       /* Create the next-to-final state, with shift to 
 432          what will be the final state.  */ 
 433       insert_start_shifting_state (); 
 437       state_t 
*statep 
= first_state
->next
; 
 438       /* The states reached by shifts from FIRST_STATE are numbered 
 439          1..(SP->NSHIFTS).  Look for one reached by START_SYMBOL. 
 440          This is typical of `start: start ... ;': there is a state 
 441          with the item `start: start . ...'.  We want to add a `shift 
 442          on EOF to eof-shifting state here.  */ 
 443       while (statep
->accessing_symbol 
!= start_symbol
 
 444              && statep
->number 
< first_state
->shifts
->nshifts
) 
 445         statep 
= statep
->next
; 
 447       if (statep
->accessing_symbol 
== start_symbol
) 
 449           /* We already have STATEP, a next-to-final state for `start: 
 450              start . ...'.  Make sure it has a shift to what will be 
 454           /* Find the shift of the inital state that leads to STATEP.  */ 
 455           shifts 
*sp 
= statep
->shifts
; 
 457           shifts 
*sp1 
= shifts_new (sp
->nshifts 
+ 1); 
 458           statep
->shifts 
= sp1
; 
 459           sp1
->shifts
[0] = nstates
; 
 460           for (i 
= sp
->nshifts
; i 
> 0; i
--) 
 461             sp1
->shifts
[i
] = sp
->shifts
[i 
- 1]; 
 465           insert_eof_shifting_state (); 
 469           /* There is no state for `start: start . ...'. */ 
 471           shifts 
*sp 
= first_state
->shifts
; 
 474           /* Add one more shift to the initial state, going to the 
 475              next-to-final state (yet to be made).  */ 
 476           sp1 
= shifts_new (sp
->nshifts 
+ 1); 
 477           first_state
->shifts 
= sp1
; 
 478           /* Stick this shift into the vector at the proper place.  */ 
 479           statep 
= first_state
->next
; 
 480           for (k 
= 0, i 
= 0; i 
< sp
->nshifts
; k
++, i
++) 
 482               if (statep
->accessing_symbol 
> start_symbol 
&& i 
== k
) 
 483                 sp1
->shifts
[k
++] = nstates
; 
 484               sp1
->shifts
[k
] = sp
->shifts
[i
]; 
 485               statep 
= statep
->next
; 
 488             sp1
->shifts
[k
++] = nstates
; 
 492           /* Create the next-to-final state, with shift to what will 
 493              be the final state.  Corresponds to `start: start . ...'.  */ 
 494           insert_start_shifting_state (); 
 498   insert_accepting_state (); 
 502 /*----------------------------------------------------------------. 
 503 | Find which rules can be used for reduction transitions from the | 
 504 | current state and make a reductions structure for the state to  | 
 505 | record their rule numbers.                                      | 
 506 `----------------------------------------------------------------*/ 
 509 save_reductions (void) 
 514   /* Find and count the active items that represent ends of rules. */ 
 517   for (i 
= 0; i 
< nitemset
; ++i
) 
 519       int item 
= ritem
[itemset
[i
]]; 
 521         redset
[count
++] = -item
; 
 524   /* Make a reductions structure and copy the data into it.  */ 
 528       reductions 
*p 
= REDUCTIONS_ALLOC (count
); 
 530       shortcpy (p
->rules
, redset
, count
); 
 532       this_state
->reductions 
= p
; 
 537 /*--------------------. 
 538 | Build STATE_TABLE.  | 
 539 `--------------------*/ 
 542 set_state_table (void) 
 544   /* NSTATES + 1 because lookahead for the pseudo state number NSTATES 
 545      might be used (see conflicts.c).  It is too opaque for me to 
 546      provide a probably less hacky implementation. --akim */ 
 547   state_table 
= XCALLOC (state_t 
*, nstates 
+ 1); 
 551     for (sp 
= first_state
; sp
; sp 
= sp
->next
) 
 552       state_table
[sp
->number
] = sp
; 
 555   /* Pessimization, but simplification of the code: make sure all the 
 556      states have a shifts, even if reduced to 0 shifts.  */ 
 559     for (i 
= 0; i 
< nstates
; i
++) 
 560       if (!state_table
[i
]->shifts
) 
 561         state_table
[i
]->shifts 
= shifts_new (0); 
 565 /*-------------------------------------------------------------------. 
 566 | Compute the nondeterministic finite state machine (see state.h for | 
 567 | details) from the grammar.                                         | 
 568 `-------------------------------------------------------------------*/ 
 571 generate_states (void) 
 574   new_closure (nitems
); 
 580         fprintf (stderr
, "Processing state %d (reached by %s)\n", 
 581                  this_state
->number
, tags
[this_state
->accessing_symbol
]); 
 582       /* Set up ruleset and itemset for the transitions out of this 
 583          state.  ruleset gets a 1 bit for each rule that could reduce 
 584          now.  itemset gets a vector of all the items that could be 
 586       closure (this_state
->items
, this_state
->nitems
); 
 587       /* record the reductions allowed out of this state */ 
 589       /* find the itemsets of the states that shifts can reach */ 
 591       /* find or create the core structures for those states */ 
 594       /* create the shifts structures for the shifts to those states, 
 595          now that the state numbers transitioning to are known */ 
 598       /* states are queued when they are created; process them all */ 
 599       this_state 
= this_state
->next
; 
 602   /* discard various storage */ 
 606   /* set up initial and final states as parser wants them */ 
 607   augment_automaton (); 
 609   /* Set up STATE_TABLE. */