mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-17 16:23:04 +00:00
Fix some memory leaks, and fix a bug: state 0 was examined twice.
* src/LR0.c (new_state): Merge into... (state_list_append): this. (new_states): Merge into... (generate_states): here. (set_states): Don't ensure a proper `errs' state member here, do it... * src/conflicts.c (conflicts_solve): here. * src/state.h, src/state.c: Comment changes. (state_t): Rename member `shifts' as `transitions'. Adjust all dependencies. (errs_new): For consistency, also take the values as argument. (errs_dup): Remove. (state_errs_set): New. (state_reductions_set, state_transitions_set): Assert that no previous value was assigned. (state_free): New. (states_free): Use it. * src/conflicts.c (resolve_sr_conflict): Don't use an `errs_t' as temporary storage: use `errs' and `nerrs' as elsewhere. (set_conflicts): Allocate and free this `errs'.
This commit is contained in:
24
ChangeLog
24
ChangeLog
@@ -1,3 +1,27 @@
|
|||||||
|
2002-07-03 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
|
Fix some memory leaks, and fix a bug: state 0 was examined twice.
|
||||||
|
|
||||||
|
* src/LR0.c (new_state): Merge into...
|
||||||
|
(state_list_append): this.
|
||||||
|
(new_states): Merge into...
|
||||||
|
(generate_states): here.
|
||||||
|
(set_states): Don't ensure a proper `errs' state member here, do it...
|
||||||
|
* src/conflicts.c (conflicts_solve): here.
|
||||||
|
* src/state.h, src/state.c: Comment changes.
|
||||||
|
(state_t): Rename member `shifts' as `transitions'.
|
||||||
|
Adjust all dependencies.
|
||||||
|
(errs_new): For consistency, also take the values as argument.
|
||||||
|
(errs_dup): Remove.
|
||||||
|
(state_errs_set): New.
|
||||||
|
(state_reductions_set, state_transitions_set): Assert that no
|
||||||
|
previous value was assigned.
|
||||||
|
(state_free): New.
|
||||||
|
(states_free): Use it.
|
||||||
|
* src/conflicts.c (resolve_sr_conflict): Don't use an `errs_t' as
|
||||||
|
temporary storage: use `errs' and `nerrs' as elsewhere.
|
||||||
|
(set_conflicts): Allocate and free this `errs'.
|
||||||
|
|
||||||
2002-07-02 Akim Demaille <akim@epita.fr>
|
2002-07-02 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
* lib/libiberty.h: New.
|
* lib/libiberty.h: New.
|
||||||
|
|||||||
81
src/LR0.c
81
src/LR0.c
@@ -46,10 +46,28 @@ typedef struct state_list_s
|
|||||||
static state_list_t *first_state = NULL;
|
static state_list_t *first_state = NULL;
|
||||||
static state_list_t *last_state = NULL;
|
static state_list_t *last_state = NULL;
|
||||||
|
|
||||||
static void
|
|
||||||
state_list_append (state_t *state)
|
/*------------------------------------------------------------------.
|
||||||
|
| A state was just discovered from another state. Queue it for |
|
||||||
|
| later examination, in order to find its transitions. Return it. |
|
||||||
|
`------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static state_t *
|
||||||
|
state_list_append (symbol_number_t symbol,
|
||||||
|
size_t core_size, item_number_t *core)
|
||||||
{
|
{
|
||||||
state_list_t *node = XMALLOC (state_list_t, 1);
|
state_list_t *node = XMALLOC (state_list_t, 1);
|
||||||
|
state_t *state = state_new (symbol, core_size, core);
|
||||||
|
|
||||||
|
if (trace_flag)
|
||||||
|
fprintf (stderr, "state_list_append (state = %d, symbol = %d (%s))\n",
|
||||||
|
nstates, symbol, symbols[symbol]->tag);
|
||||||
|
|
||||||
|
/* If this is the eoftoken, and this is not the initial state, then
|
||||||
|
this is the final state. */
|
||||||
|
if (symbol == 0 && first_state)
|
||||||
|
final_state = state;
|
||||||
|
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
node->state = state;
|
node->state = state;
|
||||||
|
|
||||||
@@ -58,6 +76,8 @@ state_list_append (state_t *state)
|
|||||||
if (last_state)
|
if (last_state)
|
||||||
last_state->next = node;
|
last_state->next = node;
|
||||||
last_state = node;
|
last_state = node;
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nshifts;
|
static int nshifts;
|
||||||
@@ -184,33 +204,6 @@ new_itemsets (state_t *state)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------.
|
|
||||||
| Subroutine of get_state. Create a new state for those items, if |
|
|
||||||
| necessary. |
|
|
||||||
`-----------------------------------------------------------------*/
|
|
||||||
|
|
||||||
static state_t *
|
|
||||||
new_state (symbol_number_t symbol, size_t core_size, item_number_t *core)
|
|
||||||
{
|
|
||||||
state_t *res;
|
|
||||||
|
|
||||||
if (trace_flag)
|
|
||||||
fprintf (stderr, "Entering new_state, state = %d, symbol = %d (%s)\n",
|
|
||||||
nstates, symbol, symbols[symbol]->tag);
|
|
||||||
|
|
||||||
res = state_new (symbol, core_size, core);
|
|
||||||
state_hash_insert (res);
|
|
||||||
|
|
||||||
/* If this is the eoftoken, and this is not the initial state, then
|
|
||||||
this is the final state. */
|
|
||||||
if (symbol == 0 && first_state)
|
|
||||||
final_state = res;
|
|
||||||
|
|
||||||
state_list_append (res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------.
|
/*--------------------------------------------------------------.
|
||||||
| Find the state number for the state we would get to (from the |
|
| Find the state number for the state we would get to (from the |
|
||||||
| current state) by shifting symbol. Create a new state if no |
|
| current state) by shifting symbol. Create a new state if no |
|
||||||
@@ -228,7 +221,7 @@ get_state (symbol_number_t symbol, size_t core_size, item_number_t *core)
|
|||||||
|
|
||||||
sp = state_hash_lookup (core_size, core);
|
sp = state_hash_lookup (core_size, core);
|
||||||
if (!sp)
|
if (!sp)
|
||||||
sp = new_state (symbol, core_size, core);
|
sp = state_list_append (symbol, core_size, core);
|
||||||
|
|
||||||
if (trace_flag)
|
if (trace_flag)
|
||||||
fprintf (stderr, "Exiting get_state => %d\n", sp->number);
|
fprintf (stderr, "Exiting get_state => %d\n", sp->number);
|
||||||
@@ -277,17 +270,6 @@ append_states (state_t *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
new_states (void)
|
|
||||||
{
|
|
||||||
/* The 0 at the lhs is the index of the item of this initial rule. */
|
|
||||||
kernel_base[0][0] = 0;
|
|
||||||
kernel_size[0] = 1;
|
|
||||||
state_list_append (new_state (0, kernel_size[0], kernel_base[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------.
|
/*----------------------------------------------------------------.
|
||||||
| Find which rules can be used for reduction transitions from the |
|
| Find which rules can be used for reduction transitions from the |
|
||||||
| current state and make a reductions structure for the state to |
|
| current state and make a reductions structure for the state to |
|
||||||
@@ -332,13 +314,12 @@ set_states (void)
|
|||||||
state_list_t *this = first_state;
|
state_list_t *this = first_state;
|
||||||
|
|
||||||
/* Pessimization, but simplification of the code: make sure all
|
/* Pessimization, but simplification of the code: make sure all
|
||||||
the states have a shifts, errs, and reductions, even if
|
the states have valid transitions and reductions members,
|
||||||
reduced to 0. */
|
even if reduced to 0. It is too soon for errs, which are
|
||||||
|
computed later, but set_conflicts. */
|
||||||
state_t *state = this->state;
|
state_t *state = this->state;
|
||||||
if (!state->shifts)
|
if (!state->transitions)
|
||||||
state_transitions_set (state, 0, 0);
|
state_transitions_set (state, 0, 0);
|
||||||
if (!state->errs)
|
|
||||||
state->errs = errs_new (0);
|
|
||||||
if (!state->reductions)
|
if (!state->reductions)
|
||||||
state_reductions_set (state, 0, 0);
|
state_reductions_set (state, 0, 0);
|
||||||
|
|
||||||
@@ -363,7 +344,13 @@ generate_states (void)
|
|||||||
state_list_t *list = NULL;
|
state_list_t *list = NULL;
|
||||||
allocate_storage ();
|
allocate_storage ();
|
||||||
new_closure (nritems);
|
new_closure (nritems);
|
||||||
new_states ();
|
|
||||||
|
/* Create the initial state. The 0 at the lhs is the index of the
|
||||||
|
item of this initial rule. */
|
||||||
|
kernel_base[0][0] = 0;
|
||||||
|
kernel_size[0] = 1;
|
||||||
|
state_list_append (0, kernel_size[0], kernel_base[0]);
|
||||||
|
|
||||||
list = first_state;
|
list = first_state;
|
||||||
|
|
||||||
while (list)
|
while (list)
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ log_resolution (rule_t *rule, symbol_number_t token,
|
|||||||
static void
|
static void
|
||||||
flush_shift (state_t *state, int token)
|
flush_shift (state_t *state, int token)
|
||||||
{
|
{
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
bitset_reset (lookaheadset, token);
|
bitset_reset (lookaheadset, token);
|
||||||
@@ -170,18 +170,20 @@ flush_reduce (bitset lookaheads, int token)
|
|||||||
| shift or reduce tables so that there is no longer a conflict. |
|
| shift or reduce tables so that there is no longer a conflict. |
|
||||||
| |
|
| |
|
||||||
| LOOKAHEAD is the number of the lookahead bitset to consider. |
|
| LOOKAHEAD is the number of the lookahead bitset to consider. |
|
||||||
|
| |
|
||||||
|
| ERRS can be used to store discovered explicit errors. |
|
||||||
`------------------------------------------------------------------*/
|
`------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
resolve_sr_conflict (state_t *state, int lookahead)
|
resolve_sr_conflict (state_t *state, int lookahead,
|
||||||
|
symbol_number_t *errs)
|
||||||
{
|
{
|
||||||
symbol_number_t i;
|
symbol_number_t i;
|
||||||
/* Find the rule to reduce by to get precedence of reduction. */
|
/* Find the rule to reduce by to get precedence of reduction. */
|
||||||
rule_t *redrule = state->lookaheads_rule[lookahead];
|
rule_t *redrule = state->lookaheads_rule[lookahead];
|
||||||
int redprec = redrule->prec->prec;
|
int redprec = redrule->prec->prec;
|
||||||
bitset lookaheads = state->lookaheads[lookahead];
|
bitset lookaheads = state->lookaheads[lookahead];
|
||||||
errs_t *errp = errs_new (ntokens + 1);
|
int nerrs = 0;
|
||||||
errp->num = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < ntokens; i++)
|
for (i = 0; i < ntokens; i++)
|
||||||
if (bitset_test (lookaheads, i)
|
if (bitset_test (lookaheads, i)
|
||||||
@@ -224,7 +226,7 @@ resolve_sr_conflict (state_t *state, int lookahead)
|
|||||||
flush_shift (state, i);
|
flush_shift (state, i);
|
||||||
flush_reduce (lookaheads, i);
|
flush_reduce (lookaheads, i);
|
||||||
/* Record an explicit error for this token. */
|
/* Record an explicit error for this token. */
|
||||||
errp->symbols[errp->num++] = i;
|
errs[nerrs++] = i;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case undef_assoc:
|
case undef_assoc:
|
||||||
@@ -235,8 +237,7 @@ resolve_sr_conflict (state_t *state, int lookahead)
|
|||||||
|
|
||||||
/* Some tokens have been explicitly made errors. Allocate a
|
/* Some tokens have been explicitly made errors. Allocate a
|
||||||
permanent errs structure for this state, to record them. */
|
permanent errs structure for this state, to record them. */
|
||||||
state->errs = errs_dup (errp);
|
state_errs_set (state, nerrs, errs);
|
||||||
free (errp);
|
|
||||||
|
|
||||||
if (obstack_object_size (&solved_conflicts_obstack))
|
if (obstack_object_size (&solved_conflicts_obstack))
|
||||||
{
|
{
|
||||||
@@ -246,18 +247,24 @@ resolve_sr_conflict (state_t *state, int lookahead)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------.
|
||||||
|
| Solve the S/R conflicts of STATE using the |
|
||||||
|
| precedence/associativity, and flag it inconsistent if it still has |
|
||||||
|
| conflicts. ERRS can be used as storage to compute the list of |
|
||||||
|
| lookaheads on which this STATE raises a parse error (%nonassoc). |
|
||||||
|
`-------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_conflicts (state_t *state)
|
set_conflicts (state_t *state, symbol_number_t *errs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
transitions_t *transitions;
|
transitions_t *transitions = state->transitions;
|
||||||
|
|
||||||
if (state->consistent)
|
if (state->consistent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bitset_zero (lookaheadset);
|
bitset_zero (lookaheadset);
|
||||||
|
|
||||||
transitions = state->shifts;
|
|
||||||
for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
|
for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
|
||||||
if (!TRANSITION_IS_DISABLED (transitions, i))
|
if (!TRANSITION_IS_DISABLED (transitions, i))
|
||||||
bitset_set (lookaheadset, TRANSITION_SYMBOL (transitions, i));
|
bitset_set (lookaheadset, TRANSITION_SYMBOL (transitions, i));
|
||||||
@@ -270,7 +277,7 @@ set_conflicts (state_t *state)
|
|||||||
&& state->lookaheads_rule[i]->prec->prec
|
&& state->lookaheads_rule[i]->prec->prec
|
||||||
&& !bitset_disjoint_p (state->lookaheads[i], lookaheadset))
|
&& !bitset_disjoint_p (state->lookaheads[i], lookaheadset))
|
||||||
{
|
{
|
||||||
resolve_sr_conflict (state, i);
|
resolve_sr_conflict (state, i, errs);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,10 +292,18 @@ set_conflicts (state_t *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------.
|
||||||
|
| Solve all the S/R conflicts using the precedence/associativity, |
|
||||||
|
| and flag as inconsistent the states that still have conflicts. |
|
||||||
|
`----------------------------------------------------------------*/
|
||||||
|
|
||||||
void
|
void
|
||||||
conflicts_solve (void)
|
conflicts_solve (void)
|
||||||
{
|
{
|
||||||
state_number_t i;
|
state_number_t i;
|
||||||
|
/* List of lookaheads on which we explicitly raise a parse error. */
|
||||||
|
symbol_number_t *errs = XMALLOC (symbol_number_t, ntokens + 1);
|
||||||
|
|
||||||
conflicts = XCALLOC (char, nstates);
|
conflicts = XCALLOC (char, nstates);
|
||||||
shiftset = bitset_create (ntokens, BITSET_FIXED);
|
shiftset = bitset_create (ntokens, BITSET_FIXED);
|
||||||
@@ -296,7 +311,16 @@ conflicts_solve (void)
|
|||||||
obstack_init (&solved_conflicts_obstack);
|
obstack_init (&solved_conflicts_obstack);
|
||||||
|
|
||||||
for (i = 0; i < nstates; i++)
|
for (i = 0; i < nstates; i++)
|
||||||
set_conflicts (states[i]);
|
{
|
||||||
|
set_conflicts (states[i], errs);
|
||||||
|
|
||||||
|
/* For uniformity of the code, make sure all the states have a valid
|
||||||
|
`errs' member. */
|
||||||
|
if (!states[i]->errs)
|
||||||
|
states[i]->errs = errs_new (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
free (errs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,7 +333,7 @@ count_sr_conflicts (state_t *state)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int src_count = 0;
|
int src_count = 0;
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
|
|
||||||
if (!transitions)
|
if (!transitions)
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
12
src/lalr.c
12
src/lalr.c
@@ -94,7 +94,7 @@ set_goto_map (void)
|
|||||||
ngotos = 0;
|
ngotos = 0;
|
||||||
for (state = 0; state < nstates; ++state)
|
for (state = 0; state < nstates; ++state)
|
||||||
{
|
{
|
||||||
transitions_t *sp = states[state]->shifts;
|
transitions_t *sp = states[state]->transitions;
|
||||||
int i;
|
int i;
|
||||||
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
|
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
|
||||||
{
|
{
|
||||||
@@ -127,7 +127,7 @@ set_goto_map (void)
|
|||||||
|
|
||||||
for (state = 0; state < nstates; ++state)
|
for (state = 0; state < nstates; ++state)
|
||||||
{
|
{
|
||||||
transitions_t *sp = states[state]->shifts;
|
transitions_t *sp = states[state]->transitions;
|
||||||
int i;
|
int i;
|
||||||
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
|
for (i = sp->num - 1; i >= 0 && TRANSITION_IS_GOTO (sp, i); --i)
|
||||||
{
|
{
|
||||||
@@ -189,7 +189,7 @@ initialize_F (void)
|
|||||||
for (i = 0; i < ngotos; i++)
|
for (i = 0; i < ngotos; i++)
|
||||||
{
|
{
|
||||||
state_number_t stateno = to_state[i];
|
state_number_t stateno = to_state[i];
|
||||||
transitions_t *sp = states[stateno]->shifts;
|
transitions_t *sp = states[stateno]->transitions;
|
||||||
|
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < sp->num && TRANSITION_IS_SHIFT (sp, j); j++)
|
for (j = 0; j < sp->num && TRANSITION_IS_SHIFT (sp, j); j++)
|
||||||
@@ -266,8 +266,8 @@ build_relations (void)
|
|||||||
|
|
||||||
for (rp = rules[*rulep].rhs; *rp >= 0; rp++)
|
for (rp = rules[*rulep].rhs; *rp >= 0; rp++)
|
||||||
{
|
{
|
||||||
state = transitions_to (state->shifts,
|
state = transitions_to (state->transitions,
|
||||||
item_number_as_symbol_number (*rp));
|
item_number_as_symbol_number (*rp));
|
||||||
states1[length++] = state->number;
|
states1[length++] = state->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +360,7 @@ states_lookaheads_count (void)
|
|||||||
int k;
|
int k;
|
||||||
int nlookaheads = 0;
|
int nlookaheads = 0;
|
||||||
reductions_t *rp = states[i]->reductions;
|
reductions_t *rp = states[i]->reductions;
|
||||||
transitions_t *sp = states[i]->shifts;
|
transitions_t *sp = states[i]->transitions;
|
||||||
|
|
||||||
/* We need a lookahead either to distinguish different
|
/* We need a lookahead either to distinguish different
|
||||||
reductions (i.e., there are two or more), or to distinguish a
|
reductions (i.e., there are two or more), or to distinguish a
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ action_row (state_t *state)
|
|||||||
int i;
|
int i;
|
||||||
rule_number_t default_rule = 0;
|
rule_number_t default_rule = 0;
|
||||||
reductions_t *redp = state->reductions;
|
reductions_t *redp = state->reductions;
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
errs_t *errp = state->errs;
|
errs_t *errp = state->errs;
|
||||||
/* set nonzero to inhibit having any default reduction */
|
/* set nonzero to inhibit having any default reduction */
|
||||||
int nodefault = 0;
|
int nodefault = 0;
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ print_core (FILE *out, state_t *state)
|
|||||||
static void
|
static void
|
||||||
print_transitions (state_t *state, FILE *out, bool display_transitions_p)
|
print_transitions (state_t *state, FILE *out, bool display_transitions_p)
|
||||||
{
|
{
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
size_t width = 0;
|
size_t width = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ state_default_rule (state_t *state)
|
|||||||
we shift (S/R conflicts)... */
|
we shift (S/R conflicts)... */
|
||||||
bitset_zero (shiftset);
|
bitset_zero (shiftset);
|
||||||
{
|
{
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
|
for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
|
||||||
if (!TRANSITION_IS_DISABLED (transitions, i))
|
if (!TRANSITION_IS_DISABLED (transitions, i))
|
||||||
{
|
{
|
||||||
@@ -302,7 +302,7 @@ print_reduction (FILE *out, size_t width,
|
|||||||
static void
|
static void
|
||||||
print_reductions (FILE *out, state_t *state)
|
print_reductions (FILE *out, state_t *state)
|
||||||
{
|
{
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
reductions_t *redp = state->reductions;
|
reductions_t *redp = state->reductions;
|
||||||
rule_t *default_rule = NULL;
|
rule_t *default_rule = NULL;
|
||||||
size_t width = 0;
|
size_t width = 0;
|
||||||
@@ -396,7 +396,7 @@ static void
|
|||||||
print_actions (FILE *out, state_t *state)
|
print_actions (FILE *out, state_t *state)
|
||||||
{
|
{
|
||||||
reductions_t *redp = state->reductions;
|
reductions_t *redp = state->reductions;
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
|
|
||||||
if (transitions->num == 0 && redp->num == 0)
|
if (transitions->num == 0 && redp->num == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ print_actions (state_t *state, const char *node_name)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
transitions_t *transitions = state->shifts;
|
transitions_t *transitions = state->transitions;
|
||||||
reductions_t *redp = state->reductions;
|
reductions_t *redp = state->reductions;
|
||||||
|
|
||||||
static char buff[10];
|
static char buff[10];
|
||||||
|
|||||||
97
src/state.c
97
src/state.c
@@ -74,25 +74,17 @@ transitions_to (transitions_t *shifts, symbol_number_t s)
|
|||||||
| Create a new array of N errs. |
|
| Create a new array of N errs. |
|
||||||
`-------------------------------*/
|
`-------------------------------*/
|
||||||
|
|
||||||
#define ERRS_ALLOC(Nerrs) \
|
#define ERRS_ALLOC(Nerrs) \
|
||||||
(errs_t *) xcalloc ((unsigned) (sizeof (errs_t) \
|
(errs_t *) xcalloc ((sizeof (errs_t) \
|
||||||
+ (Nerrs - 1) * sizeof (symbol_number_t)), 1)
|
+ (Nerrs - 1) * sizeof (symbol_number_t)), 1)
|
||||||
|
|
||||||
|
|
||||||
errs_t *
|
errs_t *
|
||||||
errs_new (int n)
|
errs_new (int num, symbol_number_t *tokens)
|
||||||
{
|
{
|
||||||
errs_t *res = ERRS_ALLOC (n);
|
errs_t *res = ERRS_ALLOC (num);
|
||||||
res->num = n;
|
res->num = num;
|
||||||
return res;
|
memcpy (res->symbols, tokens, num * sizeof (tokens[0]));
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
errs_t *
|
|
||||||
errs_dup (errs_t *src)
|
|
||||||
{
|
|
||||||
errs_t *res = errs_new (src->num);
|
|
||||||
memcpy (res->symbols, src->symbols, src->num * sizeof (src->symbols[0]));
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,16 +100,16 @@ errs_dup (errs_t *src)
|
|||||||
| Create a new array of N reductions. |
|
| Create a new array of N reductions. |
|
||||||
`-------------------------------------*/
|
`-------------------------------------*/
|
||||||
|
|
||||||
#define REDUCTIONS_ALLOC(Nreductions) \
|
#define REDUCTIONS_ALLOC(Nreductions) \
|
||||||
(reductions_t *) xcalloc ((unsigned) (sizeof (reductions_t) \
|
(reductions_t *) xcalloc ((sizeof (reductions_t) \
|
||||||
+ (Nreductions - 1) * sizeof (rule_number_t)), 1)
|
+ (Nreductions - 1) * sizeof (rule_number_t)), 1)
|
||||||
|
|
||||||
static reductions_t *
|
static reductions_t *
|
||||||
reductions_new (int nreductions, short *reductions)
|
reductions_new (int num, rule_number_t *reductions)
|
||||||
{
|
{
|
||||||
reductions_t *res = REDUCTIONS_ALLOC (nreductions);
|
reductions_t *res = REDUCTIONS_ALLOC (num);
|
||||||
res->num = nreductions;
|
res->num = num;
|
||||||
memcpy (res->rules, reductions, nreductions * sizeof (reductions[0]));
|
memcpy (res->rules, reductions, num * sizeof (reductions[0]));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,9 +129,10 @@ state_t *final_state = NULL;
|
|||||||
(state_t *) xcalloc ((unsigned) (sizeof (state_t) \
|
(state_t *) xcalloc ((unsigned) (sizeof (state_t) \
|
||||||
+ (Nitems - 1) * sizeof (item_number_t)), 1)
|
+ (Nitems - 1) * sizeof (item_number_t)), 1)
|
||||||
|
|
||||||
/*------------------------------------------------------------.
|
/*------------------------------------------------------------------.
|
||||||
| Create a new state with ACCESSING_SYMBOL, for those items. |
|
| Create a new state with ACCESSING_SYMBOL, for those items. Store |
|
||||||
`------------------------------------------------------------*/
|
| it in the state hash table. |
|
||||||
|
`------------------------------------------------------------------*/
|
||||||
|
|
||||||
state_t *
|
state_t *
|
||||||
state_new (symbol_number_t accessing_symbol,
|
state_new (symbol_number_t accessing_symbol,
|
||||||
@@ -159,18 +152,35 @@ state_new (symbol_number_t accessing_symbol,
|
|||||||
res->nitems = core_size;
|
res->nitems = core_size;
|
||||||
memcpy (res->items, core, core_size * sizeof (core[0]));
|
memcpy (res->items, core, core_size * sizeof (core[0]));
|
||||||
|
|
||||||
|
state_hash_insert (res);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------.
|
/*-------------.
|
||||||
| Set the shifts of STATE. |
|
| Free STATE. |
|
||||||
`--------------------------*/
|
`-------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
state_free (state_t *state)
|
||||||
|
{
|
||||||
|
free (state->transitions);
|
||||||
|
free (state->reductions);
|
||||||
|
free (state->errs);
|
||||||
|
free (state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------.
|
||||||
|
| Set the transitions of STATE. |
|
||||||
|
`-------------------------------*/
|
||||||
|
|
||||||
void
|
void
|
||||||
state_transitions_set (state_t *state, int nshifts, state_number_t *shifts)
|
state_transitions_set (state_t *state, int num, state_number_t *transitions)
|
||||||
{
|
{
|
||||||
state->shifts = transitions_new (nshifts, shifts);
|
assert (!state->transitions);
|
||||||
|
state->transitions = transitions_new (num, transitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -179,9 +189,22 @@ state_transitions_set (state_t *state, int nshifts, state_number_t *shifts)
|
|||||||
`------------------------------*/
|
`------------------------------*/
|
||||||
|
|
||||||
void
|
void
|
||||||
state_reductions_set (state_t *state, int nreductions, short *reductions)
|
state_reductions_set (state_t *state, int num, rule_number_t *reductions)
|
||||||
{
|
{
|
||||||
state->reductions = reductions_new (nreductions, reductions);
|
assert (!state->reductions);
|
||||||
|
state->reductions = reductions_new (num, reductions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------.
|
||||||
|
| Set the errs of STATE. |
|
||||||
|
`------------------------*/
|
||||||
|
|
||||||
|
void
|
||||||
|
state_errs_set (state_t *state, int num, symbol_number_t *tokens)
|
||||||
|
{
|
||||||
|
assert (!state->errs);
|
||||||
|
state->errs = errs_new (num, tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -322,13 +345,7 @@ void
|
|||||||
states_free (void)
|
states_free (void)
|
||||||
{
|
{
|
||||||
state_number_t i;
|
state_number_t i;
|
||||||
|
|
||||||
for (i = 0; i < nstates; ++i)
|
for (i = 0; i < nstates; ++i)
|
||||||
{
|
state_free (states[i]);
|
||||||
free (states[i]->shifts);
|
free (states);
|
||||||
XFREE (states[i]->reductions);
|
|
||||||
free (states[i]->errs);
|
|
||||||
free (states[i]);
|
|
||||||
}
|
|
||||||
XFREE (states);
|
|
||||||
}
|
}
|
||||||
|
|||||||
91
src/state.h
91
src/state.h
@@ -44,21 +44,21 @@
|
|||||||
Each core contains a vector of NITEMS items which are the indices
|
Each core contains a vector of NITEMS items which are the indices
|
||||||
in the RITEMS vector of the items that are selected in this state.
|
in the RITEMS vector of the items that are selected in this state.
|
||||||
|
|
||||||
The two types of transitions are shifts (push the lookahead token
|
The two types of actions are shifts/gotos (push the lookahead token
|
||||||
and read another) and reductions (combine the last n things on the
|
and read another/goto to the state designated by a nterm) and
|
||||||
stack via a rule, replace them with the symbol that the rule
|
reductions (combine the last n things on the stack via a rule,
|
||||||
derives, and leave the lookahead token alone). When the states are
|
replace them with the symbol that the rule derives, and leave the
|
||||||
generated, these transitions are represented in two other lists.
|
lookahead token alone). When the states are generated, these
|
||||||
|
actions are represented in two other lists.
|
||||||
|
|
||||||
Each shifts structure describes the possible shift transitions out
|
Each transition_t structure describes the possible transitions out
|
||||||
of one state, the state whose number is in the number field. The
|
of one state, the state whose number is in the number field. Each
|
||||||
shifts structures are linked through next and first_shift points to
|
contains a vector of numbers of the states that transitions can go
|
||||||
them. Each contains a vector of numbers of the states that shift
|
to. The accessing_symbol fields of those states' cores say what
|
||||||
transitions can go to. The accessing_symbol fields of those
|
kind of input leads to them.
|
||||||
states' cores say what kind of input leads to them.
|
|
||||||
|
|
||||||
A shift to state zero should be ignored. Conflict resolution
|
A transition to state zero should be ignored: conflict resolution
|
||||||
deletes shifts by changing them to zero.
|
deletes transitions by having them point to zero.
|
||||||
|
|
||||||
Each reductions structure describes the possible reductions at the
|
Each reductions structure describes the possible reductions at the
|
||||||
state whose number is in the number field. The data is a list of
|
state whose number is in the number field. The data is a list of
|
||||||
@@ -68,18 +68,16 @@
|
|||||||
Conflict resolution can decide that certain tokens in certain
|
Conflict resolution can decide that certain tokens in certain
|
||||||
states should explicitly be errors (for implementing %nonassoc).
|
states should explicitly be errors (for implementing %nonassoc).
|
||||||
For each state, the tokens that are errors for this reason are
|
For each state, the tokens that are errors for this reason are
|
||||||
recorded in an errs structure, which has the state number in its
|
recorded in an errs structure, which holds the token numbers.
|
||||||
number field. The rest of the errs structure is full of token
|
|
||||||
numbers.
|
|
||||||
|
|
||||||
There is at least one shift transition present in state zero. It
|
There is at least one goto transition present in state zero. It
|
||||||
leads to a next-to-final state whose accessing_symbol is the
|
leads to a next-to-final state whose accessing_symbol is the
|
||||||
grammar's start symbol. The next-to-final state has one shift to
|
grammar's start symbol. The next-to-final state has one shift to
|
||||||
the final state, whose accessing_symbol is zero (end of input).
|
the final state, whose accessing_symbol is zero (end of input).
|
||||||
The final state has one shift, which goes to the termination state
|
The final state has one shift, which goes to the termination state.
|
||||||
(whose number is nstates-1). The reason for the extra state at the
|
The reason for the extra state at the end is to placate the
|
||||||
end is to placate the parser's strategy of making all decisions one
|
parser's strategy of making all decisions one token ahead of its
|
||||||
token ahead of its actions. */
|
actions. */
|
||||||
|
|
||||||
#ifndef STATE_H_
|
#ifndef STATE_H_
|
||||||
# define STATE_H_
|
# define STATE_H_
|
||||||
@@ -108,36 +106,36 @@ typedef struct transtion_s
|
|||||||
} transitions_t;
|
} transitions_t;
|
||||||
|
|
||||||
|
|
||||||
/* What is the symbol which is shifted by TRANSITIONS->states[Shift]? Can
|
/* What is the symbol labelling the transition to
|
||||||
be a token (amongst which the error token), or non terminals in
|
TRANSITIONS->states[Num]? Can be a token (amongst which the error
|
||||||
case of gotos. */
|
token), or non terminals in case of gotos. */
|
||||||
|
|
||||||
#define TRANSITION_SYMBOL(Transitions, Shift) \
|
#define TRANSITION_SYMBOL(Transitions, Num) \
|
||||||
(states[Transitions->states[Shift]]->accessing_symbol)
|
(states[Transitions->states[Num]]->accessing_symbol)
|
||||||
|
|
||||||
/* Is the TRANSITIONS->states[Shift] a real shift? (as opposed to gotos.) */
|
/* Is the TRANSITIONS->states[Num] a shift? (as opposed to gotos). */
|
||||||
|
|
||||||
#define TRANSITION_IS_SHIFT(Transitions, Shift) \
|
#define TRANSITION_IS_SHIFT(Transitions, Num) \
|
||||||
(ISTOKEN (TRANSITION_SYMBOL (Transitions, Shift)))
|
(ISTOKEN (TRANSITION_SYMBOL (Transitions, Num)))
|
||||||
|
|
||||||
/* Is the TRANSITIONS->states[Shift] a goto?. */
|
/* Is the TRANSITIONS->states[Num] a goto?. */
|
||||||
|
|
||||||
#define TRANSITION_IS_GOTO(Transitions, Shift) \
|
#define TRANSITION_IS_GOTO(Transitions, Num) \
|
||||||
(!TRANSITION_IS_SHIFT (Transitions, Shift))
|
(!TRANSITION_IS_SHIFT (Transitions, Num))
|
||||||
|
|
||||||
/* Is the TRANSITIONS->states[Shift] then handling of the error token?. */
|
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
|
||||||
|
|
||||||
#define TRANSITION_IS_ERROR(Transitions, Shift) \
|
#define TRANSITION_IS_ERROR(Transitions, Num) \
|
||||||
(TRANSITION_SYMBOL (Transitions, Shift) == errtoken->number)
|
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
|
||||||
|
|
||||||
/* When resolving a SR conflicts, if the reduction wins, the shift is
|
/* When resolving a SR conflicts, if the reduction wins, the shift is
|
||||||
disabled. */
|
disabled. */
|
||||||
|
|
||||||
#define TRANSITION_DISABLE(Transitions, Shift) \
|
#define TRANSITION_DISABLE(Transitions, Num) \
|
||||||
(Transitions->states[Shift] = 0)
|
(Transitions->states[Num] = 0)
|
||||||
|
|
||||||
#define TRANSITION_IS_DISABLED(Transitions, Shift) \
|
#define TRANSITION_IS_DISABLED(Transitions, Num) \
|
||||||
(Transitions->states[Shift] == 0)
|
(Transitions->states[Num] == 0)
|
||||||
|
|
||||||
/* Return the state such these TRANSITIONS contain a shift/goto to it on
|
/* Return the state such these TRANSITIONS contain a shift/goto to it on
|
||||||
SYMBOL. Aborts if none found. */
|
SYMBOL. Aborts if none found. */
|
||||||
@@ -156,8 +154,7 @@ typedef struct errs_s
|
|||||||
symbol_number_t symbols[1];
|
symbol_number_t symbols[1];
|
||||||
} errs_t;
|
} errs_t;
|
||||||
|
|
||||||
errs_t *errs_new PARAMS ((int n));
|
errs_t *errs_new PARAMS ((int num, symbol_number_t *tokens));
|
||||||
errs_t *errs_dup PARAMS ((errs_t *src));
|
|
||||||
|
|
||||||
|
|
||||||
/*-------------.
|
/*-------------.
|
||||||
@@ -180,7 +177,7 @@ typedef struct state_s
|
|||||||
{
|
{
|
||||||
state_number_t number;
|
state_number_t number;
|
||||||
symbol_number_t accessing_symbol;
|
symbol_number_t accessing_symbol;
|
||||||
transitions_t *shifts;
|
transitions_t *transitions;
|
||||||
reductions_t *reductions;
|
reductions_t *reductions;
|
||||||
errs_t *errs;
|
errs_t *errs;
|
||||||
|
|
||||||
@@ -215,13 +212,17 @@ extern state_t *final_state;
|
|||||||
state_t *state_new PARAMS ((symbol_number_t accessing_symbol,
|
state_t *state_new PARAMS ((symbol_number_t accessing_symbol,
|
||||||
size_t core_size, item_number_t *core));
|
size_t core_size, item_number_t *core));
|
||||||
|
|
||||||
/* Set the shifts of STATE. */
|
/* Set the transitions of STATE. */
|
||||||
void state_transitions_set PARAMS ((state_t *state,
|
void state_transitions_set PARAMS ((state_t *state,
|
||||||
int nshifts, state_number_t *shifts));
|
int num, state_number_t *transitions));
|
||||||
|
|
||||||
/* Set the reductions of STATE. */
|
/* Set the reductions of STATE. */
|
||||||
void state_reductions_set PARAMS ((state_t *state,
|
void state_reductions_set PARAMS ((state_t *state,
|
||||||
int nreductions, short *reductions));
|
int num, rule_number_t *reductions));
|
||||||
|
|
||||||
|
/* Set the errs of STATE. */
|
||||||
|
void state_errs_set PARAMS ((state_t *state,
|
||||||
|
int num, symbol_number_t *errs));
|
||||||
|
|
||||||
/* Print on OUT all the lookaheads such that this STATE wants to
|
/* Print on OUT all the lookaheads such that this STATE wants to
|
||||||
reduce this RULE. */
|
reduce this RULE. */
|
||||||
|
|||||||
Reference in New Issue
Block a user