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:
Akim Demaille
2002-07-03 06:51:43 +00:00
parent 613f5e1a89
commit 8b752b00fd
9 changed files with 210 additions and 157 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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)
{ {

View File

@@ -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];

View File

@@ -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);
} }

View File

@@ -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. */