mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +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>
|
||||
|
||||
* 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 *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_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->state = state;
|
||||
|
||||
@@ -58,6 +76,8 @@ state_list_append (state_t *state)
|
||||
if (last_state)
|
||||
last_state->next = node;
|
||||
last_state = node;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
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 |
|
||||
| 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);
|
||||
if (!sp)
|
||||
sp = new_state (symbol, core_size, core);
|
||||
sp = state_list_append (symbol, core_size, core);
|
||||
|
||||
if (trace_flag)
|
||||
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 |
|
||||
| current state and make a reductions structure for the state to |
|
||||
@@ -332,13 +314,12 @@ set_states (void)
|
||||
state_list_t *this = first_state;
|
||||
|
||||
/* Pessimization, but simplification of the code: make sure all
|
||||
the states have a shifts, errs, and reductions, even if
|
||||
reduced to 0. */
|
||||
the states have valid transitions and reductions members,
|
||||
even if reduced to 0. It is too soon for errs, which are
|
||||
computed later, but set_conflicts. */
|
||||
state_t *state = this->state;
|
||||
if (!state->shifts)
|
||||
if (!state->transitions)
|
||||
state_transitions_set (state, 0, 0);
|
||||
if (!state->errs)
|
||||
state->errs = errs_new (0);
|
||||
if (!state->reductions)
|
||||
state_reductions_set (state, 0, 0);
|
||||
|
||||
@@ -363,7 +344,13 @@ generate_states (void)
|
||||
state_list_t *list = NULL;
|
||||
allocate_storage ();
|
||||
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;
|
||||
|
||||
while (list)
|
||||
|
||||
@@ -139,7 +139,7 @@ log_resolution (rule_t *rule, symbol_number_t token,
|
||||
static void
|
||||
flush_shift (state_t *state, int token)
|
||||
{
|
||||
transitions_t *transitions = state->shifts;
|
||||
transitions_t *transitions = state->transitions;
|
||||
int i;
|
||||
|
||||
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. |
|
||||
| |
|
||||
| LOOKAHEAD is the number of the lookahead bitset to consider. |
|
||||
| |
|
||||
| ERRS can be used to store discovered explicit errors. |
|
||||
`------------------------------------------------------------------*/
|
||||
|
||||
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;
|
||||
/* Find the rule to reduce by to get precedence of reduction. */
|
||||
rule_t *redrule = state->lookaheads_rule[lookahead];
|
||||
int redprec = redrule->prec->prec;
|
||||
bitset lookaheads = state->lookaheads[lookahead];
|
||||
errs_t *errp = errs_new (ntokens + 1);
|
||||
errp->num = 0;
|
||||
int nerrs = 0;
|
||||
|
||||
for (i = 0; i < ntokens; i++)
|
||||
if (bitset_test (lookaheads, i)
|
||||
@@ -224,7 +226,7 @@ resolve_sr_conflict (state_t *state, int lookahead)
|
||||
flush_shift (state, i);
|
||||
flush_reduce (lookaheads, i);
|
||||
/* Record an explicit error for this token. */
|
||||
errp->symbols[errp->num++] = i;
|
||||
errs[nerrs++] = i;
|
||||
break;
|
||||
|
||||
case undef_assoc:
|
||||
@@ -235,8 +237,7 @@ resolve_sr_conflict (state_t *state, int lookahead)
|
||||
|
||||
/* Some tokens have been explicitly made errors. Allocate a
|
||||
permanent errs structure for this state, to record them. */
|
||||
state->errs = errs_dup (errp);
|
||||
free (errp);
|
||||
state_errs_set (state, nerrs, errs);
|
||||
|
||||
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
|
||||
set_conflicts (state_t *state)
|
||||
set_conflicts (state_t *state, symbol_number_t *errs)
|
||||
{
|
||||
int i;
|
||||
transitions_t *transitions;
|
||||
transitions_t *transitions = state->transitions;
|
||||
|
||||
if (state->consistent)
|
||||
return;
|
||||
|
||||
bitset_zero (lookaheadset);
|
||||
|
||||
transitions = state->shifts;
|
||||
for (i = 0; i < transitions->num && TRANSITION_IS_SHIFT (transitions, i); i++)
|
||||
if (!TRANSITION_IS_DISABLED (transitions, i))
|
||||
bitset_set (lookaheadset, TRANSITION_SYMBOL (transitions, i));
|
||||
@@ -270,7 +277,7 @@ set_conflicts (state_t *state)
|
||||
&& state->lookaheads_rule[i]->prec->prec
|
||||
&& !bitset_disjoint_p (state->lookaheads[i], lookaheadset))
|
||||
{
|
||||
resolve_sr_conflict (state, i);
|
||||
resolve_sr_conflict (state, i, errs);
|
||||
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
|
||||
conflicts_solve (void)
|
||||
{
|
||||
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);
|
||||
shiftset = bitset_create (ntokens, BITSET_FIXED);
|
||||
@@ -296,7 +311,16 @@ conflicts_solve (void)
|
||||
obstack_init (&solved_conflicts_obstack);
|
||||
|
||||
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 src_count = 0;
|
||||
transitions_t *transitions = state->shifts;
|
||||
transitions_t *transitions = state->transitions;
|
||||
|
||||
if (!transitions)
|
||||
return 0;
|
||||
|
||||
12
src/lalr.c
12
src/lalr.c
@@ -94,7 +94,7 @@ set_goto_map (void)
|
||||
ngotos = 0;
|
||||
for (state = 0; state < nstates; ++state)
|
||||
{
|
||||
transitions_t *sp = states[state]->shifts;
|
||||
transitions_t *sp = states[state]->transitions;
|
||||
int 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)
|
||||
{
|
||||
transitions_t *sp = states[state]->shifts;
|
||||
transitions_t *sp = states[state]->transitions;
|
||||
int 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++)
|
||||
{
|
||||
state_number_t stateno = to_state[i];
|
||||
transitions_t *sp = states[stateno]->shifts;
|
||||
transitions_t *sp = states[stateno]->transitions;
|
||||
|
||||
int 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++)
|
||||
{
|
||||
state = transitions_to (state->shifts,
|
||||
item_number_as_symbol_number (*rp));
|
||||
state = transitions_to (state->transitions,
|
||||
item_number_as_symbol_number (*rp));
|
||||
states1[length++] = state->number;
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ states_lookaheads_count (void)
|
||||
int k;
|
||||
int nlookaheads = 0;
|
||||
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
|
||||
reductions (i.e., there are two or more), or to distinguish a
|
||||
|
||||
@@ -430,7 +430,7 @@ action_row (state_t *state)
|
||||
int i;
|
||||
rule_number_t default_rule = 0;
|
||||
reductions_t *redp = state->reductions;
|
||||
transitions_t *transitions = state->shifts;
|
||||
transitions_t *transitions = state->transitions;
|
||||
errs_t *errp = state->errs;
|
||||
/* set nonzero to inhibit having any default reduction */
|
||||
int nodefault = 0;
|
||||
|
||||
@@ -125,7 +125,7 @@ print_core (FILE *out, state_t *state)
|
||||
static void
|
||||
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;
|
||||
int i;
|
||||
|
||||
@@ -224,7 +224,7 @@ state_default_rule (state_t *state)
|
||||
we shift (S/R conflicts)... */
|
||||
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++)
|
||||
if (!TRANSITION_IS_DISABLED (transitions, i))
|
||||
{
|
||||
@@ -302,7 +302,7 @@ print_reduction (FILE *out, size_t width,
|
||||
static void
|
||||
print_reductions (FILE *out, state_t *state)
|
||||
{
|
||||
transitions_t *transitions = state->shifts;
|
||||
transitions_t *transitions = state->transitions;
|
||||
reductions_t *redp = state->reductions;
|
||||
rule_t *default_rule = NULL;
|
||||
size_t width = 0;
|
||||
@@ -396,7 +396,7 @@ static void
|
||||
print_actions (FILE *out, state_t *state)
|
||||
{
|
||||
reductions_t *redp = state->reductions;
|
||||
transitions_t *transitions = state->shifts;
|
||||
transitions_t *transitions = state->transitions;
|
||||
|
||||
if (transitions->num == 0 && redp->num == 0)
|
||||
{
|
||||
|
||||
@@ -125,7 +125,7 @@ print_actions (state_t *state, const char *node_name)
|
||||
{
|
||||
int i;
|
||||
|
||||
transitions_t *transitions = state->shifts;
|
||||
transitions_t *transitions = state->transitions;
|
||||
reductions_t *redp = state->reductions;
|
||||
|
||||
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. |
|
||||
`-------------------------------*/
|
||||
|
||||
#define ERRS_ALLOC(Nerrs) \
|
||||
(errs_t *) xcalloc ((unsigned) (sizeof (errs_t) \
|
||||
+ (Nerrs - 1) * sizeof (symbol_number_t)), 1)
|
||||
#define ERRS_ALLOC(Nerrs) \
|
||||
(errs_t *) xcalloc ((sizeof (errs_t) \
|
||||
+ (Nerrs - 1) * sizeof (symbol_number_t)), 1)
|
||||
|
||||
|
||||
errs_t *
|
||||
errs_new (int n)
|
||||
errs_new (int num, symbol_number_t *tokens)
|
||||
{
|
||||
errs_t *res = ERRS_ALLOC (n);
|
||||
res->num = n;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
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]));
|
||||
errs_t *res = ERRS_ALLOC (num);
|
||||
res->num = num;
|
||||
memcpy (res->symbols, tokens, num * sizeof (tokens[0]));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -108,16 +100,16 @@ errs_dup (errs_t *src)
|
||||
| Create a new array of N reductions. |
|
||||
`-------------------------------------*/
|
||||
|
||||
#define REDUCTIONS_ALLOC(Nreductions) \
|
||||
(reductions_t *) xcalloc ((unsigned) (sizeof (reductions_t) \
|
||||
+ (Nreductions - 1) * sizeof (rule_number_t)), 1)
|
||||
#define REDUCTIONS_ALLOC(Nreductions) \
|
||||
(reductions_t *) xcalloc ((sizeof (reductions_t) \
|
||||
+ (Nreductions - 1) * sizeof (rule_number_t)), 1)
|
||||
|
||||
static reductions_t *
|
||||
reductions_new (int nreductions, short *reductions)
|
||||
reductions_new (int num, rule_number_t *reductions)
|
||||
{
|
||||
reductions_t *res = REDUCTIONS_ALLOC (nreductions);
|
||||
res->num = nreductions;
|
||||
memcpy (res->rules, reductions, nreductions * sizeof (reductions[0]));
|
||||
reductions_t *res = REDUCTIONS_ALLOC (num);
|
||||
res->num = num;
|
||||
memcpy (res->rules, reductions, num * sizeof (reductions[0]));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -137,9 +129,10 @@ state_t *final_state = NULL;
|
||||
(state_t *) xcalloc ((unsigned) (sizeof (state_t) \
|
||||
+ (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_new (symbol_number_t accessing_symbol,
|
||||
@@ -159,18 +152,35 @@ state_new (symbol_number_t accessing_symbol,
|
||||
res->nitems = core_size;
|
||||
memcpy (res->items, core, core_size * sizeof (core[0]));
|
||||
|
||||
state_hash_insert (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
|
||||
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
|
||||
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)
|
||||
{
|
||||
state_number_t i;
|
||||
|
||||
for (i = 0; i < nstates; ++i)
|
||||
{
|
||||
free (states[i]->shifts);
|
||||
XFREE (states[i]->reductions);
|
||||
free (states[i]->errs);
|
||||
free (states[i]);
|
||||
}
|
||||
XFREE (states);
|
||||
state_free (states[i]);
|
||||
free (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
|
||||
in the RITEMS vector of the items that are selected in this state.
|
||||
|
||||
The two types of transitions are shifts (push the lookahead token
|
||||
and read another) and reductions (combine the last n things on the
|
||||
stack via a rule, replace them with the symbol that the rule
|
||||
derives, and leave the lookahead token alone). When the states are
|
||||
generated, these transitions are represented in two other lists.
|
||||
The two types of actions are shifts/gotos (push the lookahead token
|
||||
and read another/goto to the state designated by a nterm) and
|
||||
reductions (combine the last n things on the stack via a rule,
|
||||
replace them with the symbol that the rule derives, and leave the
|
||||
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
|
||||
of one state, the state whose number is in the number field. The
|
||||
shifts structures are linked through next and first_shift points to
|
||||
them. Each contains a vector of numbers of the states that shift
|
||||
transitions can go to. The accessing_symbol fields of those
|
||||
states' cores say what kind of input leads to them.
|
||||
Each transition_t structure describes the possible transitions out
|
||||
of one state, the state whose number is in the number field. Each
|
||||
contains a vector of numbers of the states that transitions can go
|
||||
to. The accessing_symbol fields of those states' cores say what
|
||||
kind of input leads to them.
|
||||
|
||||
A shift to state zero should be ignored. Conflict resolution
|
||||
deletes shifts by changing them to zero.
|
||||
A transition to state zero should be ignored: conflict resolution
|
||||
deletes transitions by having them point to zero.
|
||||
|
||||
Each reductions structure describes the possible reductions at the
|
||||
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
|
||||
states should explicitly be errors (for implementing %nonassoc).
|
||||
For each state, the tokens that are errors for this reason are
|
||||
recorded in an errs structure, which has the state number in its
|
||||
number field. The rest of the errs structure is full of token
|
||||
numbers.
|
||||
recorded in an errs structure, which holds the 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
|
||||
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 has one shift, which goes to the termination state
|
||||
(whose number is nstates-1). The reason for the extra state at the
|
||||
end is to placate the parser's strategy of making all decisions one
|
||||
token ahead of its actions. */
|
||||
The final state has one shift, which goes to the termination state.
|
||||
The reason for the extra state at the end is to placate the
|
||||
parser's strategy of making all decisions one token ahead of its
|
||||
actions. */
|
||||
|
||||
#ifndef STATE_H_
|
||||
# define STATE_H_
|
||||
@@ -108,36 +106,36 @@ typedef struct transtion_s
|
||||
} transitions_t;
|
||||
|
||||
|
||||
/* What is the symbol which is shifted by TRANSITIONS->states[Shift]? Can
|
||||
be a token (amongst which the error token), or non terminals in
|
||||
case of gotos. */
|
||||
/* What is the symbol labelling the transition to
|
||||
TRANSITIONS->states[Num]? Can be a token (amongst which the error
|
||||
token), or non terminals in case of gotos. */
|
||||
|
||||
#define TRANSITION_SYMBOL(Transitions, Shift) \
|
||||
(states[Transitions->states[Shift]]->accessing_symbol)
|
||||
#define TRANSITION_SYMBOL(Transitions, Num) \
|
||||
(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) \
|
||||
(ISTOKEN (TRANSITION_SYMBOL (Transitions, Shift)))
|
||||
#define TRANSITION_IS_SHIFT(Transitions, Num) \
|
||||
(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) \
|
||||
(!TRANSITION_IS_SHIFT (Transitions, Shift))
|
||||
#define TRANSITION_IS_GOTO(Transitions, Num) \
|
||||
(!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) \
|
||||
(TRANSITION_SYMBOL (Transitions, Shift) == errtoken->number)
|
||||
#define TRANSITION_IS_ERROR(Transitions, Num) \
|
||||
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
|
||||
|
||||
/* When resolving a SR conflicts, if the reduction wins, the shift is
|
||||
disabled. */
|
||||
|
||||
#define TRANSITION_DISABLE(Transitions, Shift) \
|
||||
(Transitions->states[Shift] = 0)
|
||||
#define TRANSITION_DISABLE(Transitions, Num) \
|
||||
(Transitions->states[Num] = 0)
|
||||
|
||||
#define TRANSITION_IS_DISABLED(Transitions, Shift) \
|
||||
(Transitions->states[Shift] == 0)
|
||||
#define TRANSITION_IS_DISABLED(Transitions, Num) \
|
||||
(Transitions->states[Num] == 0)
|
||||
|
||||
/* Return the state such these TRANSITIONS contain a shift/goto to it on
|
||||
SYMBOL. Aborts if none found. */
|
||||
@@ -156,8 +154,7 @@ typedef struct errs_s
|
||||
symbol_number_t symbols[1];
|
||||
} errs_t;
|
||||
|
||||
errs_t *errs_new PARAMS ((int n));
|
||||
errs_t *errs_dup PARAMS ((errs_t *src));
|
||||
errs_t *errs_new PARAMS ((int num, symbol_number_t *tokens));
|
||||
|
||||
|
||||
/*-------------.
|
||||
@@ -180,7 +177,7 @@ typedef struct state_s
|
||||
{
|
||||
state_number_t number;
|
||||
symbol_number_t accessing_symbol;
|
||||
transitions_t *shifts;
|
||||
transitions_t *transitions;
|
||||
reductions_t *reductions;
|
||||
errs_t *errs;
|
||||
|
||||
@@ -215,13 +212,17 @@ extern state_t *final_state;
|
||||
state_t *state_new PARAMS ((symbol_number_t accessing_symbol,
|
||||
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,
|
||||
int nshifts, state_number_t *shifts));
|
||||
int num, state_number_t *transitions));
|
||||
|
||||
/* Set the reductions of 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
|
||||
reduce this RULE. */
|
||||
|
||||
Reference in New Issue
Block a user