1 /* Type definitions for the finite state machine for Bison. 2 3 Copyright (C) 2001-2007, 2009-2012 Free Software Foundation, Inc. 4 5 This file is part of Bison, the GNU Compiler Compiler. 6 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. 11 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. 16 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/>. */ 19 20 #include <config.h> 21 #include "system.h" 22 23 #include <hash.h> 24 25 #include "complain.h" 26 #include "gram.h" 27 #include "state.h" 28 #include "print-xml.h" 29 30 31 /*-------------------. 32 | Shifts and Gotos. | 33 `-------------------*/ 34 35 36 /*-----------------------------------------. 37 | Create a new array of NUM shifts/gotos. | 38 `-----------------------------------------*/ 39 40 static transitions * 41 transitions_new (int num, state **the_states) 42 { 43 size_t states_size = num * sizeof *the_states; 44 transitions *res = xmalloc (offsetof (transitions, states) + states_size); 45 res->num = num; 46 memcpy (res->states, the_states, states_size); 47 return res; 48 } 49 50 51 /*-------------------------------------------------------. 52 | Return the state such that SHIFTS contain a shift/goto | 53 | to it on SYM. Abort if none found. | 54 `-------------------------------------------------------*/ 55 56 state * 57 transitions_to (transitions *shifts, symbol_number sym) 58 { 59 int j; 60 for (j = 0; ; j++) 61 { 62 aver (j < shifts->num); 63 if (TRANSITION_SYMBOL (shifts, j) == sym) 64 return shifts->states[j]; 65 } 66 } 67 68 69 /*--------------------. 70 | Error transitions. | 71 `--------------------*/ 72 73 74 /*---------------------------------. 75 | Create a new array of NUM errs. | 76 `---------------------------------*/ 77 78 errs * 79 errs_new (int num, symbol **tokens) 80 { 81 size_t symbols_size = num * sizeof *tokens; 82 errs *res = xmalloc (offsetof (errs, symbols) + symbols_size); 83 res->num = num; 84 memcpy (res->symbols, tokens, symbols_size); 85 return res; 86 } 87 88 89 90 91 /*-------------. 92 | Reductions. | 93 `-------------*/ 94 95 96 /*---------------------------------------. 97 | Create a new array of NUM reductions. | 98 `---------------------------------------*/ 99 100 static reductions * 101 reductions_new (int num, rule **reds) 102 { 103 size_t rules_size = num * sizeof *reds; 104 reductions *res = xmalloc (offsetof (reductions, rules) + rules_size); 105 res->num = num; 106 res->lookahead_tokens = NULL; 107 memcpy (res->rules, reds, rules_size); 108 return res; 109 } 110 111 112 113 /*---------. 114 | States. | 115 `---------*/ 116 117 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; 122 123 124 /*------------------------------------------------------------------. 125 | Create a new state with ACCESSING_SYMBOL, for those items. Store | 126 | it in the state hash table. | 127 `------------------------------------------------------------------*/ 128 129 state * 130 state_new (symbol_number accessing_symbol, 131 size_t nitems, item_number *core) 132 { 133 state *res; 134 size_t items_size = nitems * sizeof *core; 135 136 aver (nstates < STATE_NUMBER_MAXIMUM); 137 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; 143 res->errs = NULL; 144 res->state_list = NULL; 145 res->consistent = 0; 146 res->solved_conflicts = NULL; 147 res->solved_conflicts_xml = NULL; 148 149 res->nitems = nitems; 150 memcpy (res->items, core, items_size); 151 152 state_hash_insert (res); 153 154 return res; 155 } 156 157 state * 158 state_new_isocore (state const *s) 159 { 160 state *res; 161 size_t items_size = s->nitems * sizeof *s->items; 162 163 aver (nstates < STATE_NUMBER_MAXIMUM); 164 165 res = xmalloc (offsetof (state, items) + items_size); 166 res->number = nstates++; 167 res->accessing_symbol = s->accessing_symbol; 168 res->transitions = 169 transitions_new (s->transitions->num, s->transitions->states); 170 res->reductions = reductions_new (s->reductions->num, s->reductions->rules); 171 res->errs = NULL; 172 res->state_list = NULL; 173 res->consistent = s->consistent; 174 res->solved_conflicts = NULL; 175 res->solved_conflicts_xml = NULL; 176 177 res->nitems = s->nitems; 178 memcpy (res->items, s->items, items_size); 179 180 return res; 181 } 182 183 184 /*---------. 185 | Free S. | 186 `---------*/ 187 188 static void 189 state_free (state *s) 190 { 191 free (s->transitions); 192 free (s->reductions); 193 free (s->errs); 194 free (s); 195 } 196 197 198 /*---------------------------. 199 | Set the transitions of S. | 200 `---------------------------*/ 201 202 void 203 state_transitions_set (state *s, int num, state **trans) 204 { 205 aver (!s->transitions); 206 s->transitions = transitions_new (num, trans); 207 } 208 209 210 /*--------------------------. 211 | Set the reductions of S. | 212 `--------------------------*/ 213 214 void 215 state_reductions_set (state *s, int num, rule **reds) 216 { 217 aver (!s->reductions); 218 s->reductions = reductions_new (num, reds); 219 } 220 221 222 int 223 state_reduction_find (state *s, rule *r) 224 { 225 int i; 226 reductions *reds = s->reductions; 227 for (i = 0; i < reds->num; ++i) 228 if (reds->rules[i] == r) 229 return i; 230 return -1; 231 } 232 233 234 /*--------------------. 235 | Set the errs of S. | 236 `--------------------*/ 237 238 void 239 state_errs_set (state *s, int num, symbol **tokens) 240 { 241 aver (!s->errs); 242 s->errs = errs_new (num, tokens); 243 } 244 245 246 247 /*--------------------------------------------------. 248 | Print on OUT all the lookahead tokens such that S | 249 | wants to reduce R. | 250 `--------------------------------------------------*/ 251 252 void 253 state_rule_lookahead_tokens_print (state *s, rule *r, FILE *out) 254 { 255 /* Find the reduction we are handling. */ 256 reductions *reds = s->reductions; 257 int red = state_reduction_find (s, r); 258 259 /* Print them if there are. */ 260 if (reds->lookahead_tokens && red != -1) 261 { 262 bitset_iterator biter; 263 int k; 264 char const *sep = ""; 265 fprintf (out, " ["); 266 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0) 267 { 268 fprintf (out, "%s%s", sep, symbols[k]->tag); 269 sep = ", "; 270 } 271 fprintf (out, "]"); 272 } 273 } 274 275 void 276 state_rule_lookahead_tokens_print_xml (state *s, rule *r, 277 FILE *out, int level) 278 { 279 /* Find the reduction we are handling. */ 280 reductions *reds = s->reductions; 281 int red = state_reduction_find (s, r); 282 283 /* Print them if there are. */ 284 if (reds->lookahead_tokens && red != -1) 285 { 286 bitset_iterator biter; 287 int k; 288 xml_puts (out, level, "<lookaheads>"); 289 BITSET_FOR_EACH (biter, reds->lookahead_tokens[red], k, 0) 290 { 291 xml_printf (out, level + 1, "<symbol>%s</symbol>", 292 xml_escape (symbols[k]->tag)); 293 } 294 xml_puts (out, level, "</lookaheads>"); 295 } 296 } 297 298 299 /*---------------------. 300 | A state hash table. | 301 `---------------------*/ 302 303 /* Initial capacity of states hash table. */ 304 #define HT_INITIAL_CAPACITY 257 305 306 static struct hash_table *state_table = NULL; 307 308 /* Two states are equal if they have the same core items. */ 309 static inline bool 310 state_compare (state const *s1, state const *s2) 311 { 312 size_t i; 313 314 if (s1->nitems != s2->nitems) 315 return false; 316 317 for (i = 0; i < s1->nitems; ++i) 318 if (s1->items[i] != s2->items[i]) 319 return false; 320 321 return true; 322 } 323 324 static bool 325 state_comparator (void const *s1, void const *s2) 326 { 327 return state_compare (s1, s2); 328 } 329 330 static inline size_t 331 state_hash (state const *s, size_t tablesize) 332 { 333 /* Add up the state's item numbers to get a hash key. */ 334 size_t key = 0; 335 size_t i; 336 for (i = 0; i < s->nitems; ++i) 337 key += s->items[i]; 338 return key % tablesize; 339 } 340 341 static size_t 342 state_hasher (void const *s, size_t tablesize) 343 { 344 return state_hash (s, tablesize); 345 } 346 347 348 /*-------------------------------. 349 | Create the states hash table. | 350 `-------------------------------*/ 351 352 void 353 state_hash_new (void) 354 { 355 state_table = hash_initialize (HT_INITIAL_CAPACITY, 356 NULL, 357 state_hasher, 358 state_comparator, 359 NULL); 360 } 361 362 363 /*---------------------------------------------. 364 | Free the states hash table, not the states. | 365 `---------------------------------------------*/ 366 367 void 368 state_hash_free (void) 369 { 370 hash_free (state_table); 371 } 372 373 374 /*-----------------------------------. 375 | Insert S in the state hash table. | 376 `-----------------------------------*/ 377 378 void 379 state_hash_insert (state *s) 380 { 381 if (!hash_insert (state_table, s)) 382 xalloc_die (); 383 } 384 385 386 /*------------------------------------------------------------------. 387 | Find the state associated to the CORE, and return it. If it does | 388 | not exist yet, return NULL. | 389 `------------------------------------------------------------------*/ 390 391 state * 392 state_hash_lookup (size_t nitems, item_number *core) 393 { 394 size_t items_size = nitems * sizeof *core; 395 state *probe = xmalloc (offsetof (state, items) + items_size); 396 state *entry; 397 398 probe->nitems = nitems; 399 memcpy (probe->items, core, items_size); 400 entry = hash_lookup (state_table, probe); 401 free (probe); 402 return entry; 403 } 404 405 406 /*--------------------------------------------------------. 407 | Record S and all states reachable from S in REACHABLE. | 408 `--------------------------------------------------------*/ 409 410 static void 411 state_record_reachable_states (state *s, bitset reachable) 412 { 413 if (bitset_test (reachable, s->number)) 414 return; 415 bitset_set (reachable, s->number); 416 { 417 int i; 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); 421 } 422 } 423 424 void 425 state_remove_unreachable_states (state_number old_to_new[]) 426 { 427 state_number nstates_reachable = 0; 428 bitset reachable = bitset_create (nstates, BITSET_FIXED); 429 state_record_reachable_states (states[0], reachable); 430 { 431 state_number i; 432 for (i = 0; i < nstates; ++i) 433 { 434 if (bitset_test (reachable, states[i]->number)) 435 { 436 states[nstates_reachable] = states[i]; 437 states[nstates_reachable]->number = nstates_reachable; 438 old_to_new[i] = nstates_reachable++; 439 } 440 else 441 { 442 state_free (states[i]); 443 old_to_new[i] = nstates; 444 } 445 } 446 } 447 nstates = nstates_reachable; 448 bitset_free (reachable); 449 } 450 451 /* All the decorated states, indexed by the state number. */ 452 state **states = NULL; 453 454 455 /*----------------------. 456 | Free all the states. | 457 `----------------------*/ 458 459 void 460 states_free (void) 461 { 462 state_number i; 463 for (i = 0; i < nstates; ++i) 464 state_free (states[i]); 465 free (states); 466 } 467