Instead of attaching lookaheads and duplicating the rules being

reduced by a state, attach the lookaheads to the reductions.
* src/state.h (state_t): Remove the `lookaheads',
`lookaheads_rule' member.
(reductions_t): Add a `lookaheads' member.
Use a regular array for the `rules'.
* src/state.c (reductions_new): Initialize the lookaheads member
to 0.
(state_rule_lookaheads_print): Adjust.
* src/state.h, src/state.c (state_reductions_find): New.
* src/conflicts.c (resolve_sr_conflict, set_conflicts)
(count_rr_conflicts): Adjust.
* src/lalr.c (LArule): Remove.
(add_lookback_edge): Adjust.
(state_lookaheads_count): New.
(states_lookaheads_initialize): Merge into...
(initialize_LA): this.
(lalr_free): Adjust.
* src/main.c (main): Don't free nullable and derives too early: it
is used by --verbose.
* src/print.c, src/print_graph.c, src/tables.c: Adjust.
This commit is contained in:
Akim Demaille
2002-08-01 18:14:30 +00:00
parent bb0027a9ac
commit cd08e51eda
9 changed files with 228 additions and 240 deletions

View File

@@ -1,3 +1,28 @@
2002-08-01 Akim Demaille <akim@epita.fr>
Instead of attaching lookaheads and duplicating the rules being
reduced by a state, attach the lookaheads to the reductions.
* src/state.h (state_t): Remove the `lookaheads',
`lookaheads_rule' member.
(reductions_t): Add a `lookaheads' member.
Use a regular array for the `rules'.
* src/state.c (reductions_new): Initialize the lookaheads member
to 0.
(state_rule_lookaheads_print): Adjust.
* src/state.h, src/state.c (state_reductions_find): New.
* src/conflicts.c (resolve_sr_conflict, set_conflicts)
(count_rr_conflicts): Adjust.
* src/lalr.c (LArule): Remove.
(add_lookback_edge): Adjust.
(state_lookaheads_count): New.
(states_lookaheads_initialize): Merge into...
(initialize_LA): this.
(lalr_free): Adjust.
* src/main.c (main): Don't free nullable and derives too early: it
is used by --verbose.
* src/print.c, src/print_graph.c, src/tables.c: Adjust.
2002-08-01 Akim Demaille <akim@epita.fr> 2002-08-01 Akim Demaille <akim@epita.fr>
* src/derives.h, src/derives.c (derives): A `rule_t***' instead of * src/derives.h, src/derives.c (derives): A `rule_t***' instead of

View File

