1 /* Type definitions for the finite state machine for Bison. 
   3    Copyright (C) 2001-2007, 2009-2013 Free Software Foundation, Inc. 
   5    This file is part of Bison, the GNU Compiler Compiler. 
   7    This program is free software: you can redistribute it and/or modify 
   8    it under the terms of the GNU General Public License as published by 
   9    the Free Software Foundation, either version 3 of the License, or 
  10    (at your option) any later version. 
  12    This program is distributed in the hope that it will be useful, 
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  15    GNU General Public License for more details. 
  17    You should have received a copy of the GNU General Public License 
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */ 
  28 #include "print-xml.h" 
  31                         /*-------------------. 
  33                         `-------------------*/ 
  36 /*-----------------------------------------. 
  37 | Create a new array of NUM shifts/gotos.  | 
  38 `-----------------------------------------*/ 
  41 transitions_new (int num
, state 
**the_states
) 
  43   size_t states_size 
= num 
* sizeof *the_states
; 
  44   transitions 
*res 
= xmalloc (offsetof (transitions
, states
) + states_size
); 
  46   memcpy (res
->states
, the_states
, states_size
); 
  51 /*-------------------------------------------------------. 
  52 | Return the state such that SHIFTS contain a shift/goto | 
  53 | to it on SYM.  Abort if none found.                    | 
  54 `-------------------------------------------------------*/ 
  57 transitions_to (transitions 
*shifts
, symbol_number sym
) 
  62       aver (j 
< shifts
->num
); 
  63       if (TRANSITION_SYMBOL (shifts
, j
) == sym
) 
  64         return shifts
->states
[j
]; 
  69                         /*--------------------. 
  70                         | Error transitions.  | 
  71                         `--------------------*/ 
  74 /*---------------------------------. 
  75 | Create a new array of NUM errs.  | 
  76 `---------------------------------*/ 
  79 errs_new (int num
, symbol 
**tokens
) 
  81   size_t symbols_size 
= num 
* sizeof *tokens
; 
  82   errs 
*res 
= xmalloc (offsetof (errs
, symbols
) + symbols_size
); 
  84   memcpy (res
->symbols
, tokens
, symbols_size
); 
  96 /*---------------------------------------. 
  97 | Create a new array of NUM reductions.  | 
  98 `---------------------------------------*/ 
 101 reductions_new (int num
, rule 
**reds
) 
 103   size_t rules_size 
= num 
* sizeof *reds
; 
 104   reductions 
*res 
= xmalloc (offsetof (reductions
, rules
) + rules_size
); 
 106   res
->lookahead_tokens 
= NULL
; 
 107   memcpy (res
->rules
, reds
, rules_size
); 
 118 state_number nstates 
= 0; 
 119 /* FINAL_STATE is properly set by new_state when it recognizes its 
 120    accessing symbol: $end.  */ 
 121 state 
*final_state 
= NULL
; 
 124 /*------------------------------------------------------------------. 
 125 | Create a new state with ACCESSING_SYMBOL, for those items.  Store | 
 126 | it in the state hash table.                                       | 
 127 `------------------------------------------------------------------*/ 
 130 state_new (symbol_number accessing_symbol
, 
 131            size_t nitems
, item_number 
*core
) 
 134   size_t items_size 
= nitems 
* sizeof *core
; 
 136   aver (nstates 
< STATE_NUMBER_MAXIMUM
); 
 138   res 
= xmalloc (offsetof (state
, items
) + items_size
); 
 139   res
->number 
= nstates
++; 
 140   res
->accessing_symbol 
= accessing_symbol
; 
 141   res
->transitions 
= NULL
; 
 142   res
->reductions 
= NULL
; 
 144   res
->state_list 
= NULL
; 
 146   res
->solved_conflicts 
= NULL
; 
 147   res
->solved_conflicts_xml 
= NULL
; 
 149   res
->nitems 
= nitems
; 
 150   memcpy (res
->items
, core
, items_size
); 
 152   state_hash_insert (res
); 
 158 state_new_isocore (state 
const *s
) 
 161   size_t items_size 
