1*0f86d14eSJung-uk Kim /* $Id: lr0.c,v 1.18 2015/07/11 00:53:38 tom Exp $ */ 298e903e7SBaptiste Daroussin 398e903e7SBaptiste Daroussin #include "defs.h" 498e903e7SBaptiste Daroussin 598e903e7SBaptiste Daroussin static core *new_state(int symbol); 698e903e7SBaptiste Daroussin static Value_t get_state(int symbol); 798e903e7SBaptiste Daroussin static void allocate_itemsets(void); 898e903e7SBaptiste Daroussin static void allocate_storage(void); 998e903e7SBaptiste Daroussin static void append_states(void); 1098e903e7SBaptiste Daroussin static void free_storage(void); 1198e903e7SBaptiste Daroussin static void generate_states(void); 1298e903e7SBaptiste Daroussin static void initialize_states(void); 1398e903e7SBaptiste Daroussin static void new_itemsets(void); 1498e903e7SBaptiste Daroussin static void save_reductions(void); 1598e903e7SBaptiste Daroussin static void save_shifts(void); 1698e903e7SBaptiste Daroussin static void set_derives(void); 1798e903e7SBaptiste Daroussin static void set_nullable(void); 1898e903e7SBaptiste Daroussin 1998e903e7SBaptiste Daroussin int nstates; 2098e903e7SBaptiste Daroussin core *first_state; 2198e903e7SBaptiste Daroussin shifts *first_shift; 2298e903e7SBaptiste Daroussin reductions *first_reduction; 2398e903e7SBaptiste Daroussin 2498e903e7SBaptiste Daroussin static core **state_set; 2598e903e7SBaptiste Daroussin static core *this_state; 2698e903e7SBaptiste Daroussin static core *last_state; 2798e903e7SBaptiste Daroussin static shifts *last_shift; 2898e903e7SBaptiste Daroussin static reductions *last_reduction; 2998e903e7SBaptiste Daroussin 3098e903e7SBaptiste Daroussin static int nshifts; 310c8de5b0SBaptiste Daroussin static Value_t *shift_symbol; 3298e903e7SBaptiste Daroussin 33*0f86d14eSJung-uk Kim static Value_t *rules; 34*0f86d14eSJung-uk Kim 3598e903e7SBaptiste Daroussin static Value_t *redset; 3698e903e7SBaptiste Daroussin static Value_t *shiftset; 3798e903e7SBaptiste Daroussin 3898e903e7SBaptiste Daroussin static Value_t **kernel_base; 3998e903e7SBaptiste Daroussin static Value_t **kernel_end; 4098e903e7SBaptiste Daroussin static Value_t *kernel_items; 4198e903e7SBaptiste Daroussin 4298e903e7SBaptiste Daroussin static void 4398e903e7SBaptiste Daroussin allocate_itemsets(void) 4498e903e7SBaptiste Daroussin { 450c8de5b0SBaptiste Daroussin Value_t *itemp; 460c8de5b0SBaptiste Daroussin Value_t *item_end; 4798e903e7SBaptiste Daroussin int symbol; 4898e903e7SBaptiste Daroussin int i; 4998e903e7SBaptiste Daroussin int count; 5098e903e7SBaptiste Daroussin int max; 510c8de5b0SBaptiste Daroussin Value_t *symbol_count; 5298e903e7SBaptiste Daroussin 5398e903e7SBaptiste Daroussin count = 0; 540c8de5b0SBaptiste Daroussin symbol_count = NEW2(nsyms, Value_t); 5598e903e7SBaptiste Daroussin 5698e903e7SBaptiste Daroussin item_end = ritem + nitems; 5798e903e7SBaptiste Daroussin for (itemp = ritem; itemp < item_end; itemp++) 5898e903e7SBaptiste Daroussin { 5998e903e7SBaptiste Daroussin symbol = *itemp; 6098e903e7SBaptiste Daroussin if (symbol >= 0) 6198e903e7SBaptiste Daroussin { 6298e903e7SBaptiste Daroussin count++; 6398e903e7SBaptiste Daroussin symbol_count[symbol]++; 6498e903e7SBaptiste Daroussin } 6598e903e7SBaptiste Daroussin } 6698e903e7SBaptiste Daroussin 670c8de5b0SBaptiste Daroussin kernel_base = NEW2(nsyms, Value_t *); 680c8de5b0SBaptiste Daroussin kernel_items = NEW2(count, Value_t); 6998e903e7SBaptiste Daroussin 7098e903e7SBaptiste Daroussin count = 0; 7198e903e7SBaptiste Daroussin max = 0; 7298e903e7SBaptiste Daroussin for (i = 0; i < nsyms; i++) 7398e903e7SBaptiste Daroussin { 7498e903e7SBaptiste Daroussin kernel_base[i] = kernel_items + count; 7598e903e7SBaptiste Daroussin count += symbol_count[i]; 7698e903e7SBaptiste Daroussin if (max < symbol_count[i]) 7798e903e7SBaptiste Daroussin max = symbol_count[i]; 7898e903e7SBaptiste Daroussin } 7998e903e7SBaptiste Daroussin 8098e903e7SBaptiste Daroussin shift_symbol = symbol_count; 810c8de5b0SBaptiste Daroussin kernel_end = NEW2(nsyms, Value_t *); 8298e903e7SBaptiste Daroussin } 8398e903e7SBaptiste Daroussin 8498e903e7SBaptiste Daroussin static void 8598e903e7SBaptiste Daroussin allocate_storage(void) 8698e903e7SBaptiste Daroussin { 8798e903e7SBaptiste Daroussin allocate_itemsets(); 880c8de5b0SBaptiste Daroussin shiftset = NEW2(nsyms, Value_t); 890c8de5b0SBaptiste Daroussin redset = NEW2(nrules + 1, Value_t); 9098e903e7SBaptiste Daroussin state_set = NEW2(nitems, core *); 9198e903e7SBaptiste Daroussin } 9298e903e7SBaptiste Daroussin 9398e903e7SBaptiste Daroussin static void 9498e903e7SBaptiste Daroussin append_states(void) 9598e903e7SBaptiste Daroussin { 9698e903e7SBaptiste Daroussin int i; 9798e903e7SBaptiste Daroussin int j; 9898e903e7SBaptiste Daroussin Value_t symbol; 9998e903e7SBaptiste Daroussin 10098e903e7SBaptiste Daroussin #ifdef TRACE 10198e903e7SBaptiste Daroussin fprintf(stderr, "Entering append_states()\n"); 10298e903e7SBaptiste Daroussin #endif 10398e903e7SBaptiste Daroussin for (i = 1; i < nshifts; i++) 10498e903e7SBaptiste Daroussin { 10598e903e7SBaptiste Daroussin symbol = shift_symbol[i]; 10698e903e7SBaptiste Daroussin j = i; 10798e903e7SBaptiste Daroussin while (j > 0 && shift_symbol[j - 1] > symbol) 10898e903e7SBaptiste Daroussin { 10998e903e7SBaptiste Daroussin shift_symbol[j] = shift_symbol[j - 1]; 11098e903e7SBaptiste Daroussin j--; 11198e903e7SBaptiste Daroussin } 11298e903e7SBaptiste Daroussin shift_symbol[j] = symbol; 11398e903e7SBaptiste Daroussin } 11498e903e7SBaptiste Daroussin 11598e903e7SBaptiste Daroussin for (i = 0; i < nshifts; i++) 11698e903e7SBaptiste Daroussin { 11798e903e7SBaptiste Daroussin symbol = shift_symbol[i]; 11898e903e7SBaptiste Daroussin shiftset[i] = get_state(symbol); 11998e903e7SBaptiste Daroussin } 12098e903e7SBaptiste Daroussin } 12198e903e7SBaptiste Daroussin 12298e903e7SBaptiste Daroussin static void 12398e903e7SBaptiste Daroussin free_storage(void) 12498e903e7SBaptiste Daroussin { 12598e903e7SBaptiste Daroussin FREE(shift_symbol); 12698e903e7SBaptiste Daroussin FREE(redset); 12798e903e7SBaptiste Daroussin FREE(shiftset); 12898e903e7SBaptiste Daroussin FREE(kernel_base); 12998e903e7SBaptiste Daroussin FREE(kernel_end); 13098e903e7SBaptiste Daroussin FREE(kernel_items); 13198e903e7SBaptiste Daroussin FREE(state_set); 13298e903e7SBaptiste Daroussin } 13398e903e7SBaptiste Daroussin 13498e903e7SBaptiste Daroussin static void 13598e903e7SBaptiste Daroussin generate_states(void) 13698e903e7SBaptiste Daroussin { 13798e903e7SBaptiste Daroussin allocate_storage(); 1380c8de5b0SBaptiste Daroussin itemset = NEW2(nitems, Value_t); 13998e903e7SBaptiste Daroussin ruleset = NEW2(WORDSIZE(nrules), unsigned); 14098e903e7SBaptiste Daroussin set_first_derives(); 14198e903e7SBaptiste Daroussin initialize_states(); 14298e903e7SBaptiste Daroussin 14398e903e7SBaptiste Daroussin while (this_state) 14498e903e7SBaptiste Daroussin { 14598e903e7SBaptiste Daroussin closure(this_state->items, this_state->nitems); 14698e903e7SBaptiste Daroussin save_reductions(); 14798e903e7SBaptiste Daroussin new_itemsets(); 14898e903e7SBaptiste Daroussin append_states(); 14998e903e7SBaptiste Daroussin 15098e903e7SBaptiste Daroussin if (nshifts > 0) 15198e903e7SBaptiste Daroussin save_shifts(); 15298e903e7SBaptiste Daroussin 15398e903e7SBaptiste Daroussin this_state = this_state->next; 15498e903e7SBaptiste Daroussin } 15598e903e7SBaptiste Daroussin 15698e903e7SBaptiste Daroussin free_storage(); 15798e903e7SBaptiste Daroussin } 15898e903e7SBaptiste Daroussin 15998e903e7SBaptiste Daroussin static Value_t 16098e903e7SBaptiste Daroussin get_state(int symbol) 16198e903e7SBaptiste Daroussin { 16298e903e7SBaptiste Daroussin int key; 1630c8de5b0SBaptiste Daroussin Value_t *isp1; 1640c8de5b0SBaptiste Daroussin Value_t *isp2; 1650c8de5b0SBaptiste Daroussin Value_t *iend; 16698e903e7SBaptiste Daroussin core *sp; 16798e903e7SBaptiste Daroussin int found; 16898e903e7SBaptiste Daroussin int n; 16998e903e7SBaptiste Daroussin 17098e903e7SBaptiste Daroussin #ifdef TRACE 17198e903e7SBaptiste Daroussin fprintf(stderr, "Entering get_state(%d)\n", symbol); 17298e903e7SBaptiste Daroussin #endif 17398e903e7SBaptiste Daroussin 17498e903e7SBaptiste Daroussin isp1 = kernel_base[symbol]; 17598e903e7SBaptiste Daroussin iend = kernel_end[symbol]; 17698e903e7SBaptiste Daroussin n = (int)(iend - isp1); 17798e903e7SBaptiste Daroussin 17898e903e7SBaptiste Daroussin key = *isp1; 17998e903e7SBaptiste Daroussin assert(0 <= key && key < nitems); 18098e903e7SBaptiste Daroussin sp = state_set[key]; 18198e903e7SBaptiste Daroussin if (sp) 18298e903e7SBaptiste Daroussin { 18398e903e7SBaptiste Daroussin found = 0; 18498e903e7SBaptiste Daroussin while (!found) 18598e903e7SBaptiste Daroussin { 18698e903e7SBaptiste Daroussin if (sp->nitems == n) 18798e903e7SBaptiste Daroussin { 18898e903e7SBaptiste Daroussin found = 1; 18998e903e7SBaptiste Daroussin isp1 = kernel_base[symbol]; 19098e903e7SBaptiste Daroussin isp2 = sp->items; 19198e903e7SBaptiste Daroussin 19298e903e7SBaptiste Daroussin while (found && isp1 < iend) 19398e903e7SBaptiste Daroussin { 19498e903e7SBaptiste Daroussin if (*isp1++ != *isp2++) 19598e903e7SBaptiste Daroussin found = 0; 19698e903e7SBaptiste Daroussin } 19798e903e7SBaptiste Daroussin } 19898e903e7SBaptiste Daroussin 19998e903e7SBaptiste Daroussin if (!found) 20098e903e7SBaptiste Daroussin { 20198e903e7SBaptiste Daroussin if (sp->link) 20298e903e7SBaptiste Daroussin { 20398e903e7SBaptiste Daroussin sp = sp->link; 20498e903e7SBaptiste Daroussin } 20598e903e7SBaptiste Daroussin else 20698e903e7SBaptiste Daroussin { 20798e903e7SBaptiste Daroussin sp = sp->link = new_state(symbol); 20898e903e7SBaptiste Daroussin found = 1; 20998e903e7SBaptiste Daroussin } 21098e903e7SBaptiste Daroussin } 21198e903e7SBaptiste Daroussin } 21298e903e7SBaptiste Daroussin } 21398e903e7SBaptiste Daroussin else 21498e903e7SBaptiste Daroussin { 21598e903e7SBaptiste Daroussin state_set[key] = sp = new_state(symbol); 21698e903e7SBaptiste Daroussin } 21798e903e7SBaptiste Daroussin 21898e903e7SBaptiste Daroussin return (sp->number); 21998e903e7SBaptiste Daroussin } 22098e903e7SBaptiste Daroussin 22198e903e7SBaptiste Daroussin static void 22298e903e7SBaptiste Daroussin initialize_states(void) 22398e903e7SBaptiste Daroussin { 22498e903e7SBaptiste Daroussin unsigned i; 2250c8de5b0SBaptiste Daroussin Value_t *start_derives; 22698e903e7SBaptiste Daroussin core *p; 22798e903e7SBaptiste Daroussin 22898e903e7SBaptiste Daroussin start_derives = derives[start_symbol]; 22998e903e7SBaptiste Daroussin for (i = 0; start_derives[i] >= 0; ++i) 23098e903e7SBaptiste Daroussin continue; 23198e903e7SBaptiste Daroussin 2320c8de5b0SBaptiste Daroussin p = (core *)MALLOC(sizeof(core) + i * sizeof(Value_t)); 23398e903e7SBaptiste Daroussin NO_SPACE(p); 23498e903e7SBaptiste Daroussin 23598e903e7SBaptiste Daroussin p->next = 0; 23698e903e7SBaptiste Daroussin p->link = 0; 23798e903e7SBaptiste Daroussin p->number = 0; 23898e903e7SBaptiste Daroussin p->accessing_symbol = 0; 23998e903e7SBaptiste Daroussin p->nitems = (Value_t) i; 24098e903e7SBaptiste Daroussin 24198e903e7SBaptiste Daroussin for (i = 0; start_derives[i] >= 0; ++i) 24298e903e7SBaptiste Daroussin p->items[i] = rrhs[start_derives[i]]; 24398e903e7SBaptiste Daroussin 24498e903e7SBaptiste Daroussin first_state = last_state = this_state = p; 24598e903e7SBaptiste Daroussin nstates = 1; 24698e903e7SBaptiste Daroussin } 24798e903e7SBaptiste Daroussin 24898e903e7SBaptiste Daroussin static void 24998e903e7SBaptiste Daroussin new_itemsets(void) 25098e903e7SBaptiste Daroussin { 25198e903e7SBaptiste Daroussin Value_t i; 25298e903e7SBaptiste Daroussin int shiftcount; 2530c8de5b0SBaptiste Daroussin Value_t *isp; 2540c8de5b0SBaptiste Daroussin Value_t *ksp; 25598e903e7SBaptiste Daroussin Value_t symbol; 25698e903e7SBaptiste Daroussin 25798e903e7SBaptiste Daroussin for (i = 0; i < nsyms; i++) 25898e903e7SBaptiste Daroussin kernel_end[i] = 0; 25998e903e7SBaptiste Daroussin 26098e903e7SBaptiste Daroussin shiftcount = 0; 26198e903e7SBaptiste Daroussin isp = itemset; 26298e903e7SBaptiste Daroussin while (isp < itemsetend) 26398e903e7SBaptiste Daroussin { 26498e903e7SBaptiste Daroussin i = *isp++; 26598e903e7SBaptiste Daroussin symbol = ritem[i]; 26698e903e7SBaptiste Daroussin if (symbol > 0) 26798e903e7SBaptiste Daroussin { 26898e903e7SBaptiste Daroussin ksp = kernel_end[symbol]; 26998e903e7SBaptiste Daroussin if (!ksp) 27098e903e7SBaptiste Daroussin { 27198e903e7SBaptiste Daroussin shift_symbol[shiftcount++] = symbol; 27298e903e7SBaptiste Daroussin ksp = kernel_base[symbol]; 27398e903e7SBaptiste Daroussin } 27498e903e7SBaptiste Daroussin 27598e903e7SBaptiste Daroussin *ksp++ = (Value_t) (i + 1); 27698e903e7SBaptiste Daroussin kernel_end[symbol] = ksp; 27798e903e7SBaptiste Daroussin } 27898e903e7SBaptiste Daroussin } 27998e903e7SBaptiste Daroussin 28098e903e7SBaptiste Daroussin nshifts = shiftcount; 28198e903e7SBaptiste Daroussin } 28298e903e7SBaptiste Daroussin 28398e903e7SBaptiste Daroussin static core * 28498e903e7SBaptiste Daroussin new_state(int symbol) 28598e903e7SBaptiste Daroussin { 28698e903e7SBaptiste Daroussin unsigned n; 28798e903e7SBaptiste Daroussin core *p; 2880c8de5b0SBaptiste Daroussin Value_t *isp1; 2890c8de5b0SBaptiste Daroussin Value_t *isp2; 2900c8de5b0SBaptiste Daroussin Value_t *iend; 29198e903e7SBaptiste Daroussin 29298e903e7SBaptiste Daroussin #ifdef TRACE 29398e903e7SBaptiste Daroussin fprintf(stderr, "Entering new_state(%d)\n", symbol); 29498e903e7SBaptiste Daroussin #endif 29598e903e7SBaptiste Daroussin 2960c8de5b0SBaptiste Daroussin if (nstates >= MAXYYINT) 29798e903e7SBaptiste Daroussin fatal("too many states"); 29898e903e7SBaptiste Daroussin 29998e903e7SBaptiste Daroussin isp1 = kernel_base[symbol]; 30098e903e7SBaptiste Daroussin iend = kernel_end[symbol]; 30198e903e7SBaptiste Daroussin n = (unsigned)(iend - isp1); 30298e903e7SBaptiste Daroussin 3030c8de5b0SBaptiste Daroussin p = (core *)allocate((sizeof(core) + (n - 1) * sizeof(Value_t))); 30498e903e7SBaptiste Daroussin p->accessing_symbol = (Value_t) symbol; 30598e903e7SBaptiste Daroussin p->number = (Value_t) nstates; 30698e903e7SBaptiste Daroussin p->nitems = (Value_t) n; 30798e903e7SBaptiste Daroussin 30898e903e7SBaptiste Daroussin isp2 = p->items; 30998e903e7SBaptiste Daroussin while (isp1 < iend) 31098e903e7SBaptiste Daroussin *isp2++ = *isp1++; 31198e903e7SBaptiste Daroussin 31298e903e7SBaptiste Daroussin last_state->next = p; 31398e903e7SBaptiste Daroussin last_state = p; 31498e903e7SBaptiste Daroussin 31598e903e7SBaptiste Daroussin nstates++; 31698e903e7SBaptiste Daroussin 31798e903e7SBaptiste Daroussin return (p); 31898e903e7SBaptiste Daroussin } 31998e903e7SBaptiste Daroussin 32098e903e7SBaptiste Daroussin /* show_cores is used for debugging */ 3210c8de5b0SBaptiste Daroussin #ifdef DEBUG 32298e903e7SBaptiste Daroussin void 32398e903e7SBaptiste Daroussin show_cores(void) 32498e903e7SBaptiste Daroussin { 32598e903e7SBaptiste Daroussin core *p; 32698e903e7SBaptiste Daroussin int i, j, k, n; 32798e903e7SBaptiste Daroussin int itemno; 32898e903e7SBaptiste Daroussin 32998e903e7SBaptiste Daroussin k = 0; 33098e903e7SBaptiste Daroussin for (p = first_state; p; ++k, p = p->next) 33198e903e7SBaptiste Daroussin { 33298e903e7SBaptiste Daroussin if (k) 33398e903e7SBaptiste Daroussin printf("\n"); 33498e903e7SBaptiste Daroussin printf("state %d, number = %d, accessing symbol = %s\n", 33598e903e7SBaptiste Daroussin k, p->number, symbol_name[p->accessing_symbol]); 33698e903e7SBaptiste Daroussin n = p->nitems; 33798e903e7SBaptiste Daroussin for (i = 0; i < n; ++i) 33898e903e7SBaptiste Daroussin { 33998e903e7SBaptiste Daroussin itemno = p->items[i]; 34098e903e7SBaptiste Daroussin printf("%4d ", itemno); 34198e903e7SBaptiste Daroussin j = itemno; 34298e903e7SBaptiste Daroussin while (ritem[j] >= 0) 34398e903e7SBaptiste Daroussin ++j; 34498e903e7SBaptiste Daroussin printf("%s :", symbol_name[rlhs[-ritem[j]]]); 34598e903e7SBaptiste Daroussin j = rrhs[-ritem[j]]; 34698e903e7SBaptiste Daroussin while (j < itemno) 34798e903e7SBaptiste Daroussin printf(" %s", symbol_name[ritem[j++]]); 34898e903e7SBaptiste Daroussin printf(" ."); 34998e903e7SBaptiste Daroussin while (ritem[j] >= 0) 35098e903e7SBaptiste Daroussin printf(" %s", symbol_name[ritem[j++]]); 35198e903e7SBaptiste Daroussin printf("\n"); 35298e903e7SBaptiste Daroussin fflush(stdout); 35398e903e7SBaptiste Daroussin } 35498e903e7SBaptiste Daroussin } 35598e903e7SBaptiste Daroussin } 35698e903e7SBaptiste Daroussin 35798e903e7SBaptiste Daroussin /* show_ritems is used for debugging */ 35898e903e7SBaptiste Daroussin 35998e903e7SBaptiste Daroussin void 36098e903e7SBaptiste Daroussin show_ritems(void) 36198e903e7SBaptiste Daroussin { 36298e903e7SBaptiste Daroussin int i; 36398e903e7SBaptiste Daroussin 36498e903e7SBaptiste Daroussin for (i = 0; i < nitems; ++i) 36598e903e7SBaptiste Daroussin printf("ritem[%d] = %d\n", i, ritem[i]); 36698e903e7SBaptiste Daroussin } 36798e903e7SBaptiste Daroussin 36898e903e7SBaptiste Daroussin /* show_rrhs is used for debugging */ 36998e903e7SBaptiste Daroussin void 37098e903e7SBaptiste Daroussin show_rrhs(void) 37198e903e7SBaptiste Daroussin { 37298e903e7SBaptiste Daroussin int i; 37398e903e7SBaptiste Daroussin 37498e903e7SBaptiste Daroussin for (i = 0; i < nrules; ++i) 37598e903e7SBaptiste Daroussin printf("rrhs[%d] = %d\n", i, rrhs[i]); 37698e903e7SBaptiste Daroussin } 37798e903e7SBaptiste Daroussin 37898e903e7SBaptiste Daroussin /* show_shifts is used for debugging */ 37998e903e7SBaptiste Daroussin 38098e903e7SBaptiste Daroussin void 38198e903e7SBaptiste Daroussin show_shifts(void) 38298e903e7SBaptiste Daroussin { 38398e903e7SBaptiste Daroussin shifts *p; 38498e903e7SBaptiste Daroussin int i, j, k; 38598e903e7SBaptiste Daroussin 38698e903e7SBaptiste Daroussin k = 0; 38798e903e7SBaptiste Daroussin for (p = first_shift; p; ++k, p = p->next) 38898e903e7SBaptiste Daroussin { 38998e903e7SBaptiste Daroussin if (k) 39098e903e7SBaptiste Daroussin printf("\n"); 39198e903e7SBaptiste Daroussin printf("shift %d, number = %d, nshifts = %d\n", k, p->number, 39298e903e7SBaptiste Daroussin p->nshifts); 39398e903e7SBaptiste Daroussin j = p->nshifts; 39498e903e7SBaptiste Daroussin for (i = 0; i < j; ++i) 39598e903e7SBaptiste Daroussin printf("\t%d\n", p->shift[i]); 39698e903e7SBaptiste Daroussin } 39798e903e7SBaptiste Daroussin } 3980c8de5b0SBaptiste Daroussin #endif 39998e903e7SBaptiste Daroussin 40098e903e7SBaptiste Daroussin static void 40198e903e7SBaptiste Daroussin save_shifts(void) 40298e903e7SBaptiste Daroussin { 40398e903e7SBaptiste Daroussin shifts *p; 4040c8de5b0SBaptiste Daroussin Value_t *sp1; 4050c8de5b0SBaptiste Daroussin Value_t *sp2; 4060c8de5b0SBaptiste Daroussin Value_t *send; 40798e903e7SBaptiste Daroussin 40898e903e7SBaptiste Daroussin p = (shifts *)allocate((sizeof(shifts) + 4090c8de5b0SBaptiste Daroussin (unsigned)(nshifts - 1) * sizeof(Value_t))); 41098e903e7SBaptiste Daroussin 41198e903e7SBaptiste Daroussin p->number = this_state->number; 41298e903e7SBaptiste Daroussin p->nshifts = (Value_t) nshifts; 41398e903e7SBaptiste Daroussin 41498e903e7SBaptiste Daroussin sp1 = shiftset; 41598e903e7SBaptiste Daroussin sp2 = p->shift; 41698e903e7SBaptiste Daroussin send = shiftset + nshifts; 41798e903e7SBaptiste Daroussin 41898e903e7SBaptiste Daroussin while (sp1 < send) 41998e903e7SBaptiste Daroussin *sp2++ = *sp1++; 42098e903e7SBaptiste Daroussin 42198e903e7SBaptiste Daroussin if (last_shift) 42298e903e7SBaptiste Daroussin { 42398e903e7SBaptiste Daroussin last_shift->next = p; 42498e903e7SBaptiste Daroussin last_shift = p; 42598e903e7SBaptiste Daroussin } 42698e903e7SBaptiste Daroussin else 42798e903e7SBaptiste Daroussin { 42898e903e7SBaptiste Daroussin first_shift = p; 42998e903e7SBaptiste Daroussin last_shift = p; 43098e903e7SBaptiste Daroussin } 43198e903e7SBaptiste Daroussin } 43298e903e7SBaptiste Daroussin 43398e903e7SBaptiste Daroussin static void 43498e903e7SBaptiste Daroussin save_reductions(void) 43598e903e7SBaptiste Daroussin { 4360c8de5b0SBaptiste Daroussin Value_t *isp; 4370c8de5b0SBaptiste Daroussin Value_t *rp1; 4380c8de5b0SBaptiste Daroussin Value_t *rp2; 43998e903e7SBaptiste Daroussin int item; 44098e903e7SBaptiste Daroussin Value_t count; 44198e903e7SBaptiste Daroussin reductions *p; 4420c8de5b0SBaptiste Daroussin Value_t *rend; 44398e903e7SBaptiste Daroussin 44498e903e7SBaptiste Daroussin count = 0; 44598e903e7SBaptiste Daroussin for (isp = itemset; isp < itemsetend; isp++) 44698e903e7SBaptiste Daroussin { 44798e903e7SBaptiste Daroussin item = ritem[*isp]; 44898e903e7SBaptiste Daroussin if (item < 0) 44998e903e7SBaptiste Daroussin { 45098e903e7SBaptiste Daroussin redset[count++] = (Value_t) - item; 45198e903e7SBaptiste Daroussin } 45298e903e7SBaptiste Daroussin } 45398e903e7SBaptiste Daroussin 45498e903e7SBaptiste Daroussin if (count) 45598e903e7SBaptiste Daroussin { 45698e903e7SBaptiste Daroussin p = (reductions *)allocate((sizeof(reductions) + 45798e903e7SBaptiste Daroussin (unsigned)(count - 1) * 4580c8de5b0SBaptiste Daroussin sizeof(Value_t))); 45998e903e7SBaptiste Daroussin 46098e903e7SBaptiste Daroussin p->number = this_state->number; 46198e903e7SBaptiste Daroussin p->nreds = count; 46298e903e7SBaptiste Daroussin 46398e903e7SBaptiste Daroussin rp1 = redset; 46498e903e7SBaptiste Daroussin rp2 = p->rules; 46598e903e7SBaptiste Daroussin rend = rp1 + count; 46698e903e7SBaptiste Daroussin 46798e903e7SBaptiste Daroussin while (rp1 < rend) 46898e903e7SBaptiste Daroussin *rp2++ = *rp1++; 46998e903e7SBaptiste Daroussin 47098e903e7SBaptiste Daroussin if (last_reduction) 47198e903e7SBaptiste Daroussin { 47298e903e7SBaptiste Daroussin last_reduction->next = p; 47398e903e7SBaptiste Daroussin last_reduction = p; 47498e903e7SBaptiste Daroussin } 47598e903e7SBaptiste Daroussin else 47698e903e7SBaptiste Daroussin { 47798e903e7SBaptiste Daroussin first_reduction = p; 47898e903e7SBaptiste Daroussin last_reduction = p; 47998e903e7SBaptiste Daroussin } 48098e903e7SBaptiste Daroussin } 48198e903e7SBaptiste Daroussin } 48298e903e7SBaptiste Daroussin 48398e903e7SBaptiste Daroussin static void 48498e903e7SBaptiste Daroussin set_derives(void) 48598e903e7SBaptiste Daroussin { 48698e903e7SBaptiste Daroussin Value_t i, k; 48798e903e7SBaptiste Daroussin int lhs; 48898e903e7SBaptiste Daroussin 4890c8de5b0SBaptiste Daroussin derives = NEW2(nsyms, Value_t *); 4900c8de5b0SBaptiste Daroussin rules = NEW2(nvars + nrules, Value_t); 49198e903e7SBaptiste Daroussin 49298e903e7SBaptiste Daroussin k = 0; 49398e903e7SBaptiste Daroussin for (lhs = start_symbol; lhs < nsyms; lhs++) 49498e903e7SBaptiste Daroussin { 49598e903e7SBaptiste Daroussin derives[lhs] = rules + k; 49698e903e7SBaptiste Daroussin for (i = 0; i < nrules; i++) 49798e903e7SBaptiste Daroussin { 49898e903e7SBaptiste Daroussin if (rlhs[i] == lhs) 49998e903e7SBaptiste Daroussin { 50098e903e7SBaptiste Daroussin rules[k] = i; 50198e903e7SBaptiste Daroussin k++; 50298e903e7SBaptiste Daroussin } 50398e903e7SBaptiste Daroussin } 50498e903e7SBaptiste Daroussin rules[k] = -1; 50598e903e7SBaptiste Daroussin k++; 50698e903e7SBaptiste Daroussin } 50798e903e7SBaptiste Daroussin 50898e903e7SBaptiste Daroussin #ifdef DEBUG 50998e903e7SBaptiste Daroussin print_derives(); 51098e903e7SBaptiste Daroussin #endif 51198e903e7SBaptiste Daroussin } 51298e903e7SBaptiste Daroussin 51398e903e7SBaptiste Daroussin #ifdef DEBUG 51498e903e7SBaptiste Daroussin void 51598e903e7SBaptiste Daroussin print_derives(void) 51698e903e7SBaptiste Daroussin { 51798e903e7SBaptiste Daroussin int i; 5180c8de5b0SBaptiste Daroussin Value_t *sp; 51998e903e7SBaptiste Daroussin 52098e903e7SBaptiste Daroussin printf("\nDERIVES\n\n"); 52198e903e7SBaptiste Daroussin 52298e903e7SBaptiste Daroussin for (i = start_symbol; i < nsyms; i++) 52398e903e7SBaptiste Daroussin { 52498e903e7SBaptiste Daroussin printf("%s derives ", symbol_name[i]); 52598e903e7SBaptiste Daroussin for (sp = derives[i]; *sp >= 0; sp++) 52698e903e7SBaptiste Daroussin { 52798e903e7SBaptiste Daroussin printf(" %d", *sp); 52898e903e7SBaptiste Daroussin } 52998e903e7SBaptiste Daroussin putchar('\n'); 53098e903e7SBaptiste Daroussin } 53198e903e7SBaptiste Daroussin 53298e903e7SBaptiste Daroussin putchar('\n'); 53398e903e7SBaptiste Daroussin } 53498e903e7SBaptiste Daroussin #endif 53598e903e7SBaptiste Daroussin 53698e903e7SBaptiste Daroussin static void 53798e903e7SBaptiste Daroussin set_nullable(void) 53898e903e7SBaptiste Daroussin { 53998e903e7SBaptiste Daroussin int i, j; 54098e903e7SBaptiste Daroussin int empty; 54198e903e7SBaptiste Daroussin int done_flag; 54298e903e7SBaptiste Daroussin 5433e066022SBaptiste Daroussin nullable = TMALLOC(char, nsyms); 54498e903e7SBaptiste Daroussin NO_SPACE(nullable); 54598e903e7SBaptiste Daroussin 54698e903e7SBaptiste Daroussin for (i = 0; i < nsyms; ++i) 54798e903e7SBaptiste Daroussin nullable[i] = 0; 54898e903e7SBaptiste Daroussin 54998e903e7SBaptiste Daroussin done_flag = 0; 55098e903e7SBaptiste Daroussin while (!done_flag) 55198e903e7SBaptiste Daroussin { 55298e903e7SBaptiste Daroussin done_flag = 1; 55398e903e7SBaptiste Daroussin for (i = 1; i < nitems; i++) 55498e903e7SBaptiste Daroussin { 55598e903e7SBaptiste Daroussin empty = 1; 55698e903e7SBaptiste Daroussin while ((j = ritem[i]) >= 0) 55798e903e7SBaptiste Daroussin { 55898e903e7SBaptiste Daroussin if (!nullable[j]) 55998e903e7SBaptiste Daroussin empty = 0; 56098e903e7SBaptiste Daroussin ++i; 56198e903e7SBaptiste Daroussin } 56298e903e7SBaptiste Daroussin if (empty) 56398e903e7SBaptiste Daroussin { 56498e903e7SBaptiste Daroussin j = rlhs[-j]; 56598e903e7SBaptiste Daroussin if (!nullable[j]) 56698e903e7SBaptiste Daroussin { 56798e903e7SBaptiste Daroussin nullable[j] = 1; 56898e903e7SBaptiste Daroussin done_flag = 0; 56998e903e7SBaptiste Daroussin } 57098e903e7SBaptiste Daroussin } 57198e903e7SBaptiste Daroussin } 57298e903e7SBaptiste Daroussin } 57398e903e7SBaptiste Daroussin 57498e903e7SBaptiste Daroussin #ifdef DEBUG 57598e903e7SBaptiste Daroussin for (i = 0; i < nsyms; i++) 57698e903e7SBaptiste Daroussin { 57798e903e7SBaptiste Daroussin if (nullable[i]) 57898e903e7SBaptiste Daroussin printf("%s is nullable\n", symbol_name[i]); 57998e903e7SBaptiste Daroussin else 58098e903e7SBaptiste Daroussin printf("%s is not nullable\n", symbol_name[i]); 58198e903e7SBaptiste Daroussin } 58298e903e7SBaptiste Daroussin #endif 58398e903e7SBaptiste Daroussin } 58498e903e7SBaptiste Daroussin 58598e903e7SBaptiste Daroussin void 58698e903e7SBaptiste Daroussin lr0(void) 58798e903e7SBaptiste Daroussin { 58898e903e7SBaptiste Daroussin set_derives(); 58998e903e7SBaptiste Daroussin set_nullable(); 59098e903e7SBaptiste Daroussin generate_states(); 59198e903e7SBaptiste Daroussin } 59298e903e7SBaptiste Daroussin 59398e903e7SBaptiste Daroussin #ifdef NO_LEAKS 59498e903e7SBaptiste Daroussin void 59598e903e7SBaptiste Daroussin lr0_leaks(void) 59698e903e7SBaptiste Daroussin { 5970c8de5b0SBaptiste Daroussin if (derives) 5980c8de5b0SBaptiste Daroussin { 599*0f86d14eSJung-uk Kim if (derives[start_symbol] != rules) 600*0f86d14eSJung-uk Kim { 60198e903e7SBaptiste Daroussin DO_FREE(derives[start_symbol]); 602*0f86d14eSJung-uk Kim } 60398e903e7SBaptiste Daroussin DO_FREE(derives); 604*0f86d14eSJung-uk Kim DO_FREE(rules); 6050c8de5b0SBaptiste Daroussin } 60698e903e7SBaptiste Daroussin DO_FREE(nullable); 60798e903e7SBaptiste Daroussin } 60898e903e7SBaptiste Daroussin #endif 609