mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-14 23:03:04 +00:00
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:
25
ChangeLog
25
ChangeLog
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
179
src/lalr.c
179
src/lalr.c
@@ -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,68 +324,72 @@ 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;
|
int k;
|
||||||
nLA = 0;
|
int nlookaheads = 0;
|
||||||
|
reductions_t *rp = state->reductions;
|
||||||
|
transitions_t *sp = state->transitions;
|
||||||
|
|
||||||
/* Count */
|
/* We need a lookahead either to distinguish different
|
||||||
for (i = 0; i < nstates; i++)
|
reductions (i.e., there are two or more), or to distinguish a
|
||||||
{
|
reduction from a shift. Otherwise, it is straightforward,
|
||||||
int k;
|
and the state is `consistent'. */
|
||||||
int nlookaheads = 0;
|
if (rp->num > 1
|
||||||
reductions_t *rp = states[i]->reductions;
|
|| (rp->num == 1 && sp->num &&
|
||||||
transitions_t *sp = states[i]->transitions;
|
!TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0)))
|
||||||
|
nlookaheads += rp->num;
|
||||||
|
else
|
||||||
|
state->consistent = 1;
|
||||||
|
|
||||||
/* We need a lookahead either to distinguish different
|
for (k = 0; k < sp->num; k++)
|
||||||
reductions (i.e., there are two or more), or to distinguish a
|
if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k))
|
||||||
reduction from a shift. Otherwise, it is straightforward,
|
{
|
||||||
and the state is `consistent'. */
|
state->consistent = 0;
|
||||||
if (rp->num > 1
|
break;
|
||||||
|| (rp->num == 1 && sp->num &&
|
}
|
||||||
!TRANSITION_IS_DISABLED (sp, 0) && TRANSITION_IS_SHIFT (sp, 0)))
|
|
||||||
nlookaheads += rp->num;
|
|
||||||
else
|
|
||||||
states[i]->consistent = 1;
|
|
||||||
|
|
||||||
for (k = 0; k < sp->num; k++)
|
return nlookaheads;
|
||||||
if (!TRANSITION_IS_DISABLED (sp, k) && TRANSITION_IS_ERROR (sp, k))
|
|
||||||
{
|
|
||||||
states[i]->consistent = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
states[i]->nlookaheads = 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,18 +406,26 @@ 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",
|
{
|
||||||
k, symbols[k]->tag,
|
fprintf (out, " on %d (%s) -> rule %d\n",
|
||||||
states[i]->lookaheads_rule[j]->number);
|
k, symbols[k]->tag,
|
||||||
};
|
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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 ();
|
||||||
|
|||||||
101
src/print.c
101
src/print.c
@@ -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,25 +322,27 @@ 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"));
|
||||||
for (i = 0; i < ntokens; i++)
|
|
||||||
{
|
|
||||||
int count = bitset_test (shiftset, i);
|
|
||||||
|
|
||||||
for (j = 0; j < state->nlookaheads; ++j)
|
if (redp->lookaheads)
|
||||||
if (bitset_test (state->lookaheads[j], i))
|
for (i = 0; i < ntokens; i++)
|
||||||
{
|
{
|
||||||
if (count == 0)
|
int count = bitset_test (shiftset, i);
|
||||||
{
|
|
||||||
if (state->lookaheads_rule[j] != default_rule)
|
for (j = 0; j < redp->num; ++j)
|
||||||
|
if (bitset_test (redp->lookaheads[j], i))
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
if (redp->rules[j] != default_rule)
|
||||||
|
max_length (&width, symbols[i]->tag);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
max_length (&width, symbols[i]->tag);
|
max_length (&width, symbols[i]->tag);
|
||||||
count++;
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
max_length (&width, symbols[i]->tag);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nothing to report. */
|
/* Nothing to report. */
|
||||||
if (!width)
|
if (!width)
|
||||||
@@ -350,37 +352,38 @@ print_reductions (FILE *out, state_t *state)
|
|||||||
width += 2;
|
width += 2;
|
||||||
|
|
||||||
/* Report lookaheads (or $default) and reductions. */
|
/* Report lookaheads (or $default) and reductions. */
|
||||||
for (i = 0; i < ntokens; i++)
|
if (redp->lookaheads)
|
||||||
{
|
for (i = 0; i < ntokens; i++)
|
||||||
int defaulted = 0;
|
{
|
||||||
int count = bitset_test (shiftset, i);
|
int defaulted = 0;
|
||||||
|
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,
|
||||||
|
symbols[i]->tag,
|
||||||
|
redp->rules[j], TRUE);
|
||||||
|
else
|
||||||
|
defaulted = 1;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (defaulted)
|
||||||
|
print_reduction (out, width,
|
||||||
|
symbols[i]->tag,
|
||||||
|
default_rule, TRUE);
|
||||||
|
defaulted = 0;
|
||||||
print_reduction (out, width,
|
print_reduction (out, width,
|
||||||
symbols[i]->tag,
|
symbols[i]->tag,
|
||||||
state->lookaheads_rule[j], TRUE);
|
redp->rules[j], FALSE);
|
||||||
else
|
}
|
||||||
defaulted = 1;
|
}
|
||||||
count++;
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (defaulted)
|
|
||||||
print_reduction (out, width,
|
|
||||||
symbols[i]->tag,
|
|
||||||
default_rule, TRUE);
|
|
||||||
defaulted = 0;
|
|
||||||
print_reduction (out, width,
|
|
||||||
symbols[i]->tag,
|
|
||||||
state->lookaheads_rule[j], FALSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (default_rule)
|
if (default_rule)
|
||||||
print_reduction (out, width,
|
print_reduction (out, width,
|
||||||
|
|||||||
@@ -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)
|
|
||||||
{
|
{
|
||||||
int j, k;
|
/* Find the reduction we are handling. */
|
||||||
bitset_iterator biter;
|
reductions_t *reds = state->reductions;
|
||||||
int nlookaheads = 0;
|
int redno = state_reduction_find (state, &rules[rule]);
|
||||||
|
|
||||||
/* Look for lookaheads corresponding to this rule. */
|
/* Print them if there are. */
|
||||||
for (j = 0; j < state->nlookaheads; ++j)
|
if (reds->lookaheads && redno != -1)
|
||||||
BITSET_FOR_EACH (biter, state->lookaheads[j], k, 0)
|
|
||||||
if (state->lookaheads_rule[j]->number == rule)
|
|
||||||
nlookaheads++;
|
|
||||||
|
|
||||||
if (nlookaheads)
|
|
||||||
{
|
{
|
||||||
obstack_sgrow (oout, " [");
|
bitset_iterator biter;
|
||||||
for (j = 0; j < state->nlookaheads; ++j)
|
int k;
|
||||||
BITSET_FOR_EACH (biter, state->lookaheads[j], k, 0)
|
int not_first = 0;
|
||||||
if (state->lookaheads_rule[j]->number == rule)
|
obstack_sgrow (oout, "[");
|
||||||
obstack_fgrow2 (oout, "%s%s",
|
BITSET_FOR_EACH (biter, reds->lookaheads[redno], k, 0)
|
||||||
symbols[k]->tag,
|
obstack_fgrow2 (oout, "%s%s",
|
||||||
--nlookaheads ? ", " : "");
|
not_first++ ? ", " : "",
|
||||||
|
symbols[k]->tag);
|
||||||
obstack_sgrow (oout, "]");
|
obstack_sgrow (oout, "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
43
src/state.c
43
src/state.c
@@ -100,8 +100,8 @@ errs_new (int num, symbol_t **tokens)
|
|||||||
| 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 ((sizeof (reductions_t) \
|
(reductions_t *) xcalloc ((sizeof (reductions_t) \
|
||||||
+ (Nreductions - 1) * sizeof (rule_t *)), 1)
|
+ (Nreductions - 1) * sizeof (rule_t *)), 1)
|
||||||
|
|
||||||
static reductions_t *
|
static reductions_t *
|
||||||
@@ -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)
|
fprintf (out, "%s%s",
|
||||||
if (state->lookaheads_rule[j] == rule)
|
not_first++ ? ", " : "",
|
||||||
fprintf (out, "%s%s",
|
symbols[k]->tag);
|
||||||
symbols[k]->tag,
|
|
||||||
--nlookaheads ? ", " : "");
|
|
||||||
fprintf (out, "]");
|
fprintf (out, "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/state.h
16
src/state.h
@@ -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));
|
||||||
|
|||||||
25
src/tables.c
25
src/tables.c
@@ -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++)
|
||||||
|
|||||||
Reference in New Issue
Block a user