= s
->nitems 
* sizeof *s
->items
; 
 163   aver (nstates 
< STATE_NUMBER_MAXIMUM
); 
 165   res 
= xmalloc (offsetof (state
, items
) + items_size
); 
 166   res
->number 
= nstates
++; 
 167   res
->accessing_symbol 
= s
->accessing_symbol
; 
 169     transitions_new (s
->transitions
->num
, s
->transitions
->states
); 
 170   res
->reductions 
= reductions_new (s
->reductions
->num
, s
->reductions
->rules
); 
 172   res
->state_list 
= NULL
; 
 173   res
->consistent 
= s
->consistent
; 
 174   res
->solved_conflicts 
= NULL
; 
 175   res
->solved_conflicts_xml 
= NULL
; 
 177   res
->nitems 
= s
->nitems
; 
 178   memcpy (res
->items
, s
->items
, items_size
); 
 189 state_free (state 
*s
) 
 191   free (s
->transitions
); 
 192   free (s
->reductions
); 
 198 /*---------------------------. 
 199 | Set the transitions of S.  | 
 200 `---------------------------*/ 
 203 state_transitions_set (state 
*s
, int num
, state 
**trans
) 
 205   aver (!s
->transitions
); 
 206   s
->transitions 
= transitions_new (num
, trans
); 
 210 /*--------------------------. 
 211 | Set the reductions of S.  | 
 212 `--------------------------*/ 
 215 state_reductions_set (state 
*s
, int num
, rule 
**reds
) 
 217   aver (!s
->reductions
); 
 218   s
->reductions 
= reductions_new (num
, reds
); 
 223 state_reduction_find (state 
*s
, rule 
*r
) 
 226   reductions 
*reds 
= s
->reductions
; 
 227   for (i 
= 0; i 
< reds
->num
; ++i
) 
 228     if (reds
->rules
[i
] == r
) 
 234 /*--------------------. 
 235 | Set the errs of S.  | 
 236 `--------------------*/ 
 239 state_errs_set (state 
*s
, int num
, symbol 
**tokens
) 
 242   s
->errs 
= errs_new (num
, tokens
); 
 247 /*--------------------------------------------------. 
 248 | Print on OUT all the lookahead tokens such that S | 
 249 | wants to reduce R.                                | 
 250 `--------------------------------------------------*/ 
 253 state_rule_lookahead_tokens_print (state 
*s
, rule 
*r
, FILE *out
) 
 255   /* Find the reduction we are handling.  */ 
 256   reductions 
*reds 
= s
->reductions
; 
 257   int red 
= state_reduction_find (s
, r
); 
 259   /* Print them if there are.  */ 
 260   if (reds
->lookahead_tokens 
&& red 
!= -1) 
 262       bitset_iterator biter
; 
 264       char const *sep 
= ""; 
 266       BITSET_FOR_EACH (biter
, reds
->lookahead_tokens
[red
], k
, 0) 
 268           fprintf (out
, "%s%s", sep
, symbols
[k
]->tag
); 
 276 state_rule_lookahead_tokens_print_xml (state 
*s
, rule 
*r
, 
 277                                        FILE *out
, int level
) 
 279   /* Find the reduction we are handling.  */ 
 280   reductions 
*reds 
= s
->reductions
; 
 281   int red 
= state_reduction_find (s
, r
); 
 283   /* Print them if there are.  */ 
 284   if (reds
->lookahead_tokens 
&& red 
!= -1) 
 286       bitset_iterator biter
; 
 288       xml_puts (out
, level
, "<lookaheads>"); 
 289       BITSET_FOR_EACH (biter
, reds
->lookahead_tokens
[red
], k
, 0) 
 291           xml_printf (out
, level 
+ 1, "<symbol>%s</symbol>", 
 292                       xml_escape (symbols
[k
]->tag
)); 
 294       xml_puts (out
, level
, "</lookaheads>"); 
 299 /*---------------------. 
 300 | A state hash table.  | 
 301 `---------------------*/ 
 303 /* Initial capacity of states hash table.  */ 
 304 #define HT_INITIAL_CAPACITY 257 
 306 static struct hash_table 
