int main(int argc, char **argv) { bitset_size_t pos; bitset_t *bitset = bitset_init(NULL, DATA_SIZE); bitset_set(bitset, 0); bitset_set(bitset, 5); bitset_set(bitset, 38); bitset_set(bitset, 31); bitset_set(bitset, 32); bitset_print(bitset); bitset_unset_all(bitset); bitset_print(bitset); bitset_set_all(bitset); bitset_print(bitset); /* pos = -1; */ /* while ((pos = bitset_find_first_set_since(bitset, pos + 1)) */ /* != bitset_npos) */ /* printf("%d is set\n", pos); */ /* pos = -1; */ /* while ((pos = bitset_find_first_unset_since(bitset, pos + 1)) */ /* != bitset_npos) */ /* printf("%d is unset\n", pos); */ bitset_delete(bitset); return 0; }
static int apply_alternating_path(bipartite_t const *const gr, int *const matching, bitset_t *const matched_left, bitset_t *const matched_right) { bool done_something = false; bitset_t *const tmp = bitset_alloca(gr->n_right); for (unsigned left = 0; left < gr->n_left; ++left) { bitset_t *left_adj = gr->adj[left]; bitset_copy(tmp, left_adj); if (matching[left] >= 0) { int old_right = matching[left]; /* Check of all neighbors of the left node are already matched. * We cannot improve this edge then. */ if (bitset_contains(left_adj, matched_right)) continue; bitset_andnot(tmp, matched_right); unsigned right = bitset_next_set(tmp, 0); assert(right != ~0u); /* We have to find another left node which has the old right one as * a neighbor. This node must not be part of a matching */ unsigned i; for (i = 0; i < gr->n_left; ++i) if (i != left && bitset_is_set(gr->adj[i], old_right) && !bitset_is_set(matched_left, i)) break; /* If no such node can be found, exit. */ if (i >= gr->n_left) continue; /* Else, we can improve this edge. */ matching[left] = right; matching[i] = old_right; bitset_set(matched_left, i); bitset_set(matched_right, right); done_something = true; } else { /* We have to create a new single edge */ assert(!bitset_is_set(matched_left, left)); bitset_andnot(tmp, matched_right); if (bitset_is_empty(tmp)) continue; unsigned right = bitset_next_set(tmp, 0); assert(!bitset_is_set(matched_right, right)); matching[left] = right; bitset_set(matched_left, left); bitset_set(matched_right, right); done_something = true; } } return done_something; }
/** * \post: * - \c result = a new \c bitset of size \c ::nritems such that any bit \c i * is set iff <tt>ritem[i]</tt> is a nonterminal after which all ritems in * the same RHS are nullable nonterminals. In other words, the follows of * a goto on <tt>ritem[i]</tt> include the lookahead set of the item. */ static bitset ielr_compute_ritem_sees_lookahead_set (void) { bitset result = bitset_create (nritems, BITSET_FIXED); unsigned int i = nritems-1; while (i>0) { --i; while (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i]) && nullable [item_number_as_symbol_number (ritem[i]) - ntokens]) bitset_set (result, i--); if (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i])) bitset_set (result, i--); while (!item_number_is_rule_number (ritem[i]) && i>0) --i; } if (trace_flag & trace_ielr) { fprintf (stderr, "ritem_sees_lookahead_set:\n"); debug_bitset (result); fprintf (stderr, "\n"); } return result; }
void test_hint( int *passed, int *failed ) { int res = 1; bitset *bs = bitset_create(); if ( bs != NULL ) { bs = bitset_set(bs,1); if ( bs != NULL ) bs = bitset_set(bs,23); if ( bs != NULL ) { hint *h = hint_create( bs, (vgnode*)0x123 ); if ( h != NULL ) { if ( hint_node(h) != (vgnode*)0x123 ) { fprintf(stderr,"hint: failed to set node\n"); res = 0; } bitset *bs2 = bitset_create(); if ( bs2 != NULL ) { bs2 = bitset_set( bs2, 12 ); hint_or( h, bs2 ); if ( !hint_contains(h,bs) ) { fprintf(stderr,"hint: failed to save bs\n"); res = 0; } if ( !hint_contains(h,bs2) ) { fprintf(stderr,"hint: failed to save bs2\n"); res = 0; } hint *h2 = hint_create( bs2, NULL ); if ( h2 != NULL ) { hint_append( h, h2 ); hint *head = hint_delist( h ); if ( head != h2 ) { fprintf(stderr,"hint: delist failed\n"); res = 0; } hint_dispose( h2 ); } bitset_dispose( bs2 ); } hint_dispose( h ); } bitset_dispose( bs ); } else res = 0; } if ( res ) (*passed)++; else (*failed)++; }
static rule * state_default_rule (state *s) { reductions *reds = s->reductions; rule *default_rule = NULL; int cmax = 0; int i; /* No need for a look-ahead. */ if (s->consistent) return reds->rules[0]; /* 1. Each reduction is possibly masked by the look-ahead tokens on which we shift (S/R conflicts)... */ bitset_zero (shift_set); { transitions *trans = s->transitions; FOR_EACH_SHIFT (trans, i) { /* If this state has a shift for the error token, don't use a default rule. */ if (TRANSITION_IS_ERROR (trans, i)) return NULL; bitset_set (shift_set, TRANSITION_SYMBOL (trans, i)); } } /* 2. Each reduction is possibly masked by the look-ahead tokens on which we raise an error (due to %nonassoc). */ { errs *errp = s->errs; for (i = 0; i < errp->num; i++) if (errp->symbols[i]) bitset_set (shift_set, errp->symbols[i]->number); } for (i = 0; i < reds->num; ++i) { int count = 0; /* How many non-masked look-ahead tokens are there for this reduction? */ bitset_andn (look_ahead_set, reds->look_ahead_tokens[i], shift_set); count = bitset_count (look_ahead_set); if (count > cmax) { cmax = count; default_rule = reds->rules[i]; } /* 3. And finally, each reduction is possibly masked by previous reductions (in R/R conflicts, we keep the first reductions). */ bitset_or (shift_set, shift_set, reds->look_ahead_tokens[i]); } return default_rule; }
void mem_add_edge(rga_node * u, rga_node * v){ if(!bitset_check(adjSet[u->id], v->id) && !bitset_check(adjSet[v->id], u->id) && u != v){ bitset_set(adjSet[u->id], v->id); bitset_set(adjSet[v->id], u->id); adjList[u->id] = rga_node_map_add(adjList[u->id], v); adjList[v->id] = rga_node_map_add(adjList[v->id], u); } }
static void no_reduce_bitset_init (state const *s, bitset *no_reduce_set) { int n; *no_reduce_set = bitset_create (ntokens, BITSET_FIXED); bitset_zero (*no_reduce_set); FOR_EACH_SHIFT (s->transitions, n) bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n)); for (n = 0; n < s->errs->num; ++n) if (s->errs->symbols[n]) bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number); }
static void card_test_overhang( int *passed, int *failed, plugin_log *log ) { card_set_right(cl,cr); card_set_left(cr,cl); bitset *bs = card_node_overhang( cl ); if ( bs != NULL ) { bitset *bsc = bitset_create(); if ( bsc != NULL ) { bsc = bitset_or( bsc, bsl ); bsc = bitset_set( bsc, 7 ); bitset_and_not( bsc, pair_versions(pr) ); if ( !bitset_equals(bsc,bs) ) { fprintf(stderr,"card: overhang text failed\n"); (*failed)++; } else (*passed)++; } else (*failed)++; if ( bsc != NULL ) bitset_dispose( bsc ); } else { fprintf(stderr,"card: failed to compute overhang\n"); (*failed)++; } if ( bs != NULL ) bitset_dispose( bs ); }
/** * Add a new card * @param list the list of cards to add it to * @param c the card to add * @param text_off the offset in version for lp * @param version the version to follow */ void card_add_at( card **list, card *c, int text_off, int version ) { card *temp = *list; bitset *bs = bitset_create(); if ( bs != NULL ) bs = bitset_set( bs, version ); if ( bs != NULL ) { card *last = NULL; while ( temp != NULL ) { pair *p = card_pair(temp); if ( bitset_next_set_bit(pair_versions(p),version)== version ) { int off = card_text_off(temp); if ( off < text_off ) last = temp; else { if ( last != NULL ) card_add_after( last, c ); else { c->right = *list; *list = c; } break; } } temp = card_next( temp, bs, 0 ); } bitset_dispose( bs ); } }
/* Obtain and set a PID for the new process. * O(1) in average case, O(N) degenerate case (more than PID_MAX procs) * Uses hardware FFS instruction, so runs in very quick N/32 time */ static int _set_pid(process_create_data *data) { // Try to increment _last_pid. int err; sos_pcb *pcb = data->pcb; int cur_pid = _last_pid + 1; sos_pcb *taken = NULL; if (!pids) { dprintf(6, "Allocating PID set...\n"); bitset_alloc(&pids, SOS_PID_MAX - SOS_PID_MIN); } dprintf(1, "bs size: %d\n", pids->size); if (bitset_test(pids, cur_pid)) { dprintf(6, "\tPID %d is already taken.\n", cur_pid); // cur_pid is taken cur_pid = bitset_ffz(pids); dprintf(6, "\tfirst free PID: %d\n", cur_pid); if (cur_pid < 0 || cur_pid > pids->size) { return SOS_PROCESS_MAXPROC; } } // cur_pid is known to be free bitset_set(pids, cur_pid); pcb->pid = cur_pid + SOS_PID_MIN; _last_pid = cur_pid; HASH_ADD_INT(_process_table, pid, pcb); return SOS_PROCESS_SUCCESS; }
/** * Check if a word is a keyword and, if so, to mark it (marking is used to show * the player which keywords have already been used in a conversation). * * @conv is the conversation to check. * @word is the word to look for in the keywords. */ static void conv_mark_if_keyword(struct conv *conv, char *word) { int index = conv_lookup_keyword(conv, word); if (index != -1) { bitset_set(conv->marked, index); } }
int main(int argc, char **argv) { bitset *set; set = bitset_new(50); if (set == NULL) return 0; init_array(); printf("A: \n"); print_array(A, 20); printf("B: \n"); print_array(B, 20); int i, j, common[20]; for (i = 0; i < 20; i++) { bitset_set(set, A[i], 1); } j = 0; for (i = 0; i < 20; i++) { if (bitset_get(set, B[i])) { common[j++] = B[i]; } } printf("Common: \n"); print_array(common, j); bitset_free(set); return 0; }
static int count_sr_conflicts (state *s) { int i; int src_count = 0; transitions *trans = s->transitions; reductions *reds = s->reductions; if (!trans) return 0; bitset_zero (lookahead_set); bitset_zero (shift_set); FOR_EACH_SHIFT (trans, i) bitset_set (shift_set, TRANSITION_SYMBOL (trans, i)); for (i = 0; i < reds->num; ++i) bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); bitset_and (lookahead_set, lookahead_set, shift_set); src_count = bitset_count (lookahead_set); return src_count; }
static void useless_nonterminals (void) { bitset Np, Ns; rule_number r; /* N is set as built. Np is set being built this iteration. P is set of all productions which have a RHS all in N. */ Np = bitset_create (nvars, BITSET_FIXED); /* The set being computed is a set of nonterminals which can derive the empty string or strings consisting of all terminals. At each iteration a nonterminal is added to the set if there is a production with that nonterminal as its LHS for which all the nonterminals in its RHS are already in the set. Iterate until the set being computed remains unchanged. Any nonterminals not in the set at that point are useless in that they will never be used in deriving a sentence of the language. This iteration doesn't use any special traversal over the productions. A set is kept of all productions for which all the nonterminals in the RHS are in useful. Only productions not in this set are scanned on each iteration. At the end, this set is saved to be used when finding useful productions: only productions in this set will appear in the final grammar. */ while (1) { bitset_copy (Np, N); for (r = 0; r < nrules; r++) if (!bitset_test (P, r) && useful_production (r, N)) { bitset_set (Np, rules[r].lhs->number - ntokens); bitset_set (P, r); } if (bitset_equal_p (N, Np)) break; Ns = Np; Np = N; N = Ns; } bitset_free (N); N = Np; }
void add_edge(rga_node * u, rga_node * v){ if(!bitset_check(adjSet[u->id], v->id) && !bitset_check(adjSet[v->id], u->id) && u != v){ bitset_set(adjSet[u->id], v->id); bitset_set(adjSet[v->id], u->id); #ifdef DEBUG_MODE printf("Edge from v%u to v%u\n", u->id, v->id); #endif if(u->set != RGA_PRECOLOURED){ adjList[u->id] = rga_node_map_add(adjList[u->id], v); degree[u->id]++; } if(v->set != RGA_PRECOLOURED){ adjList[v->id] = rga_node_map_add(adjList[v->id], u); degree[v->id]++; } } }
int bitset_toggle(bitset *bs, unsigned int bit) { if (bs == NULL || bit >= bs->size) return -BITSET_ERROR; if (bitset_test(bs, bit) > 0) { return bitset_clear(bs, bit); } else { return bitset_set(bs, bit); } }
void output_red (state const *s, reductions const *reds, FILE *fout) { bitset no_reduce_set; int j; int source = s->number; /* Two obstacks are needed: one for the enabled reductions, and one for the disabled reductions, because in the end we want two separate edges, even though in most cases only one will actually be printed. */ struct obstack dout; struct obstack eout; no_reduce_bitset_init (s, &no_reduce_set); obstack_init (&dout); obstack_init (&eout); for (j = 0; j < reds->num; ++j) { bool defaulted = false; bool firstd = true; bool firste = true; rule_number ruleno = reds->rules[j]->number; rule *default_reduction = NULL; if (yydefact[s->number] != 0) default_reduction = &rules[yydefact[s->number] - 1]; /* Build the lookahead tokens lists, one for enabled transitions and one for disabled transistions. */ if (default_reduction && default_reduction == reds->rules[j]) defaulted = true; if (reds->lookahead_tokens) { int i; for (i = 0; i < ntokens; i++) if (bitset_test (reds->lookahead_tokens[j], i)) { if (bitset_test (no_reduce_set, i)) firstd = print_token (&dout, firstd, symbols[i]->tag); else { if (! defaulted) firste = print_token (&eout, firste, symbols[i]->tag); bitset_set (no_reduce_set, i); } } } /* Do the actual output. */ conclude_red (&dout, source, ruleno, false, firstd, fout); conclude_red (&eout, source, ruleno, true, firste && !defaulted, fout); } obstack_free (&dout, 0); obstack_free (&eout, 0); bitset_free (no_reduce_set); }
static void test_cardinality() { header(); struct bitset bm; bitset_create(&bm, realloc); fail_unless(bitset_cardinality(&bm) == 0); size_t cnt = 0; fail_if(bitset_set(&bm, 10) < 0); cnt++; fail_if(bitset_set(&bm, 15) < 0); cnt++; fail_if(bitset_set(&bm, 20) < 0); cnt++; fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_set(&bm, 10) < 0); fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 20) < 0); cnt--; fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 20) < 0); fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 666) < 0); fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 10) < 0); cnt--; fail_unless(bitset_cardinality(&bm) == cnt); fail_if(bitset_clear(&bm, 15) < 0); cnt--; fail_unless(bitset_cardinality(&bm) == cnt); bitset_destroy(&bm); footer(); }
void combine_edge(rga_node * u, rga_node * v){ if(!bitset_check(adjSet[u->id], v->id) && !bitset_check(adjSet[v->id], u->id) && u != v){ bitset_set(adjSet[u->id], v->id); bitset_set(adjSet[v->id], u->id); if(u->set != RGA_PRECOLOURED){ adjList[u->id] = rga_node_map_add(adjList[u->id], v); } if(v->set != RGA_PRECOLOURED){ adjList[v->id] = rga_node_map_add(adjList[v->id], u); degree[v->id]++; #ifdef DEBUG_MODE printf("Degree of v%u ++ (now = %u)\n", v->id, degree[v->id]); #endif } }else{ decrement_degree(u); } }
/* Given a vector BSETV of N bitsets of size N, modify its contents to be the reflexive transitive closure of what was given. This is the same as transitive closure but with all bits on the diagonal of the bit matrix set. */ void bitsetv_reflexive_transitive_closure (bitsetv bsetv) { bitset_bindex i; bitsetv_transitive_closure (bsetv); for (i = 0; bsetv[i]; i++) bitset_set (bsetv[i], i); }
int main(int args, char **argv) { size_t bitset_size = 1 << (30 - 5); uint64_t max_prime = bitset_size << 5; fprintf(stderr, "Upper limit: %d\n", max_prime); bitset bits; bits.size = bitset_size; bits.elements = calloc(sizeof(unsigned int), bits.size); // Set all multiples of two to be non-primes and the rest // to be primes memset(bits.elements, 2 + 8 + 32 + 128, bits.size * sizeof(unsigned int)); bitset *primes = &bits; bitset_unset(primes, 1); bitset_set(primes, 2); uint64_t p = 3; while (p < max_prime) { // Filter out all multiples of p for (uint32_t i = p + p; i < max_prime; i += p) { bitset_unset(primes, i); } // Find next number to filter out do { p += 2; } while (p < max_prime && !bitset_isset(primes, p)); } // Write to file /* FILE *fp = fopen("test2.raw", "w"); for (p = 2; p < max_prime; p++) { if (bitset_isset(primes, p)) { writeVarint64(p, fp); } } fflush(fp); fclose(fp); fprintf(stderr, "wrote varints\n"); */ FILE *fp = fopen("primes.bin", "w"); fwrite(bits.elements, sizeof(unsigned int), bits.size, fp); fflush(fp); fclose(fp); fprintf(stderr, "Largest prime: %d\n", p - 2); fprintf(stderr, "Wrote bitset: primes.bin\n"); free(bits.elements); }
//Calculates the interference for a single set of live variables static void calc_interference(bitset_t live, bitset_t matrix, unsigned reg_index, unsigned num_regs) { unsigned i; for (i = 0; i < num_regs; i++) { if (i == reg_index) continue; if (bitset_get(live, 4 * i + 0) || bitset_get(live, 4 * i + 1) || bitset_get(live, 4 * i + 2) || bitset_get(live, 4 * i + 3)) { bitset_set(matrix, num_regs*reg_index + i, true); bitset_set(matrix, num_regs*i + reg_index, true); } } }
static inline void matrix_fill_row(sp_matrix_t *m, int row, bitset_t *fullrow) { bitset_set(fullrow, row); matrix_foreach_in_col(m, row, e) { if (! bitset_is_set(fullrow, e->row)) { assert(0.0 == matrix_get(m, e->col, e->row)); matrix_set(m, e->col, e->row, e->val); matrix_set(m, e->row, e->col, 0.0); } } }
bitset * idset_to_bitset(sdm_idset ids) { sdm_id id; bitset_clear(tmp_bitset); for (id = sdm_set_first(ids); !sdm_set_done(ids); id = sdm_set_next(ids)) { bitset_set(tmp_bitset, id); } return tmp_bitset; }
/* Check that all conditions refer to at least one variable; it is silly to * have a constant-based (or context-free) expression to filter information * that passes through Pulley. * Return NULL if all are bound; otherwise return the variables * that are not bound. */ bitset_t *cndtab_invariant_conditions (struct cndtab *tab) { bitset_t *retval = NULL; cndnum_t i; for (i=0; i<tab->count_cnds; i++) { if (bitset_isempty (tab->cnds [i].vars_needed)) { // Error found if (retval == NULL) { retval = bitset_new (&tab->cndtype); } bitset_set (retval, i); } } return retval; }
static void set_conflicts (state *s, symbol **errors) { int i; transitions *trans = s->transitions; reductions *reds = s->reductions; int nerrs = 0; if (s->consistent) return; bitset_zero (lookahead_set); FOR_EACH_SHIFT (trans, i) bitset_set (lookahead_set, TRANSITION_SYMBOL (trans, i)); /* Loop over all rules which require lookahead in this state. First check for shift-reduce conflict, and try to resolve using precedence. */ for (i = 0; i < reds->num; ++i) if (reds->rules[i]->prec && reds->rules[i]->prec->prec && !bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) resolve_sr_conflict (s, i, errors, &nerrs); if (nerrs) { /* Some tokens have been explicitly made errors. Allocate a permanent errs structure for this state, to record them. */ state_errs_set (s, nerrs, errors); } if (obstack_object_size (&solved_conflicts_obstack)) { obstack_1grow (&solved_conflicts_obstack, '\0'); s->solved_conflicts = obstack_finish (&solved_conflicts_obstack); } if (obstack_object_size (&solved_conflicts_xml_obstack)) { obstack_1grow (&solved_conflicts_xml_obstack, '\0'); s->solved_conflicts_xml = obstack_finish (&solved_conflicts_xml_obstack); } /* Loop over all rules which require lookahead in this state. Check for conflicts not resolved above. */ for (i = 0; i < reds->num; ++i) { if (!bitset_disjoint_p (reds->lookahead_tokens[i], lookahead_set)) conflicts[s->number] = 1; bitset_or (lookahead_set, lookahead_set, reds->lookahead_tokens[i]); } }
// ascii test int main() { // create a bitset capable of representing any ascii char bitset_t set = bitset_alloc(128); char str1[255]; printf("\033[1;34mplease enter characters to set:\033[0m "); fgets(str1, 255, stdin); char* p = str1; while(*p != '\0' && *p != '\n') { bitset_set(set, (int)(*p), 1); ++p; } printf("\n\033[1;34mbitset looks like:\n\033[1;36m"); bitset_print(set); print_bitset_chars(set); printf("\033[1;34mplease enter characters to delete:\033[0m "); fgets(str1, 255, stdin); p = str1; while(*p != '\0' && *p != '\n') { bitset_set(set, (int)(*p), 0); ++p; } printf("\n\033[1;34mbitset looks like:\n\033[1;36m"); bitset_print(set); print_bitset_chars(set); printf("\033[0m\n"); return 0; }
END_TEST START_TEST(test_bitset_getset) { int i, j; bitset_init(bs, NCOL1); for (i = 0, j = 0; i < NCOL1; i++) { if (i == cols[j]) { bitset_set(bs, i, 1); j++; ck_assert_int_eq(bs->count, j); } else { /* only bits specified are set */ ck_assert_int_eq(bitset_get(bs, i), 0); } } for (j=0; j < 4; j++) { /* set these bits back to 0 */ ck_assert_int_eq(bitset_get(bs, cols[j]), 1); bitset_set(bs, cols[j], 0); ck_assert_int_eq(bitset_get(bs, cols[j]), 0); ck_assert_int_eq(bs->count, 3 - j); } }
/** * Convert string into a bitset. Inverse of bitset_to_str(). * */ bitset *str_to_bitset(char *str, char **end) { int nbits = 0; int bytes; int n; int pos; int b; int len; bitset *bp; char dst[1024]; if (!str) return NULL; /* hex string has 0x prefix */ if (str[0] == '0' && str[1] == 'x') str = str + 2; len = strlen(str); if (len % 2) { nbits = (len + 1) << 2; bytes = NUM_BYTES(nbits); pos = (bytes << 3) - 5; } else { nbits = len << 2; bytes = NUM_BYTES(nbits); pos = (bytes << 3) - 1; } if (0) hex2binary(str, dst); bp = bitset_new(nbits); for (; *str != '\0' && isxdigit(*str) && pos >= 0; str++) { b = digittoint(*str); for (n = 3; n >= 0; n--, pos--) { if (b & (1 << n)) { bitset_set(bp, pos); } } } if (end != NULL) *end = str - 1; return bp; }
/** * \pre * - \c *edgesp and \c edge_counts were computed by * \c ielr_compute_internal_follow_edges. * \post * - \c *always_followsp is a new \c bitsetv with \c ngotos rows and * \c ntokens columns. * - <tt>(*always_followsp)[i][j]</tt> is set iff token \c j is an always * follow (that is, it's computed by internal and successor edges) of goto * \c i. * - Rows of \c *edgesp have been realloc'ed and extended to include * successor follow edges. \c edge_counts has not been updated. */ static void ielr_compute_always_follows (goto_number ***edgesp, int const edge_counts[], bitsetv *always_followsp) { *always_followsp = bitsetv_create (ngotos, ntokens, BITSET_FIXED); { goto_number *edge_array = xnmalloc (ngotos, sizeof *edge_array); goto_number i; for (i = 0; i < ngotos; ++i) { goto_number nedges = edge_counts[i]; { int j; transitions *trans = states[to_state[i]]->transitions; FOR_EACH_SHIFT (trans, j) bitset_set ((*always_followsp)[i], TRANSITION_SYMBOL (trans, j)); for (; j < trans->num; ++j) { symbol_number sym = TRANSITION_SYMBOL (trans, j); if (nullable[sym - ntokens]) edge_array[nedges++] = map_goto (to_state[i], sym); } } if (nedges - edge_counts[i]) { (*edgesp)[i] = xnrealloc ((*edgesp)[i], nedges + 1, sizeof *(*edgesp)[i]); memcpy ((*edgesp)[i] + edge_counts[i], edge_array + edge_counts[i], (nedges - edge_counts[i]) * sizeof *(*edgesp)[i]); (*edgesp)[i][nedges] = END_NODE; } } free (edge_array); } relation_digraph (*edgesp, ngotos, always_followsp); if (trace_flag & trace_ielr) { fprintf (stderr, "always follow edges:\n"); relation_print (*edgesp, ngotos, stderr); fprintf (stderr, "always_follows:\n"); debug_bitsetv (*always_followsp); } }