@@ -175,14 +175,15 @@ flush_reduce (bitset lookaheads, int token)
`------------------------------------------------------------------*/ `------------------------------------------------------------------*/
static void static void
resolve_sr_conflict (state_t *state, int lookahead, resolve_sr_conflict (state_t *state, int ruleno,
symbol_t **errs) symbol_t **errs)
{ {
symbol_number_t i; symbol_number_t i;
reductions_t *reds = state->reductions;
/* 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 = reds->rules[ruleno];
int redprec = redrule->prec->prec; int redprec = redrule->prec->prec;
bitset lookaheads = state->lookaheads[lookahead]; bitset lookaheads = reds->lookaheads[ruleno];
int nerrs = 0; int nerrs = 0;
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
@@ -259,6 +260,7 @@ set_conflicts (state_t *state, symbol_t **errs)
{ {
int i; int i;
transitions_t *transitions = state->transitions; transitions_t *transitions = state->transitions;
reductions_t *reds = state->reductions;
if (state->consistent) if (state->consistent)
return; return;
@@ -271,10 +273,9 @@ set_conflicts (state_t *state, symbol_t **errs)
/* Loop over all rules which require lookahead in this state. First /* Loop over all rules which require lookahead in this state. First
check for shift-reduce conflict, and try to resolve using check for shift-reduce conflict, and try to resolve using
precedence. */ precedence. */
for (i = 0; i < state->nlookaheads; ++i) for (i = 0; i < reds->num; ++i)
if (state->lookaheads_rule[i]->prec if (reds->rules[i]->prec && reds->rules[i]->prec->prec
&& state->lookaheads_rule[i]->prec->prec && !bitset_disjoint_p (reds->lookaheads[i], lookaheadset))
&& !bitset_disjoint_p (state->lookaheads[i], lookaheadset))
{ {
resolve_sr_conflict (state, i, errs); resolve_sr_conflict (state, i, errs);
break; break;
@@ -282,12 +283,12 @@ set_conflicts (state_t *state, symbol_t **errs)
/* Loop over all rules which require lookahead in this state. Check /* Loop over all rules which require lookahead in this state. Check
for conflicts not resolved above. */ for conflicts not resolved above. */
for (i = 0; i < state->nlookaheads; ++i) for (i = 0; i < reds->num; ++i)
{ {
if (!bitset_disjoint_p (state->lookaheads[i], lookaheadset)) if (!bitset_disjoint_p (reds->lookaheads[i], lookaheadset))
conflicts[state->number] = 1; conflicts[state->number] = 1;
bitset_or (lookaheadset, lookaheadset, state->lookaheads[i]); bitset_or (lookaheadset, lookaheadset, reds->lookaheads[i]);
} }
} }
@@ -333,6 +334,7 @@ count_sr_conflicts (state_t *state)
int i; int i;
int src_count = 0; int src_count = 0;
transitions_t *transitions = state->transitions; transitions_t *transitions = state->transitions;
reductions_t *reds = state->reductions;
if (!transitions) if (!transitions)
return 0; return 0;
@@ -343,8 +345,8 @@ count_sr_conflicts (state_t *state)
FOR_EACH_SHIFT (transitions, i) FOR_EACH_SHIFT (transitions, i)
bitset_set (shiftset, TRANSITION_SYMBOL (transitions, i)); bitset_set (shiftset, TRANSITION_SYMBOL (transitions, i));
for (i = 0; i < state->nlookaheads; ++i) for (i = 0; i < reds->num; ++i)
bitset_or (lookaheadset, lookaheadset, state->lookaheads[i]); bitset_or (lookaheadset, lookaheadset, reds->lookaheads[i]);
bitset_and (lookaheadset, lookaheadset, shiftset); bitset_and (lookaheadset, lookaheadset, shiftset);
@@ -365,17 +367,15 @@ static int
count_rr_conflicts (state_t *state, int one_per_token) count_rr_conflicts (state_t *state, int one_per_token)
{ {
int i; int i;
reductions_t *reds = state->reductions;
int rrc_count = 0; int rrc_count = 0;
if (state->nlookaheads < 2)
return 0;
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
{ {
int count = 0; int count = 0;
int j; int j;
for (j = 0; j < state->nlookaheads; ++j) for (j = 0; j < reds->num; ++j)
if (bitset_test (state->lookaheads[j], i)) if (bitset_test (reds->lookaheads[j], i))
count++; count++;
if (count >= 2) if (count >= 2)
@@ -456,9 +456,10 @@ conflicts_output (FILE *out)
for (i = 0; i < nstates; i++) for (i = 0; i < nstates; i++)
{ {
state_t *s = states[i]; state_t *s = states[i];
reductions_t *reds = s->reductions;
int j; int j;
for (j = 0; j < s->reductions->num; ++j) for (j = 0; j < reds->num; ++j)
used_rules[s->reductions->rules[j]->number] = TRUE; used_rules[reds->rules[j]->number] = TRUE;
if (conflicts[i]) if (conflicts[i])
{ {
fprintf (out, _("State %d contains "), i); fprintf (out, _("State %d contains "), i);

View File

@@ -52,16 +52,6 @@ typedef struct goto_list_s
} goto_list_t; } goto_list_t;
/* LARULE is a vector which records the rules that need lookahead in
various states. The elements of LARULE that apply to state S are
those from LOOKAHEADS[S] through LOOKAHEADS[S+1]-1.
If LR is the length of LArule, then a number from 0 to LR-1 can
specify both a rule and a state where the rule might be applied.
*/
static rule_t **LArule = NULL;
/* LA is a LR by NTOKENS matrix of bits. LA[l, i] is 1 if the rule /* LA is a LR by NTOKENS matrix of bits. LA[l, i] is 1 if the rule
LArule[l] is applicable in the appropriate state when the next LArule[l] is applicable in the appropriate state when the next
token is symbol i. If LA[l, i] and LA[l, j] are both 1 for i != j, token is symbol i. If LA[l, i] and LA[l, j] are both 1 for i != j,
@@ -81,29 +71,6 @@ static goto_list_t **lookback;
static void
initialize_LA (void)
{
state_number_t i;
int j;
rule_t **np;
/* Avoid having to special case 0. */
if (!nLA)
nLA = 1;
LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
LArule = XCALLOC (rule_t *, nLA);
lookback = XCALLOC (goto_list_t *, nLA);
np = LArule;
for (i = 0; i < nstates; i++)
if (!states[i]->consistent)
for (j = 0; j < states[i]->reductions->num; j++)
*np++ = states[i]->reductions->rules[j];
}
static void static void
set_goto_map (void) set_goto_map (void)
{ {
@@ -246,19 +213,11 @@ initialize_F (void)
static void static void
add_lookback_edge (state_t *state, rule_t *rule, int gotono) add_lookback_edge (state_t *state, rule_t *rule, int gotono)
{ {
int i; int r = state_reduction_find (state, rule);
goto_list_t *sp; goto_list_t *sp = XCALLOC (goto_list_t, 1);
sp->next = lookback[(state->reductions->lookaheads - LA) + r];
for (i = 0; i < state->nlookaheads; ++i)
if (state->lookaheads_rule[i] == rule)
break;
assert (state->lookaheads_rule[i] == rule);
sp = XCALLOC (goto_list_t, 1);
sp->next = lookback[(state->lookaheads - LA) + i];
sp->value = gotono; sp->value = gotono;
lookback[(state->lookaheads - LA) + i] = sp; lookback[(state->reductions->lookaheads - LA) + r] = sp;
} }
@@ -365,24 +324,18 @@ compute_lookaheads (void)
} }
/*-------------------------------------------------------------. /*---------------------------------------------------------------.
| Count the number of lookaheads required for each state | | Count the number of lookaheads required for STATE (NLOOKAHEADS |
| (NLOOKAHEADS member). Compute the total number of LA, NLA. | | member). |
`-------------------------------------------------------------*/ `---------------------------------------------------------------*/
static void static int
states_lookaheads_count (void) state_lookaheads_count (state_t *state)
{ {
state_number_t i;
nLA = 0;
/* Count */
for (i = 0; i < nstates; i++)
{
int k; int k;
int nlookaheads = 0; int nlookaheads = 0;
reductions_t *rp = states[i]->reductions; reductions_t *rp = state->reductions;
transitions_t *sp = states[i]->transitions; transitions_t *sp = state->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
@@ -393,40 +346,50 @@ states_lookaheads_count (void)
!TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0))) !TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0)))
nlookaheads += rp->num; nlookaheads += rp->num;
else else
states[i]->consistent = 1; state->consistent = 1;
for (k = 0; k < sp->num; k++) for (k = 0; k < sp->num; k++)
if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k)) if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k))
{ {
states[i]->consistent = 0; state->consistent = 0;
break; break;
} }
states[i]->nlookaheads = nlookaheads; return nlookaheads;
nLA += nlookaheads;
}
} }
/*--------------------------------------. /*----------------------------------------------.
| Initializing the lookaheads members. | | Compute LA, NLA, and the lookaheads members. |
`--------------------------------------*/ `----------------------------------------------*/
static void static void
states_lookaheads_initialize (void) initialize_LA (void)
{ {
state_number_t i; state_number_t i;
bitsetv pLA = LA; bitsetv pLA;
rule_t **pLArule = LArule;
/* Initialize the members LOOKAHEADS and LOOKAHEADS_RULE for each /* Compute the total number of reductions requiring a lookahead. */
state. */ nLA = 0;
for (i = 0; i < nstates; i++)
nLA += state_lookaheads_count (states[i]);
/* Avoid having to special case 0. */
if (!nLA)
nLA = 1;
pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED);
lookback = XCALLOC (goto_list_t *, nLA);
/* Initialize the members LOOKAHEADS for each state which reductions
require lookaheads. */
for (i = 0; i < nstates; i++) for (i = 0; i < nstates; i++)
{ {
states[i]->lookaheads = pLA; int count = state_lookaheads_count (states[i]);
states[i]->lookaheads_rule = pLArule; if (count)
pLA += states[i]->nlookaheads; {
pLArule += states[i]->nlookaheads; states[i]->reductions->lookaheads = pLA;
pLA += count;
}
} }
} }
@@ -443,17 +406,25 @@ lookaheads_print (FILE *out)
fprintf (out, "Lookaheads: BEGIN\n"); fprintf (out, "Lookaheads: BEGIN\n");
for (i = 0; i < nstates; ++i) for (i = 0; i < nstates; ++i)
{ {
reductions_t *reds = states[i]->reductions;
bitset_iterator iter; bitset_iterator iter;
int nlookaheads = 0;
if (reds->lookaheads)
for (k = 0; k < reds->num; ++k)
if (reds->lookaheads[k])
++nlookaheads;
fprintf (out, "State %d: %d lookaheads\n", fprintf (out, "State %d: %d lookaheads\n",
i, states[i]->nlookaheads); i, nlookaheads);
for (j = 0; j < states[i]->nlookaheads; ++j) if (reds->lookaheads)
BITSET_FOR_EACH (iter, states[i]->lookaheads[j], k, 0) for (j = 0; j < reds->num; ++j)
BITSET_FOR_EACH (iter, reds->lookaheads[j], k, 0)
{ {
fprintf (out, " on %d (%s) -> rule %d\n", fprintf (out, " on %d (%s) -> rule %d\n",
k, symbols[k]->tag, k, symbols[k]->tag,
states[i]->lookaheads_rule[j]->number); reds->rules[j]->number);
}; };
} }
fprintf (out, "Lookaheads: END\n"); fprintf (out, "Lookaheads: END\n");
@@ -462,9 +433,7 @@ lookaheads_print (FILE *out)
void void
lalr (void) lalr (void)
{ {
states_lookaheads_count ();
initialize_LA (); initialize_LA ();
states_lookaheads_initialize ();
set_goto_map (); set_goto_map ();
initialize_F (); initialize_F ();
build_relations (); build_relations ();
@@ -481,10 +450,6 @@ lalr_free (void)
{ {
state_number_t s; state_number_t s;
for (s = 0; s < nstates; ++s) for (s = 0; s < nstates; ++s)
{ states[s]->reductions->lookaheads = NULL;
states[s]->lookaheads = NULL;
states[s]->lookaheads_rule = NULL;
}
bitsetv_free (LA); bitsetv_free (LA);
free (LArule);
} }

View File

@@ -99,11 +99,6 @@ main (int argc, char *argv[])
lalr (); lalr ();
timevar_pop (TV_LALR); timevar_pop (TV_LALR);
timevar_push (TV_FREE);
nullable_free ();
derives_free ();
timevar_pop (TV_FREE);
/* Find and record any conflicts: places where one token of /* Find and record any conflicts: places where one token of
lookahead is not enough to disambiguate the parsing. In file lookahead is not enough to disambiguate the parsing. In file
conflicts. Also resolve s/r conflicts based on precedence conflicts. Also resolve s/r conflicts based on precedence
@@ -153,6 +148,8 @@ main (int argc, char *argv[])
timevar_pop (TV_PARSER); timevar_pop (TV_PARSER);
timevar_push (TV_FREE); timevar_push (TV_FREE);
nullable_free ();
derives_free ();
tables_free (); tables_free ();
states_free (); states_free ();
reduce_free (); reduce_free ();

View File

@@ -244,25 +244,25 @@ state_default_rule (state_t *state)
bitset_set (shiftset, errp->symbols[i]->number); bitset_set (shiftset, errp->symbols[i]->number);
} }
for (i = 0; i < state->nlookaheads; ++i) for (i = 0; i < redp->num; ++i)
{ {
int count = 0; int count = 0;
/* How many non-masked lookaheads are there for this reduction? /* How many non-masked lookaheads are there for this reduction?
*/ */
bitset_andn (lookaheadset, state->lookaheads[i], shiftset); bitset_andn (lookaheadset, redp->lookaheads[i], shiftset);
count = bitset_count (lookaheadset); count = bitset_count (lookaheadset);
if (count > cmax) if (count > cmax)
{ {
cmax = count; cmax = count;
default_rule = state->lookaheads_rule[i]; default_rule = redp->rules[i];
} }
/* 3. And finally, each reduction is possibly masked by previous /* 3. And finally, each reduction is possibly masked by previous
reductions (in R/R conflicts, we keep the first reductions). reductions (in R/R conflicts, we keep the first reductions).
*/ */
bitset_or (shiftset, shiftset, state->lookaheads[i]); bitset_or (shiftset, shiftset, redp->lookaheads[i]);
} }
return default_rule; return default_rule;
@@ -322,16 +322,18 @@ print_reductions (FILE *out, state_t *state)
/* Compute the width of the lookaheads column. */ /* Compute the width of the lookaheads column. */
if (default_rule) if (default_rule)
width = strlen (_("$default")); width = strlen (_("$default"));
if (redp->lookaheads)
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
{ {
int count = bitset_test (shiftset, i); int count = bitset_test (shiftset, i);
for (j = 0; j < state->nlookaheads; ++j) for (j = 0; j < redp->num; ++j)
if (bitset_test (state->lookaheads[j], i)) if (bitset_test (redp->lookaheads[j], i))
{ {
if (count == 0) if (count == 0)
{ {
if (state->lookaheads_rule[j] != default_rule) if (redp->rules[j] != default_rule)
max_length (&width, symbols[i]->tag); max_length (&width, symbols[i]->tag);
count++; count++;
} }
@@ -350,20 +352,21 @@ print_reductions (FILE *out, state_t *state)
width += 2; width += 2;
/* Report lookaheads (or $default) and reductions. */ /* Report lookaheads (or $default) and reductions. */
if (redp->lookaheads)
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
{ {
int defaulted = 0; int defaulted = 0;
int count = bitset_test (shiftset, i); int count = bitset_test (shiftset, i);
for (j = 0; j < state->nlookaheads; ++j) for (j = 0; j < redp->num; ++j)
if (bitset_test (state->lookaheads[j], i)) if (bitset_test (redp->lookaheads[j], i))
{ {
if (count == 0) if (count == 0)
{ {
if (state->lookaheads_rule[j] != default_rule) if (redp->rules[j] != default_rule)
print_reduction (out, width, print_reduction (out, width,
symbols[i]->tag, symbols[i]->tag,
state->lookaheads_rule[j], TRUE); redp->rules[j], TRUE);
else else
defaulted = 1; defaulted = 1;
count++; count++;
@@ -377,7 +380,7 @@ print_reductions (FILE *out, state_t *state)
defaulted = 0; defaulted = 0;
print_reduction (out, width, print_reduction (out, width,
symbols[i]->tag, symbols[i]->tag,
state->lookaheads_rule[j], FALSE); redp->rules[j], FALSE);
} }
} }
} }

View File

@@ -86,28 +86,23 @@ print_core (struct obstack *oout, state_t *state)
obstack_fgrow1 (oout, " %s", symbols[*sp]->tag); obstack_fgrow1 (oout, " %s", symbols[*sp]->tag);
/* Experimental feature: display the lookaheads. */ /* Experimental feature: display the lookaheads. */
if ((report_flag & report_lookaheads) if (report_flag & report_lookaheads)
&& state->nlookaheads) {
/* Find the reduction we are handling. */
reductions_t *reds = state->reductions;
int redno = state_reduction_find (state, &rules[rule]);
/* Print them if there are. */
if (reds->lookaheads && redno != -1)
{ {
int j, k;
bitset_iterator biter; bitset_iterator biter;
int nlookaheads = 0; int k;
int not_first = 0;
/* Look for lookaheads corresponding to this rule. */ obstack_sgrow (oout, "[");
for (j = 0; j < state->nlookaheads; ++j) BITSET_FOR_EACH (biter, reds->lookaheads[redno], k, 0)
BITSET_FOR_EACH (biter, state->lookaheads[j], k, 0)
if (state->lookaheads_rule[j]->number == rule)
nlookaheads++;
if (nlookaheads)
{
obstack_sgrow (oout, " [");
for (j = 0; j < state->nlookaheads; ++j)
BITSET_FOR_EACH (biter, state->lookaheads[j], k, 0)
if (state->lookaheads_rule[j]->number == rule)
obstack_fgrow2 (oout, "%s%s", obstack_fgrow2 (oout, "%s%s",
symbols[k]->tag, not_first++ ? ", " : "",
--nlookaheads ? ", " : ""); symbols[k]->tag);
obstack_sgrow (oout, "]"); obstack_sgrow (oout, "]");
} }
} }

View File

@@ -110,6 +110,7 @@ reductions_new (int num, rule_t **reductions)
reductions_t *res = REDUCTIONS_ALLOC (num); reductions_t *res = REDUCTIONS_ALLOC (num);
res->num = num; res->num = num;
memcpy (res->rules, reductions, num * sizeof (reductions[0])); memcpy (res->rules, reductions, num * sizeof (reductions[0]));
res->lookaheads = NULL;
return res; return res;
} }
@@ -196,6 +197,18 @@ state_reductions_set (state_t *state, int num, rule_t **reductions)
} }
int
state_reduction_find (state_t *state, rule_t *rule)
{
int i;
reductions_t *reds = state->reductions;
for (i = 0; i < reds->num; ++i)
if (reds->rules[i] == rule)
return i;
return -1;
}
/*------------------------. /*------------------------.
| Set the errs of STATE. | | Set the errs of STATE. |
`------------------------*/ `------------------------*/
@@ -217,25 +230,21 @@ state_errs_set (state_t *state, int num, symbol_t **tokens)
void void
state_rule_lookaheads_print (state_t *state, rule_t *rule, FILE *out) state_rule_lookaheads_print (state_t *state, rule_t *rule, FILE *out)
{ {
int j, k; /* Find the reduction we are handling. */
bitset_iterator biter; reductions_t *reds = state->reductions;
int nlookaheads = 0; int red = state_reduction_find (state, rule);
/* Count the number of lookaheads corresponding to this rule. */
for (j = 0; j < state->nlookaheads; ++j)
BITSET_FOR_EACH (biter, state->lookaheads[j], k, 0)
if (state->lookaheads_rule[j] == rule)
nlookaheads++;
/* Print them if there are. */ /* Print them if there are. */
if (nlookaheads) if (reds->lookaheads && red != -1)
{ {
bitset_iterator biter;
int k;
int not_first = 0;
fprintf (out, " ["); fprintf (out, " [");
for (j = 0; j < state->nlookaheads; ++j) BITSET_FOR_EACH (biter, reds->lookaheads[red], k, 0)
BITSET_FOR_EACH (biter, state->lookaheads[j], k, 0)
if (state->lookaheads_rule[j] == rule)
fprintf (out, "%s%s", fprintf (out, "%s%s",
symbols[k]->tag, not_first++ ? ", " : "",
--nlookaheads ? ", " : ""); symbols[k]->tag);
fprintf (out, "]"); fprintf (out, "]");
} }
} }

View File

@@ -82,7 +82,7 @@
#ifndef STATE_H_ #ifndef STATE_H_
# define STATE_H_ # define STATE_H_
# include "bitsetv.h" # include "bitset.h"
/*-------------------. /*-------------------.
@@ -178,6 +178,7 @@ errs_t *errs_new PARAMS ((int num, symbol_t **tokens));
typedef struct reductions_s typedef struct reductions_s
{ {
short num; short num;
bitset *lookaheads;
rule_t *rules[1]; rule_t *rules[1];
} reductions_t; } reductions_t;
@@ -198,17 +199,6 @@ struct state_s
/* Nonzero if no lookahead is needed to decide what to do in state S. */ /* Nonzero if no lookahead is needed to decide what to do in state S. */
char consistent; char consistent;
/* Used in LALR, not LR(0).
When a state is not consistent (there is an S/R or R/R conflict),
lookaheads are needed to enable the reductions. NLOOKAHEADS is
the number of lookahead guarded reductions of the
LOOKAHEADS_RULE. For each rule LOOKAHEADS_RULE[R], LOOKAHEADS[R]
is the bitset of the lookaheads enabling this reduction. */
int nlookaheads;
bitsetv lookaheads;
rule_t **lookaheads_rule;
/* If some conflicts were solved thanks to precedence/associativity, /* If some conflicts were solved thanks to precedence/associativity,
a human readable description of the resolution. */ a human readable description of the resolution. */
const char *solved_conflicts; const char *solved_conflicts;
@@ -234,6 +224,8 @@ void state_transitions_set PARAMS ((state_t *state,
void state_reductions_set PARAMS ((state_t *state, void state_reductions_set PARAMS ((state_t *state,
int num, rule_t **reductions)); int num, rule_t **reductions));
int state_reduction_find PARAMS ((state_t *state, rule_t *rule));
/* Set the errs of STATE. */ /* Set the errs of STATE. */
void state_errs_set PARAMS ((state_t *state, void state_errs_set PARAMS ((state_t *state,
int num, symbol_t **errs)); int num, symbol_t **errs));

View File

@@ -239,6 +239,7 @@ static void
conflict_row (state_t *state) conflict_row (state_t *state)
{ {
int i, j; int i, j;
reductions_t *reds = state->reductions;
if (! glr_parser) if (! glr_parser)
return; return;
@@ -250,14 +251,13 @@ conflict_row (state_t *state)
/* Find all reductions for token J, and record all that do not /* Find all reductions for token J, and record all that do not
match ACTROW[J]. */ match ACTROW[J]. */
for (i = 0; i < state->nlookaheads; i += 1) for (i = 0; i < reds->num; i += 1)
if (bitset_test (state->lookaheads[i], j) if (bitset_test (reds->lookaheads[i], j)
&& (actrow[j] && (actrow[j]
!= rule_number_as_item_number (state->lookaheads_rule[i]->number))) != rule_number_as_item_number (reds->rules[i]->number)))
{ {
assert (conflict_list_free > 0); assert (conflict_list_free > 0);
conflict_list[conflict_list_cnt] conflict_list[conflict_list_cnt] = reds->rules[i]->number + 1;
= state->lookaheads_rule[i]->number + 1;
conflict_list_cnt += 1; conflict_list_cnt += 1;
conflict_list_free -= 1; conflict_list_free -= 1;
} }
@@ -304,22 +304,23 @@ action_row (state_t *state)
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
actrow[i] = conflrow[i] = 0; actrow[i] = conflrow[i] = 0;
if (redp->num >= 1) if (redp->lookaheads)
{ {
int j; int j;
bitset_iterator biter; bitset_iterator biter;
/* loop over all the rules available here which require /* loop over all the rules available here which require
lookahead */ lookahead (in reverse order to give precedence to the first
for (i = state->nlookaheads - 1; i >= 0; --i) rule) */
for (i = redp->num - 1; i >= 0; --i)
/* and find each token which the rule finds acceptable /* and find each token which the rule finds acceptable
to come next */ to come next */
BITSET_FOR_EACH (biter, state->lookaheads[i], j, 0) BITSET_FOR_EACH (biter, redp->lookaheads[i], j, 0)
{ {
/* and record this rule as the rule to use if that /* and record this rule as the rule to use if that
token follows. */ token follows. */
if (actrow[j] != 0) if (actrow[j] != 0)
conflicted = conflrow[j] = 1; conflicted = conflrow[j] = 1;
actrow[j] = rule_number_as_item_number (state->lookaheads_rule[i]->number); actrow[j] = rule_number_as_item_number (redp->rules[i]->number);
} }
} }
@@ -359,10 +360,10 @@ action_row (state_t *state)
else else
{ {
int max = 0; int max = 0;
for (i = 0; i < state->nlookaheads; i++) for (i = 0; i < redp->num; i++)
{ {
int count = 0; int count = 0;
rule_t *rule = state->lookaheads_rule[i]; rule_t *rule = redp->rules[i];
symbol_number_t j; symbol_number_t j;
for (j = 0; j < ntokens; j++) for (j = 0; j < ntokens; j++)