mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
lists: fix various issues with the use of gnulib's list
First, we should avoid code such as
gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation *child = NULL;
while (gl_list_iterator_next (&it, (const void **) &child, NULL))
{
derivation_print (child, f);
because of -Wstrict-aliasing (whose job is to catch type-punning
issues). See https://lists.gnu.org/r/bug-bison/2020-05/msg00039.html.
Rather we need
gl_list_iterator_t it = gl_list_iterator (deriv->children);
const void **p = NULL;
while (gl_list_iterator_next (&it, &p, NULL))
{
derivation *child = (derivation *) p;
derivation_print (child, f);
Second, list iterators actually have destructors. Even though they
are noop in the case of linked-lists, we should use them.
Let's address both issues with typed wrappers (such as
derivation_list_next) that take care of both issues, and besides allow
to scope the iterators within the loop:
derivation *child;
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
derivation_list_next (&it, &child);
)
{
derivation_print (child, f);
* src/derivation.h, src/derivation.c (derivation_list_next): New.
Use it where appropriate.
* src/counterexample.c (search_state_list_next): New.
Use it where appropriate.
* src/parse-simulation.h, src/parse-simulation.c
* src/state-item.h (state_item_list_next): New.
Use it where appropriate.
This commit is contained in:
@@ -334,9 +334,9 @@ complete_diverging_example (symbol_number conflict_sym,
|
||||
lookahead_required = false;
|
||||
derivation_list next_derivs =
|
||||
expand_to_conflict (nsi, conflict_sym);
|
||||
gl_list_iterator_t it = gl_list_iterator (next_derivs);
|
||||
derivation *d = NULL;
|
||||
while (gl_list_iterator_next (&it, (const void **) &d, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (next_derivs);
|
||||
derivation_list_next (&it, &d);)
|
||||
derivation_list_append (result, d);
|
||||
i += gl_list_size (next_derivs) - 1;
|
||||
derivation_list_free (next_derivs);
|
||||
@@ -469,9 +469,10 @@ nonunifying_shift_path (gl_list_t reduce_path, state_item *shift_conflict)
|
||||
if (trace_flag & trace_cex)
|
||||
{
|
||||
fputs ("SHIFT ITEM PATH:\n", stderr);
|
||||
gl_list_iterator_t it = gl_list_iterator (result);
|
||||
state_item *sip = NULL;
|
||||
while (gl_list_iterator_next (&it, (const void **) &sip, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (result);
|
||||
state_item_list_next (&it, &sip);
|
||||
)
|
||||
print_state_item (sip, stderr);
|
||||
}
|
||||
return result;
|
||||
@@ -574,6 +575,18 @@ search_state_print (search_state *ss)
|
||||
putc ('\n', stderr);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
search_state_list_next (gl_list_iterator_t *it, search_state **ss)
|
||||
{
|
||||
const void *p = NULL;
|
||||
bool res = gl_list_iterator_next (it, &p, NULL);
|
||||
if (res)
|
||||
*ss = (search_state*) p;
|
||||
else
|
||||
gl_list_iterator_free (it);
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* When a search state is copied, this is used to
|
||||
* directly set one of the parse states
|
||||
@@ -712,9 +725,10 @@ production_step (search_state *ss, int parser_state)
|
||||
simulate_production (ss->states[parser_state], other_sym);
|
||||
int complexity = ss->complexity + PRODUCTION_COST;
|
||||
|
||||
gl_list_iterator_t it = gl_list_iterator (prods);
|
||||
parse_state *ps = NULL;
|
||||
while (gl_list_iterator_next (&it, (const void **) &ps, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (prods);
|
||||
parse_state_list_next (&it, &ps);
|
||||
)
|
||||
{
|
||||
search_state *copy = copy_search_state (ss);
|
||||
ss_set_parse_state (copy, parser_state, ps);
|
||||
@@ -761,9 +775,10 @@ reduction_step (search_state *ss, const item_number *conflict_item,
|
||||
// FIXME: search_state *new_root = copy_search_state (ss);
|
||||
parse_state_list reduced =
|
||||
simulate_reduction (ps, rule_len, symbol_set);
|
||||
gl_list_iterator_t it = gl_list_iterator (reduced);
|
||||
parse_state *reduced_ps;
|
||||
while (gl_list_iterator_next (&it, (const void **) &reduced_ps, NULL))
|
||||
parse_state *reduced_ps = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (reduced);
|
||||
parse_state_list_next (&it, &reduced_ps);
|
||||
)
|
||||
{
|
||||
search_state *copy = copy_search_state (ss);
|
||||
ss_set_parse_state (copy, parser_state, reduced_ps);
|
||||
@@ -797,9 +812,10 @@ search_state_prepend (search_state *ss, symbol_number sym, bitset guide)
|
||||
{
|
||||
int prod_state = prod1 ? 0 : 1;
|
||||
parse_state_list prev = parser_prepend (ss->states[prod_state]);
|
||||
gl_list_iterator_t iter = gl_list_iterator (prev);
|
||||
parse_state *ps = NULL;
|
||||
while (gl_list_iterator_next (&iter, (const void **)&ps, NULL))
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (prev);
|
||||
parse_state_list_next (&iter, &ps);
|
||||
)
|
||||
{
|
||||
const state_item *psi = parse_state_head (ps);
|
||||
bool guided = bitset_test (guide, psi->state->number);
|
||||
@@ -828,18 +844,20 @@ search_state_prepend (search_state *ss, symbol_number sym, bitset guide)
|
||||
// loop through each pair of possible prepend states and append search
|
||||
// states for each pair where the parser states correspond to the same
|
||||
// parsed input.
|
||||
gl_list_iterator_t iter1 = gl_list_iterator (prev1);
|
||||
parse_state *ps1;
|
||||
while (gl_list_iterator_next (&iter1, (const void **)&ps1, NULL))
|
||||
parse_state *ps1 = NULL;
|
||||
for (gl_list_iterator_t iter1 = gl_list_iterator (prev1);
|
||||
parse_state_list_next (&iter1, &ps1);
|
||||
)
|
||||
{
|
||||
const state_item *psi1 = parse_state_head (ps1);
|
||||
bool guided1 = bitset_test (guide, psi1->state->number);
|
||||
if (!guided1 && !EXTENDED_SEARCH)
|
||||
continue;
|
||||
|
||||
gl_list_iterator_t iter2 = gl_list_iterator (prev2);
|
||||
parse_state *ps2;
|
||||
while (gl_list_iterator_next (&iter2, (const void **)&ps2, NULL))
|
||||
parse_state *ps2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (prev2);
|
||||
parse_state_list_next (&iter2, &ps2);
|
||||
)
|
||||
{
|
||||
const state_item *psi2 = parse_state_head (ps2);
|
||||
|
||||
@@ -926,16 +944,15 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
int complexity = ss->complexity + 2 * SHIFT_COST;
|
||||
parse_state_list trans1 = simulate_transition (ps1);
|
||||
parse_state_list trans2 = simulate_transition (ps2);
|
||||
gl_list_iterator_t it1 = gl_list_iterator (trans1);
|
||||
parse_state *tps1;
|
||||
while (gl_list_iterator_next (&it1, (const void **) &tps1, NULL))
|
||||
{
|
||||
gl_list_iterator_t it2 = gl_list_iterator (trans2);
|
||||
parse_state *tps2;
|
||||
while (gl_list_iterator_next
|
||||
(&it2, (const void **) &tps2, NULL))
|
||||
ssb_append (new_search_state (tps1, tps2, complexity));
|
||||
}
|
||||
parse_state *tps1 = NULL;
|
||||
parse_state *tps2 = NULL;
|
||||
for (gl_list_iterator_t it1 = gl_list_iterator (trans1);
|
||||
parse_state_list_next (&it1, &tps1);
|
||||
)
|
||||
for (gl_list_iterator_t it2 = gl_list_iterator (trans2);
|
||||
parse_state_list_next (&it2, &tps2);
|
||||
)
|
||||
ssb_append (new_search_state (tps1, tps2, complexity));
|
||||
gl_list_free (trans1);
|
||||
gl_list_free (trans2);
|
||||
}
|
||||
@@ -958,43 +975,48 @@ generate_next_states (search_state *ss, state_item *conflict1,
|
||||
int len2 = rhe2 - rhs2;
|
||||
int size2 = parse_state_length (ps2);
|
||||
bool ready2 = si2reduce && len2 < size2;
|
||||
// If there is a path ready for reduction
|
||||
// without being prepended further, reduce.
|
||||
if (ready1)
|
||||
// If there is a path ready for reduction without being
|
||||
// prepended further, reduce.
|
||||
if (ready1 && ready2)
|
||||
{
|
||||
gl_list_t reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
gl_list_add_last (reduced1, ss);
|
||||
search_state *red1 = NULL;
|
||||
if (ready2)
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
search_state_list_next (&iter, &red1);
|
||||
)
|
||||
{
|
||||
gl_list_add_last (reduced1, ss);
|
||||
while (gl_list_iterator_next
|
||||
(&iter, (const void **) &red1, NULL))
|
||||
{
|
||||
gl_list_t reduced2 =
|
||||
reduction_step (red1, conflict2->item, 1, len2);
|
||||
gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
search_state *red2;
|
||||
while (gl_list_iterator_next
|
||||
(&iter2, (const void **) &red2, NULL))
|
||||
ssb_append (red2);
|
||||
// avoid duplicates
|
||||
if (red1 != ss)
|
||||
ssb_append (red1);
|
||||
gl_list_free (reduced2);
|
||||
}
|
||||
gl_list_t reduced2 =
|
||||
reduction_step (red1, conflict2->item, 1, len2);
|
||||
search_state *red2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
search_state_list_next (&iter2, &red2);
|
||||
)
|
||||
ssb_append (red2);
|
||||
// Avoid duplicates.
|
||||
if (red1 != ss)
|
||||
ssb_append (red1);
|
||||
gl_list_free (reduced2);
|
||||
}
|
||||
else
|
||||
while (gl_list_iterator_next (&iter, (const void **) &red1, NULL))
|
||||
ssb_append (red1);
|
||||
gl_list_free (reduced1);
|
||||
}
|
||||
else if (ready1)
|
||||
{
|
||||
gl_list_t reduced1 = reduction_step (ss, conflict1->item, 0, len1);
|
||||
search_state *red1 = NULL;
|
||||
for (gl_list_iterator_t iter = gl_list_iterator (reduced1);
|
||||
search_state_list_next (&iter, &red1);
|
||||
)
|
||||
ssb_append (red1);
|
||||
gl_list_free (reduced1);
|
||||
}
|
||||
else if (ready2)
|
||||
{
|
||||
gl_list_t reduced2 = reduction_step (ss, conflict2->item, 1, len2);
|
||||
gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
search_state *red2;
|
||||
while (gl_list_iterator_next (&iter2, (const void **) &red2, NULL))
|
||||
search_state *red2 = NULL;
|
||||
for (gl_list_iterator_t iter2 = gl_list_iterator (reduced2);
|
||||
search_state_list_next (&iter2, &red2);
|
||||
)
|
||||
ssb_append (red2);
|
||||
gl_list_free (reduced2);
|
||||
}
|
||||
@@ -1046,9 +1068,11 @@ unifying_example (state_item_number itm1,
|
||||
while (gl_list_size (ssb_queue) > 0)
|
||||
{
|
||||
const search_state_bundle *ssb = gl_list_get_at (ssb_queue, 0);
|
||||
gl_list_iterator_t it = gl_list_iterator (ssb->states);
|
||||
|
||||
search_state *ss = NULL;
|
||||
while (gl_list_iterator_next (&it, (const void **) &ss, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (ssb->states);
|
||||
search_state_list_next (&it, &ss);
|
||||
)
|
||||
{
|
||||
if (trace_flag & trace_cex)
|
||||
search_state_print (ss);
|
||||
@@ -1157,19 +1181,21 @@ counterexample_report (state_item_number itm1, state_item_number itm2,
|
||||
// Compute the shortest lookahead-sensitive path and associated sets of
|
||||
// parser states.
|
||||
gl_list_t shortest_path = shortest_path_from_start (itm1, next_sym);
|
||||
bool reduceProdReached = false;
|
||||
bool reduce_prod_reached = false;
|
||||
const rule *reduce_rule = item_rule (state_items[itm1].item);
|
||||
|
||||
bitset_zero (scp_set);
|
||||
bitset_zero (rpp_set);
|
||||
gl_list_iterator_t it = gl_list_iterator (shortest_path);
|
||||
|
||||
state_item *si = NULL;
|
||||
while (gl_list_iterator_next (&it, (const void **) &si, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (shortest_path);
|
||||
state_item_list_next (&it, &si);
|
||||
)
|
||||
{
|
||||
bitset_set (scp_set, si->state->number);
|
||||
reduceProdReached = reduceProdReached
|
||||
reduce_prod_reached = reduce_prod_reached
|
||||
|| item_rule (si->item) == reduce_rule;
|
||||
if (reduceProdReached)
|
||||
if (reduce_prod_reached)
|
||||
bitset_set (rpp_set, si->state->number);
|
||||
}
|
||||
time_t t = time (NULL);
|
||||
|
||||
@@ -55,9 +55,10 @@ derivation_list_prepend (derivation_list dl, derivation *d)
|
||||
|
||||
void derivation_list_free (derivation_list dl)
|
||||
{
|
||||
gl_list_iterator_t it = gl_list_iterator (dl);
|
||||
derivation *d;
|
||||
while (gl_list_iterator_next (&it, (const void **) &d, NULL))
|
||||
derivation *d = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (dl);
|
||||
derivation_list_next (&it, &d);
|
||||
)
|
||||
if (d != &d_dot)
|
||||
derivation_free (d);
|
||||
gl_list_free (dl);
|
||||
@@ -94,9 +95,10 @@ derivation_free (derivation *d)
|
||||
{
|
||||
if (deriv->children)
|
||||
{
|
||||
gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation *child;
|
||||
while (gl_list_iterator_next (&it, (const void **) &child, NULL))
|
||||
derivation *child = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
if (child != &d_dot)
|
||||
gl_list_add_last (free_queue, child);
|
||||
gl_list_free (deriv->children);
|
||||
@@ -114,9 +116,10 @@ derivation_size (const derivation *deriv)
|
||||
if (!deriv->children)
|
||||
return 1;
|
||||
int size = 1;
|
||||
gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation *child;
|
||||
while (gl_list_iterator_next (&it, (const void **) &child, NULL))
|
||||
derivation *child = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
size += derivation_size (child);
|
||||
return size;
|
||||
}
|
||||
@@ -136,10 +139,12 @@ derivation_print (const derivation *deriv, FILE *f)
|
||||
fprintf (f, " %s", sym->tag);
|
||||
return;
|
||||
}
|
||||
gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation *child;
|
||||
|
||||
fprintf (f, " %s ::=[", sym->tag);
|
||||
while (gl_list_iterator_next (&it, (const void **) &child, NULL))
|
||||
derivation *child;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
derivation_print (child, f);
|
||||
fputs (" ", f);
|
||||
@@ -162,10 +167,11 @@ derivation_print_leaves (const derivation *deriv, FILE *f)
|
||||
return;
|
||||
}
|
||||
|
||||
gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
const char *sep = "";
|
||||
derivation *child;
|
||||
while (gl_list_iterator_next (&it, (const void **) &child, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (deriv->children);
|
||||
derivation_list_next (&it, &child);
|
||||
)
|
||||
{
|
||||
fputs (sep, f);
|
||||
sep = " ";
|
||||
|
||||
@@ -37,6 +37,18 @@ static inline derivation_list derivation_list_new (void)
|
||||
return gl_list_create_empty (GL_LINKED_LIST, NULL, NULL, NULL, true);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
derivation_list_next (gl_list_iterator_t *it, derivation **d)
|
||||
{
|
||||
const void *p = NULL;
|
||||
bool res = gl_list_iterator_next (it, &p, NULL);
|
||||
if (res)
|
||||
*d = (derivation *) p;
|
||||
else
|
||||
gl_list_iterator_free (it);
|
||||
return res;
|
||||
}
|
||||
|
||||
void derivation_list_append (derivation_list dl, derivation *d);
|
||||
void derivation_list_prepend (derivation_list dl, derivation *d);
|
||||
void derivation_list_free (derivation_list dl);
|
||||
|
||||
@@ -253,10 +253,12 @@ parse_state_completed_steps (const parse_state *ps, int *shifts, int *production
|
||||
|
||||
gl_list_t sis = root_ps->state_items.contents;
|
||||
int count = 0;
|
||||
gl_list_iterator_t it = gl_list_iterator (sis);
|
||||
|
||||
state_item *last = NULL;
|
||||
state_item *next = NULL;
|
||||
while (gl_list_iterator_next (&it, (const void **) &next, NULL))
|
||||
for (gl_list_iterator_t it = gl_list_iterator (sis);
|
||||
state_item_list_next (&it, &next);
|
||||
)
|
||||
{
|
||||
if (last && last->state == next->state)
|
||||
++count;
|
||||
@@ -285,22 +287,24 @@ list_flatten_and_split (gl_list_t *list, gl_list_t *rets, int split, int n,
|
||||
int ret_array = 0;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
const void *p = NULL;
|
||||
gl_list_iterator_t it = gl_list_iterator (list[i]);
|
||||
gl_list_t l;
|
||||
while (gl_list_iterator_next (&it, (const void **) &l, NULL))
|
||||
{
|
||||
if (!l)
|
||||
continue;
|
||||
gl_list_iterator_t it2 = gl_list_iterator (l);
|
||||
void *si;
|
||||
while (gl_list_iterator_next (&it2, (const void **) &si, NULL))
|
||||
{
|
||||
if (ret_index++ == split)
|
||||
++ret_array;
|
||||
if (rets[ret_array])
|
||||
append_fn (rets[ret_array], si);
|
||||
}
|
||||
}
|
||||
while (gl_list_iterator_next (&it, &p, NULL))
|
||||
if (p)
|
||||
{
|
||||
gl_list_t l = (gl_list_t) p;
|
||||
const void *si = NULL;
|
||||
gl_list_iterator_t it2 = gl_list_iterator (l);
|
||||
while (gl_list_iterator_next (&it2, &si, NULL))
|
||||
{
|
||||
if (ret_index++ == split)
|
||||
++ret_array;
|
||||
if (rets[ret_array])
|
||||
append_fn (rets[ret_array], si);
|
||||
}
|
||||
gl_list_iterator_free (&it2);
|
||||
}
|
||||
gl_list_iterator_free (&it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,11 +544,12 @@ simulate_reduction (parse_state *ps, int rule_len, bitset symbol_set)
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_list_iterator_t it = gl_list_iterator (prev);
|
||||
state_item *psis;
|
||||
while (gl_list_iterator_next (&it, (const void **) &psis, NULL))
|
||||
state_item *psis = NULL;
|
||||
for (gl_list_iterator_t it = gl_list_iterator (prev);
|
||||
state_item_list_next (&it, &psis);
|
||||
)
|
||||
{
|
||||
//Prepend the result from the reverse production
|
||||
// Prepend the result from the reverse production.
|
||||
parse_state *copy = copy_parse_state (true, new_root);
|
||||
ps_si_prepend (copy, psis);
|
||||
|
||||
|
||||
@@ -74,6 +74,18 @@
|
||||
typedef struct parse_state parse_state;
|
||||
typedef gl_list_t parse_state_list;
|
||||
|
||||
static inline bool
|
||||
parse_state_list_next (gl_list_iterator_t *it, parse_state **ps)
|
||||
{
|
||||
const void *p = NULL;
|
||||
bool res = gl_list_iterator_next (it, &p, NULL);
|
||||
if (res)
|
||||
*ps = (parse_state *) p;
|
||||
else
|
||||
gl_list_iterator_free (it);
|
||||
return res;
|
||||
}
|
||||
|
||||
parse_state *new_parse_state (const state_item *conflict);
|
||||
|
||||
size_t parse_state_hasher (const parse_state *ps, size_t max);
|
||||
|
||||
@@ -92,4 +92,17 @@ void state_items_free (void);
|
||||
|
||||
bool production_allowed (const state_item *si, const state_item *next);
|
||||
|
||||
static inline bool
|
||||
state_item_list_next (gl_list_iterator_t *it, state_item **si)
|
||||
{
|
||||
const void *p = NULL;
|
||||
bool res = gl_list_iterator_next (it, &p, NULL);
|
||||
if (res)
|
||||
*si = (state_item *) p;
|
||||
else
|
||||
gl_list_iterator_free (it);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#endif /* STATE_ITEM_H */
|
||||
|
||||
Reference in New Issue
Block a user