*state_table 
= NULL
; 
 308 /* Two states are equal if they have the same core items.  */ 
 310 state_compare (state 
const *s1
, state 
const *s2
) 
 314   if (s1
->nitems 
!= s2
->nitems
) 
 317   for (i 
= 0; i 
< s1
->nitems
; ++i
) 
 318     if (s1
->items
[i
] != s2
->items
[i
]) 
 325 state_comparator (void const *s1
, void const *s2
) 
 327   return state_compare (s1
, s2
); 
 331 state_hash (state 
const *s
, size_t tablesize
) 
 333   /* Add up the state's item numbers to get a hash key.  */ 
 336   for (i 
= 0; i 
< s
->nitems
; ++i
) 
 338   return key 
% tablesize
; 
 342 state_hasher (void const *s
, size_t tablesize
) 
 344   return state_hash (s
, tablesize
); 
 348 /*-------------------------------. 
 349 | Create the states hash table.  | 
 350 `-------------------------------*/ 
 353 state_hash_new (void) 
 355   state_table 
= hash_initialize (HT_INITIAL_CAPACITY
, 
 363 /*---------------------------------------------. 
 364 | Free the states hash table, not the states.  | 
 365 `---------------------------------------------*/ 
 368 state_hash_free (void) 
 370   hash_free (state_table
); 
 374 /*-----------------------------------. 
 375 | Insert S in the state hash table.  | 
 376 `-----------------------------------*/ 
 379 state_hash_insert (state 
*s
) 
 381   if (!hash_insert (state_table
, s
)) 
 386 /*------------------------------------------------------------------. 
 387 | Find the state associated to the CORE, and return it.  If it does | 
 388 | not exist yet, return NULL.                                       | 
 389 `------------------------------------------------------------------*/ 
 392 state_hash_lookup (size_t nitems
, item_number 
*core
) 
 394   size_t items_size 
= nitems 
* sizeof *core
; 
 395   state 
*probe 
= xmalloc (offsetof (state
, items
) + items_size
); 
 398   probe
->nitems 
= nitems
; 
 399   memcpy (probe
->items
, core
, items_size
); 
 400   entry 
= hash_lookup (state_table
, probe
); 
 406 /*--------------------------------------------------------. 
 407 | Record S and all states reachable from S in REACHABLE.  | 
 408 `--------------------------------------------------------*/ 
 411 state_record_reachable_states (state 
*s
, bitset reachable
) 
 413   if (bitset_test (reachable
, s
->number
)) 
 415   bitset_set (reachable
, s
->number
); 
 418     for (i 
= 0; i 
< s
->transitions
->num
; ++i
) 
 419       if (!TRANSITION_IS_DISABLED (s
->transitions
, i
)) 
 420         state_record_reachable_states (s
->transitions
->states
[i
], reachable
); 
 425 state_remove_unreachable_states (state_number old_to_new
[]) 
 427   state_number nstates_reachable 
= 0; 
 428   bitset reachable 
= bitset_create (nstates
, BITSET_FIXED
); 
 429   state_record_reachable_states (states
[0], reachable
); 
 432     for (i 
= 0; i 
< nstates
; ++i
) 
 434         if (bitset_test (reachable
, states
[i
]->number
)) 
 436             states
[nstates_reachable
] = states
[i
]; 
 437             states
[nstates_reachable
]->number 
= nstates_reachable
; 
 438             old_to_new
[i
] = nstates_reachable
++; 
 442             state_free (states
[i
]); 
 443             old_to_new
[i
] = nstates
; 
 447   nstates 
= nstates_reachable
; 
 448   bitset_free (reachable
); 
 451 /* All the decorated states, indexed by the state number.  */ 
 452 state 
**states 
= NULL
; 
 455 /*----------------------. 
 456 | Free all the states.  | 
 457 `----------------------*/ 
 463   for (i 
= 0; i 
< nstates
; ++i
) 
 464     state_free (states
[i
]);