mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
symbols: improve symbol aliasing
Rather than having duplicate info in the symbol and the alias that has to be resolved later on, both the symbol and the alias have a common pointer to a separate structure containing this info. * src/symtab.h (sym_content): New structure. * src/symtab.c (sym_content_new, sym_content_free, symbol_free): New * src/AnnotationList.c, src/conflicts.c, src/gram.c, src/gram.h, * src/graphviz.c, src/ielr.c, src/output.c, src/parse-gram.y, src/print.c * src/print-xml.c, src/print_graph.c, src/reader.c, src/reduce.c, * src/state.h, src/symlist.c, src/symtab.c, src/symtab.h, src/tables.c: Adjust. * tests/input.at: Fix expectations (order changes).
This commit is contained in:
committed by
Akim Demaille
parent
c4aa4ff541
commit
a728075710
@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
|
||||
{
|
||||
symbol_number contribution_token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->number;
|
||||
->content->number;
|
||||
if (AnnotationList__isContributionAlways (self, ci))
|
||||
{
|
||||
annotation_node->contributions[ci] = NULL;
|
||||
@@ -549,7 +549,7 @@ AnnotationList__compute_from_inadequacies (
|
||||
does discard annotations in the simplest case of a S/R
|
||||
conflict with no token precedence. */
|
||||
aver (!bitset_test (shift_tokens, conflicted_token)
|
||||
|| symbols[conflicted_token]->prec);
|
||||
|| symbols[conflicted_token]->content->prec);
|
||||
++annotation_counts[s->number];
|
||||
if (contribution_count > *max_contributionsp)
|
||||
*max_contributionsp = contribution_count;
|
||||
@@ -595,7 +595,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
|
||||
{
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (a->inadequacyNode, ci)
|
||||
->number;
|
||||
->content->number;
|
||||
{
|
||||
int j;
|
||||
for (j = 0; j < spaces+2; ++j)
|
||||
@@ -644,7 +644,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
|
||||
Sbitset biter;
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->number;
|
||||
->content->number;
|
||||
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
||||
bitset_set (lookahead_filter[item], token);
|
||||
}
|
||||
@@ -679,7 +679,8 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
|
||||
return false;
|
||||
{
|
||||
symbol_number token =
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number;
|
||||
InadequacyList__getContributionToken (self->inadequacyNode, ci)
|
||||
->content->number;
|
||||
Sbitset__Index item;
|
||||
Sbitset biter;
|
||||
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
|
||||
@@ -709,7 +710,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
ContributionIndex ci;
|
||||
int actioni;
|
||||
ContributionIndex ci_rr_dominator = ContributionIndex__none;
|
||||
int shift_precedence = token->prec;
|
||||
int shift_precedence = token->content->prec;
|
||||
|
||||
/* If the token has no precedence set, shift is always chosen. */
|
||||
if (!shift_precedence)
|
||||
@@ -739,7 +740,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
if (reduce_precedence
|
||||
&& (reduce_precedence < shift_precedence
|
||||
|| (reduce_precedence == shift_precedence
|
||||
&& token->assoc == right_assoc)))
|
||||
&& token->content->assoc == right_assoc)))
|
||||
continue;
|
||||
if (!AnnotationList__stateMakesContribution (self, nitems, ci,
|
||||
lookaheads))
|
||||
@@ -747,7 +748,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
|
||||
/* This uneliminated reduction contributes, so see if it can cause
|
||||
an error action. */
|
||||
if (reduce_precedence == shift_precedence
|
||||
&& token->assoc == non_assoc)
|
||||
&& token->content->assoc == non_assoc)
|
||||
{
|
||||
/* It's not possible to find split-stable domination over
|
||||
shift after a potential %nonassoc. */
|
||||
|
||||
@@ -104,7 +104,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
case shift_resolution:
|
||||
obstack_printf (&solved_conflicts_obstack,
|
||||
" (%s < %s)",
|
||||
r->prec->tag,
|
||||
r->prec->symbol->tag,
|
||||
symbols[token]->tag);
|
||||
break;
|
||||
|
||||
@@ -112,7 +112,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
obstack_printf (&solved_conflicts_obstack,
|
||||
" (%s < %s)",
|
||||
symbols[token]->tag,
|
||||
r->prec->tag);
|
||||
r->prec->symbol->tag);
|
||||
break;
|
||||
|
||||
case left_resolution:
|
||||
@@ -176,7 +176,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
case shift_resolution:
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%s < %s",
|
||||
xml_escape_n (0, r->prec->tag),
|
||||
xml_escape_n (0, r->prec->symbol->tag),
|
||||
xml_escape_n (1, symbols[token]->tag));
|
||||
break;
|
||||
|
||||
@@ -184,7 +184,7 @@ log_resolution (rule *r, symbol_number token,
|
||||
obstack_printf (&solved_conflicts_xml_obstack,
|
||||
"%s < %s",
|
||||
xml_escape_n (0, symbols[token]->tag),
|
||||
xml_escape_n (1, r->prec->tag));
|
||||
xml_escape_n (1, r->prec->symbol->tag));
|
||||
break;
|
||||
|
||||
case left_resolution:
|
||||
@@ -269,18 +269,18 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
for (i = 0; i < ntokens; i++)
|
||||
if (bitset_test (lookahead_tokens, i)
|
||||
&& bitset_test (lookahead_set, i)
|
||||
&& symbols[i]->prec)
|
||||
&& symbols[i]->content->prec)
|
||||
{
|
||||
/* Shift-reduce conflict occurs for token number i
|
||||
and it has a precedence.
|
||||
The precedence of shifting is that of token i. */
|
||||
if (symbols[i]->prec < redprec)
|
||||
if (symbols[i]->content->prec < redprec)
|
||||
{
|
||||
register_precedence (redrule->prec->number, i);
|
||||
log_resolution (redrule, i, reduce_resolution);
|
||||
flush_shift (s, i);
|
||||
}
|
||||
else if (symbols[i]->prec > redprec)
|
||||
else if (symbols[i]->content->prec > redprec)
|
||||
{
|
||||
register_precedence (i, redrule->prec->number);
|
||||
log_resolution (redrule, i, shift_resolution);
|
||||
@@ -294,7 +294,7 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
|
||||
For right associativity, keep only the shift.
|
||||
For nonassociativity, keep neither. */
|
||||
|
||||
switch (symbols[i]->assoc)
|
||||
switch (symbols[i]->content->assoc)
|
||||
{
|
||||
case undef_assoc:
|
||||
abort ();
|
||||
|
||||
16
src/gram.c
16
src/gram.c
@@ -65,19 +65,19 @@ rule_useless_in_parser_p (rule const *r)
|
||||
}
|
||||
|
||||
void
|
||||
rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out)
|
||||
rule_lhs_print (rule const *r, sym_content const *previous_lhs, FILE *out)
|
||||
{
|
||||
fprintf (out, " %3d ", r->number);
|
||||
if (previous_lhs != r->lhs)
|
||||
fprintf (out, "%s:", r->lhs->tag);
|
||||
fprintf (out, "%s:", r->lhs->symbol->tag);
|
||||
else
|
||||
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), "");
|
||||
fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
|
||||
}
|
||||
|
||||
void
|
||||
rule_lhs_print_xml (rule const *r, FILE *out, int level)
|
||||
{
|
||||
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->tag);
|
||||
xml_printf (out, level, "<lhs>%s</lhs>", r->lhs->symbol->tag);
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -158,7 +158,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
|
||||
{
|
||||
rule_number r;
|
||||
bool first = true;
|
||||
symbol *previous_lhs = NULL;
|
||||
sym_content *previous_lhs = NULL;
|
||||
|
||||
/* rule # : LHS -> RHS */
|
||||
for (r = 0; r < nrules + nuseless_productions; r++)
|
||||
@@ -209,7 +209,7 @@ grammar_rules_print_xml (FILE *out, int level)
|
||||
rules[r].number, usefulness);
|
||||
if (rules[r].precsym)
|
||||
fprintf (out, " percent_prec=\"%s\"",
|
||||
xml_escape (rules[r].precsym->tag));
|
||||
xml_escape (rules[r].precsym->symbol->tag));
|
||||
fputs (">\n", out);
|
||||
}
|
||||
rule_lhs_print_xml (&rules[r], out, level + 3);
|
||||
@@ -239,7 +239,7 @@ grammar_dump (FILE *out, const char *title)
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
fprintf (out, "%5d %5d %5d %s\n",
|
||||
i,
|
||||
symbols[i]->prec, symbols[i]->assoc,
|
||||
symbols[i]->content->prec, symbols[i]->content->assoc,
|
||||
symbols[i]->tag);
|
||||
fprintf (out, "\n\n");
|
||||
}
|
||||
@@ -280,7 +280,7 @@ grammar_dump (FILE *out, const char *title)
|
||||
rule_number r;
|
||||
for (r = 0; r < nrules + nuseless_productions; r++)
|
||||
{
|
||||
fprintf (out, "%-5d %s:", r, rules[r].lhs->tag);
|
||||
fprintf (out, "%-5d %s:", r, rules[r].lhs->symbol->tag);
|
||||
rule_rhs_print (&rules[r], out);
|
||||
fprintf (out, "\n");
|
||||
}
|
||||
|
||||
@@ -180,17 +180,17 @@ typedef struct
|
||||
except if some rules are useless. */
|
||||
rule_number number;
|
||||
|
||||
symbol *lhs;
|
||||
sym_content *lhs;
|
||||
item_number *rhs;
|
||||
|
||||
/* This symbol provides both the associativity, and the precedence. */
|
||||
symbol *prec;
|
||||
sym_content *prec;
|
||||
|
||||
int dprec;
|
||||
int merger;
|
||||
|
||||
/* This symbol was attached to the rule via %prec. */
|
||||
symbol *precsym;
|
||||
sym_content *precsym;
|
||||
|
||||
location location;
|
||||
bool useful;
|
||||
@@ -220,7 +220,8 @@ bool rule_useless_in_parser_p (rule const *r);
|
||||
/* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
|
||||
already displayed (by a previous call for another rule), avoid
|
||||
useless repetitions. */
|
||||
void rule_lhs_print (rule const *r, symbol const *previous_lhs, FILE *out);
|
||||
void rule_lhs_print (rule const *r, sym_content const *previous_lhs,
|
||||
FILE *out);
|
||||
void rule_lhs_print_xml (rule const *r, FILE *out, int level);
|
||||
|
||||
/* Return the length of the RHS. */
|
||||
|
||||
@@ -93,7 +93,7 @@ no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
|
||||
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
|
||||
for (n = 0; n < s->errs->num; ++n)
|
||||
if (s->errs->symbols[n])
|
||||
bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
|
||||
bitset_set (*no_reduce_set, s->errs->symbols[n]->content->number);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -424,7 +424,7 @@ ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item,
|
||||
if (item_number_is_rule_number (ritem[s->items[item] - 2]))
|
||||
{
|
||||
state **predecessor;
|
||||
aver (lhs != accept->number);
|
||||
aver (lhs != accept->content->number);
|
||||
for (predecessor = predecessors[s->number];
|
||||
*predecessor;
|
||||
++predecessor)
|
||||
@@ -580,7 +580,7 @@ typedef struct state_list {
|
||||
static void
|
||||
ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
|
||||
bitsetv always_follows, state_list *s,
|
||||
symbol *n, bitset follow_set)
|
||||
sym_content *n, bitset follow_set)
|
||||
{
|
||||
goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
|
||||
bitset_copy (follow_set, always_follows[n_goto]);
|
||||
|
||||
22
src/output.c
22
src/output.c
@@ -149,7 +149,7 @@ prepare_symbols (void)
|
||||
MUSCLE_INSERT_INT ("tokens_number", ntokens);
|
||||
MUSCLE_INSERT_INT ("nterms_number", nvars);
|
||||
MUSCLE_INSERT_INT ("symbols_number", nsyms);
|
||||
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->number);
|
||||
MUSCLE_INSERT_INT ("undef_token_number", undeftoken->content->number);
|
||||
MUSCLE_INSERT_INT ("user_token_number_max", max_user_token_number);
|
||||
|
||||
muscle_insert_symbol_number_table ("translate",
|
||||
@@ -197,7 +197,7 @@ prepare_symbols (void)
|
||||
int i;
|
||||
int *values = xnmalloc (ntokens, sizeof *values);
|
||||
for (i = 0; i < ntokens; ++i)
|
||||
values[i] = symbols[i]->user_token_number;
|
||||
values[i] = symbols[i]->content->user_token_number;
|
||||
muscle_insert_int_table ("toknum", values,
|
||||
values[0], 1, ntokens);
|
||||
free (values);
|
||||
@@ -283,9 +283,9 @@ prepare_states (void)
|
||||
static int
|
||||
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs)
|
||||
{
|
||||
int res = uniqstr_cmp ((*lhs)->type_name, (*rhs)->type_name);
|
||||
int res = uniqstr_cmp ((*lhs)->content->type_name, (*rhs)->content->type_name);
|
||||
if (!res)
|
||||
res = (*lhs)->number - (*rhs)->number;
|
||||
res = (*lhs)->content->number - (*rhs)->content->number;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -320,8 +320,9 @@ type_names_output (FILE *out)
|
||||
/* The index of the first symbol of the current type-name. */
|
||||
int i0 = i;
|
||||
fputs (i ? ",\n[" : "[", out);
|
||||
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i)
|
||||
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number);
|
||||
for (; i < nsyms
|
||||
&& syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
|
||||
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
|
||||
fputs ("]", out);
|
||||
}
|
||||
fputs ("])\n\n", out);
|
||||
@@ -428,20 +429,21 @@ prepare_symbol_definitions (void)
|
||||
MUSCLE_INSERT_STRING (key, sym->tag);
|
||||
|
||||
SET_KEY ("user_number");
|
||||
MUSCLE_INSERT_INT (key, sym->user_token_number);
|
||||
MUSCLE_INSERT_INT (key, sym->content->user_token_number);
|
||||
|
||||
SET_KEY ("is_token");
|
||||
MUSCLE_INSERT_INT (key,
|
||||
i < ntokens && sym != errtoken && sym != undeftoken);
|
||||
|
||||
SET_KEY ("number");
|
||||
MUSCLE_INSERT_INT (key, sym->number);
|
||||
MUSCLE_INSERT_INT (key, sym->content->number);
|
||||
|
||||
SET_KEY ("has_type");
|
||||
MUSCLE_INSERT_INT (key, !!sym->type_name);
|
||||
MUSCLE_INSERT_INT (key, !!sym->content->type_name);
|
||||
|
||||
SET_KEY ("type");
|
||||
MUSCLE_INSERT_STRING (key, sym->type_name ? sym->type_name : "");
|
||||
MUSCLE_INSERT_STRING (key, sym->content->type_name
|
||||
? sym->content->type_name : "");
|
||||
|
||||
{
|
||||
int j;
|
||||
|
||||
@@ -260,7 +260,7 @@ print_reductions (FILE *out, int level, state *s)
|
||||
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
||||
for (i = 0; i < s->errs->num; ++i)
|
||||
if (s->errs->symbols[i])
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
|
||||
|
||||
if (default_reduction)
|
||||
report = true;
|
||||
@@ -388,11 +388,11 @@ print_grammar (FILE *out, int level)
|
||||
/* Terminals */
|
||||
xml_puts (out, level + 1, "<terminals>");
|
||||
for (i = 0; i < max_user_token_number + 1; i++)
|
||||
if (token_translations[i] != undeftoken->number)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
{
|
||||
char const *tag = symbols[token_translations[i]]->tag;
|
||||
int precedence = symbols[token_translations[i]]->prec;
|
||||
assoc associativity = symbols[token_translations[i]]->assoc;
|
||||
int precedence = symbols[token_translations[i]]->content->prec;
|
||||
assoc associativity = symbols[token_translations[i]]->content->assoc;
|
||||
xml_indent (out, level + 2);
|
||||
fprintf (out,
|
||||
"<terminal symbol-number=\"%d\" token-number=\"%d\""
|
||||
|
||||
@@ -72,7 +72,7 @@ print_core (FILE *out, state *s)
|
||||
size_t i;
|
||||
item_number *sitems = s->items;
|
||||
size_t snritems = s->nitems;
|
||||
symbol *previous_lhs = NULL;
|
||||
sym_content *previous_lhs = NULL;
|
||||
|
||||
/* Output all the items of a state, not only its kernel. */
|
||||
if (report_flag & report_itemsets)
|
||||
@@ -223,7 +223,8 @@ print_reduction (FILE *out, size_t width,
|
||||
if (!enabled)
|
||||
fputc ('[', out);
|
||||
if (r->number)
|
||||
fprintf (out, _("reduce using rule %d (%s)"), r->number, r->lhs->tag);
|
||||
fprintf (out, _("reduce using rule %d (%s)"), r->number,
|
||||
r->lhs->symbol->tag);
|
||||
else
|
||||
fprintf (out, _("accept"));
|
||||
if (!enabled)
|
||||
@@ -257,7 +258,7 @@ print_reductions (FILE *out, state *s)
|
||||
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
|
||||
for (i = 0; i < s->errs->num; ++i)
|
||||
if (s->errs->symbols[i])
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->number);
|
||||
bitset_set (no_reduce_set, s->errs->symbols[i]->content->number);
|
||||
|
||||
/* Compute the width of the lookahead token column. */
|
||||
if (default_reduction)
|
||||
@@ -408,7 +409,7 @@ print_grammar (FILE *out)
|
||||
/* TERMINAL (type #) : rule #s terminal is on RHS */
|
||||
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
|
||||
for (i = 0; i < max_user_token_number + 1; i++)
|
||||
if (token_translations[i] != undeftoken->number)
|
||||
if (token_translations[i] != undeftoken->content->number)
|
||||
{
|
||||
const char *tag = symbols[token_translations[i]]->tag;
|
||||
rule_number r;
|
||||
|
||||
@@ -46,7 +46,7 @@ static void
|
||||
print_core (struct obstack *oout, state *s)
|
||||
{
|
||||
item_number const *sitems = s->items;
|
||||
symbol *previous_lhs = NULL;
|
||||
sym_content *previous_lhs = NULL;
|
||||
size_t i;
|
||||
size_t snritems = s->nitems;
|
||||
|
||||
@@ -72,11 +72,12 @@ print_core (struct obstack *oout, state *s)
|
||||
r = &rules[item_number_as_rule_number (*sp)];
|
||||
|
||||
obstack_printf (oout, "%3d ", r->number);
|
||||
if (previous_lhs && UNIQSTR_EQ (previous_lhs->tag, r->lhs->tag))
|
||||
if (previous_lhs && UNIQSTR_EQ (previous_lhs->symbol->tag,
|
||||
r->lhs->symbol->tag))
|
||||
obstack_printf (oout, "%*s| ",
|
||||
(int) strlen (previous_lhs->tag), "");
|
||||
(int) strlen (previous_lhs->symbol->tag), "");
|
||||
else
|
||||
obstack_printf (oout, "%s: ", escape (r->lhs->tag));
|
||||
obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
|
||||
previous_lhs = r->lhs;
|
||||
|
||||
for (sp = r->rhs; sp < sp1; sp++)
|
||||
|
||||
53
src/reader.c
53
src/reader.c
@@ -240,13 +240,13 @@ grammar_current_rule_begin (symbol *lhs, location loc,
|
||||
current_rule = grammar_end;
|
||||
|
||||
/* Mark the rule's lhs as a nonterminal if not already so. */
|
||||
if (lhs->class == unknown_sym)
|
||||
if (lhs->content->class == unknown_sym)
|
||||
{
|
||||
lhs->class = nterm_sym;
|
||||
lhs->number = nvars;
|
||||
lhs->content->class = nterm_sym;
|
||||
lhs->content->number = nvars;
|
||||
++nvars;
|
||||
}
|
||||
else if (lhs->class == token_sym)
|
||||
else if (lhs->content->class == token_sym)
|
||||
complain (&loc, complaint, _("rule given for %s, which is a token"),
|
||||
lhs->tag);
|
||||
}
|
||||
@@ -292,15 +292,15 @@ grammar_rule_check (const symbol_list *r)
|
||||
|
||||
Don't worry about the default action if $$ is untyped, since $$'s
|
||||
value can't be used. */
|
||||
if (!r->action_props.code && r->content.sym->type_name)
|
||||
if (!r->action_props.code && r->content.sym->content->type_name)
|
||||
{
|
||||
symbol *first_rhs = r->next->content.sym;
|
||||
/* If $$ is being set in default way, report if any type mismatch. */
|
||||
if (first_rhs)
|
||||
{
|
||||
char const *lhs_type = r->content.sym->type_name;
|
||||
char const *lhs_type = r->content.sym->content->type_name;
|
||||
const char *rhs_type =
|
||||
first_rhs->type_name ? first_rhs->type_name : "";
|
||||
first_rhs->content->type_name ? first_rhs->content->type_name : "";
|
||||
if (!UNIQSTR_EQ (lhs_type, rhs_type))
|
||||
complain (&r->location, Wother,
|
||||
_("type clash on default action: <%s> != <%s>"),
|
||||
@@ -350,7 +350,8 @@ grammar_rule_check (const symbol_list *r)
|
||||
it for char literals and strings, which are always tokens. */
|
||||
if (r->ruleprec
|
||||
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"'
|
||||
&& r->ruleprec->status != declared && !r->ruleprec->prec)
|
||||
&& r->ruleprec->content->status != declared
|
||||
&& !r->ruleprec->content->prec)
|
||||
complain (&r->location, Wother,
|
||||
_("token for %%prec is not defined: %s"), r->ruleprec->tag);
|
||||
}
|
||||
@@ -517,8 +518,8 @@ grammar_current_rule_symbol_append (symbol *sym, location loc,
|
||||
p = grammar_symbol_append (sym, loc);
|
||||
if (name)
|
||||
assign_named_ref (p, name);
|
||||
if (sym->status == undeclared || sym->status == used)
|
||||
sym->status = needed;
|
||||
if (sym->content->status == undeclared || sym->content->status == used)
|
||||
sym->content->status = needed;
|
||||
}
|
||||
|
||||
/* Attach an ACTION to the current rule. */
|
||||
@@ -558,11 +559,11 @@ packgram (void)
|
||||
for (p = grammar; p; p = p->next)
|
||||
{
|
||||
symbol *ruleprec = p->ruleprec;
|
||||
record_merge_function_type (p->merger, p->content.sym->type_name,
|
||||
record_merge_function_type (p->merger, p->content.sym->content->type_name,
|
||||
p->merger_declaration_location);
|
||||
rules[ruleno].user_number = ruleno;
|
||||
rules[ruleno].number = ruleno;
|
||||
rules[ruleno].lhs = p->content.sym;
|
||||
rules[ruleno].lhs = p->content.sym->content;
|
||||
rules[ruleno].rhs = ritem + itemno;
|
||||
rules[ruleno].prec = NULL;
|
||||
rules[ruleno].dprec = p->dprec;
|
||||
@@ -604,11 +605,11 @@ packgram (void)
|
||||
/* item_number = symbol_number.
|
||||
But the former needs to contain more: negative rule numbers. */
|
||||
ritem[itemno++] =
|
||||
symbol_number_as_item_number (p->content.sym->number);
|
||||
symbol_number_as_item_number (p->content.sym->content->number);
|
||||
/* A rule gets by default the precedence and associativity
|
||||
of its last token. */
|
||||
if (p->content.sym->class == token_sym && default_prec)
|
||||
rules[ruleno].prec = p->content.sym;
|
||||
if (p->content.sym->content->class == token_sym && default_prec)
|
||||
rules[ruleno].prec = p->content.sym->content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,8 +617,8 @@ packgram (void)
|
||||
the specified symbol's precedence replaces the default. */
|
||||
if (ruleprec)
|
||||
{
|
||||
rules[ruleno].precsym = ruleprec;
|
||||
rules[ruleno].prec = ruleprec;
|
||||
rules[ruleno].precsym = ruleprec->content;
|
||||
rules[ruleno].prec = ruleprec->content;
|
||||
}
|
||||
/* An item ends by the rule number (negated). */
|
||||
ritem[itemno++] = rule_number_as_item_number (ruleno);
|
||||
@@ -647,19 +648,19 @@ reader (void)
|
||||
|
||||
/* Construct the accept symbol. */
|
||||
accept = symbol_get ("$accept", empty_location);
|
||||
accept->class = nterm_sym;
|
||||
accept->number = nvars++;
|
||||
accept->content->class = nterm_sym;
|
||||
accept->content->number = nvars++;
|
||||
|
||||
/* Construct the error token */
|
||||
errtoken = symbol_get ("error", empty_location);
|
||||
errtoken->class = token_sym;
|
||||
errtoken->number = ntokens++;
|
||||
errtoken->content->class = token_sym;
|
||||
errtoken->content->number = ntokens++;
|
||||
|
||||
/* Construct a token that represents all undefined literal tokens.
|
||||
It is always token number 2. */
|
||||
undeftoken = symbol_get ("$undefined", empty_location);
|
||||
undeftoken->class = token_sym;
|
||||
undeftoken->number = ntokens++;
|
||||
undeftoken->content->class = token_sym;
|
||||
undeftoken->content->number = ntokens++;
|
||||
|
||||
gram_in = xfopen (grammar_file, "r");
|
||||
|
||||
@@ -721,10 +722,10 @@ check_and_convert_grammar (void)
|
||||
if (!endtoken)
|
||||
{
|
||||
endtoken = symbol_get ("$end", empty_location);
|
||||
endtoken->class = token_sym;
|
||||
endtoken->number = 0;
|
||||
endtoken->content->class = token_sym;
|
||||
endtoken->content->number = 0;
|
||||
/* Value specified by POSIX. */
|
||||
endtoken->user_token_number = 0;
|
||||
endtoken->content->user_token_number = 0;
|
||||
}
|
||||
|
||||
/* Report any undefined symbols and consider them nonterminals. */
|
||||
|
||||
18
src/reduce.c
18
src/reduce.c
@@ -163,9 +163,9 @@ inaccessable_symbols (void)
|
||||
Pp = bitset_create (nrules, BITSET_FIXED);
|
||||
|
||||
/* If the start symbol isn't useful, then nothing will be useful. */
|
||||
if (bitset_test (N, accept->number - ntokens))
|
||||
if (bitset_test (N, accept->content->number - ntokens))
|
||||
{
|
||||
bitset_set (V, accept->number);
|
||||
bitset_set (V, accept->content->number);
|
||||
|
||||
while (1)
|
||||
{
|
||||
@@ -196,9 +196,9 @@ inaccessable_symbols (void)
|
||||
V = Vp;
|
||||
|
||||
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
|
||||
bitset_set (V, endtoken->number); /* end-of-input token */
|
||||
bitset_set (V, errtoken->number); /* error token */
|
||||
bitset_set (V, undeftoken->number); /* some undefined token */
|
||||
bitset_set (V, endtoken->content->number); /* end-of-input token */
|
||||
bitset_set (V, errtoken->content->number); /* error token */
|
||||
bitset_set (V, undeftoken->content->number); /* some undefined token */
|
||||
|
||||
bitset_free (P);
|
||||
P = Pp;
|
||||
@@ -298,7 +298,7 @@ nonterminals_reduce (void)
|
||||
if (!bitset_test (V, i))
|
||||
{
|
||||
nontermmap[i - ntokens] = n++;
|
||||
if (symbols[i]->status != used)
|
||||
if (symbols[i]->content->status != used)
|
||||
complain (&symbols[i]->location, Wother,
|
||||
_("nonterminal useless in grammar: %s"),
|
||||
symbols[i]->tag);
|
||||
@@ -310,7 +310,7 @@ nonterminals_reduce (void)
|
||||
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
|
||||
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
symbols[i]->number = nontermmap[i - ntokens];
|
||||
symbols[i]->content->number = nontermmap[i - ntokens];
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
|
||||
for (i = ntokens; i < nsyms; i++)
|
||||
@@ -328,7 +328,7 @@ nonterminals_reduce (void)
|
||||
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp
|
||||
- ntokens]);
|
||||
}
|
||||
accept->number = nontermmap[accept->number - ntokens];
|
||||
accept->content->number = nontermmap[accept->content->number - ntokens];
|
||||
}
|
||||
|
||||
nsyms -= nuseless_nonterminals;
|
||||
@@ -415,7 +415,7 @@ reduce_grammar (void)
|
||||
|
||||
reduce_print ();
|
||||
|
||||
if (!bitset_test (N, accept->number - ntokens))
|
||||
if (!bitset_test (N, accept->content->number - ntokens))
|
||||
complain (&startsymbol_location, fatal,
|
||||
_("start symbol %s does not derive any sentence"),
|
||||
startsymbol->tag);
|
||||
|
||||
@@ -135,7 +135,7 @@ typedef struct
|
||||
/* Is the TRANSITIONS->states[Num] labelled by the error token? */
|
||||
|
||||
# define TRANSITION_IS_ERROR(Transitions, Num) \
|
||||
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->number)
|
||||
(TRANSITION_SYMBOL (Transitions, Num) == errtoken->content->number)
|
||||
|
||||
/* When resolving a SR conflicts, if the reduction wins, the shift is
|
||||
disabled. */
|
||||
|
||||
@@ -205,7 +205,7 @@ symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
|
||||
return NULL;
|
||||
}
|
||||
aver (l->content_type == SYMLIST_SYMBOL);
|
||||
return l->content.sym->type_name;
|
||||
return l->content.sym->content->type_name;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -223,8 +223,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
|
||||
{
|
||||
case SYMLIST_SYMBOL:
|
||||
symbol_code_props_set (node->content.sym, kind, cprops);
|
||||
if (node->content.sym->status == undeclared)
|
||||
node->content.sym->status = used;
|
||||
if (node->content.sym->content->status == undeclared)
|
||||
node->content.sym->content->status = used;
|
||||
break;
|
||||
case SYMLIST_TYPE:
|
||||
semantic_type_code_props_set
|
||||
|
||||
295
src/symtab.c
295
src/symtab.c
@@ -58,6 +58,35 @@ static symgraph **prec_nodes;
|
||||
|
||||
bool *used_assoc = NULL;
|
||||
|
||||
/*--------------------------.
|
||||
| Create a new sym_content. |
|
||||
`--------------------------*/
|
||||
|
||||
static sym_content *
|
||||
sym_content_new (symbol *s)
|
||||
{
|
||||
sym_content *res = xmalloc (sizeof *res);
|
||||
|
||||
res->symbol = s;
|
||||
|
||||
res->type_name = NULL;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
||||
code_props_none_init (&res->props[i]);
|
||||
}
|
||||
|
||||
res->number = NUMBER_UNDEFINED;
|
||||
res->prec = 0;
|
||||
res->assoc = undef_assoc;
|
||||
res->user_token_number = USER_NUMBER_UNDEFINED;
|
||||
|
||||
res->class = unknown_sym;
|
||||
res->status = undeclared;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*---------------------------------.
|
||||
| Create a new symbol, named TAG. |
|
||||
`---------------------------------*/
|
||||
@@ -76,22 +105,9 @@ symbol_new (uniqstr tag, location loc)
|
||||
|
||||
res->tag = tag;
|
||||
res->location = loc;
|
||||
|
||||
res->type_name = NULL;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
||||
code_props_none_init (&res->props[i]);
|
||||
}
|
||||
|
||||
res->number = NUMBER_UNDEFINED;
|
||||
res->prec = 0;
|
||||
res->assoc = undef_assoc;
|
||||
res->user_token_number = USER_NUMBER_UNDEFINED;
|
||||
|
||||
res->alias = NULL;
|
||||
res->class = unknown_sym;
|
||||
res->status = undeclared;
|
||||
res->content = sym_content_new (res);
|
||||
res->is_alias = false;
|
||||
|
||||
if (nsyms == SYMBOL_NUMBER_MAXIMUM)
|
||||
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
|
||||
@@ -100,6 +116,30 @@ symbol_new (uniqstr tag, location loc)
|
||||
return res;
|
||||
}
|
||||
|
||||
/*--------------------.
|
||||
| Free a sym_content. |
|
||||
`--------------------*/
|
||||
|
||||
static void
|
||||
sym_content_free (sym_content *sym)
|
||||
{
|
||||
free (sym);
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------.
|
||||
| Free a symbol and its associated content if appropriate. |
|
||||
`---------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
symbol_free (void *ptr)
|
||||
{
|
||||
symbol *sym = (symbol *)ptr;
|
||||
if (!sym->is_alias)
|
||||
sym_content_free (sym->content);
|
||||
free (sym);
|
||||
}
|
||||
|
||||
char const *
|
||||
code_props_type_string (code_props_type kind)
|
||||
{
|
||||
@@ -141,12 +181,12 @@ semantic_type_new (uniqstr tag, const location *loc)
|
||||
`-----------------*/
|
||||
|
||||
#define SYMBOL_ATTR_PRINT(Attr) \
|
||||
if (s->Attr) \
|
||||
fprintf (f, " %s { %s }", #Attr, s->Attr)
|
||||
if (s->content->Attr) \
|
||||
fprintf (f, " %s { %s }", #Attr, s->content->Attr)
|
||||
|
||||
#define SYMBOL_CODE_PRINT(Attr) \
|
||||
if (s->props[Attr].code) \
|
||||
fprintf (f, " %s { %s }", #Attr, s->props[Attr].code)
|
||||
if (s->content->props[Attr].code) \
|
||||
fprintf (f, " %s { %s }", #Attr, s->content->props[Attr].code)
|
||||
|
||||
void
|
||||
symbol_print (symbol const *s, FILE *f)
|
||||
@@ -193,7 +233,7 @@ is_identifier (uniqstr s)
|
||||
uniqstr
|
||||
symbol_id_get (symbol const *sym)
|
||||
{
|
||||
aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
|
||||
aver (sym->content->user_token_number != USER_NUMBER_HAS_STRING_ALIAS);
|
||||
if (sym->alias)
|
||||
sym = sym->alias;
|
||||
return is_identifier (sym->tag) ? sym->tag : 0;
|
||||
@@ -241,13 +281,13 @@ symbol_type_set (symbol *sym, uniqstr type_name, location loc)
|
||||
{
|
||||
if (type_name)
|
||||
{
|
||||
if (sym->type_name)
|
||||
symbol_redeclaration (sym, "%type", sym->type_location, loc);
|
||||
if (sym->content->type_name)
|
||||
symbol_redeclaration (sym, "%type", sym->content->type_location, loc);
|
||||
else
|
||||
{
|
||||
uniqstr_assert (type_name);
|
||||
sym->type_name = type_name;
|
||||
sym->type_location = loc;
|
||||
sym->content->type_name = type_name;
|
||||
sym->content->type_location = loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -260,12 +300,12 @@ void
|
||||
symbol_code_props_set (symbol *sym, code_props_type kind,
|
||||
code_props const *code)
|
||||
{
|
||||
if (sym->props[kind].code)
|
||||
if (sym->content->props[kind].code)
|
||||
symbol_redeclaration (sym, code_props_type_string (kind),
|
||||
sym->props[kind].location,
|
||||
sym->content->props[kind].location,
|
||||
code->location);
|
||||
else
|
||||
sym->props[kind] = *code;
|
||||
sym->content->props[kind] = *code;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------.
|
||||
@@ -293,14 +333,14 @@ code_props *
|
||||
symbol_code_props_get (symbol *sym, code_props_type kind)
|
||||
{
|
||||
/* Per-symbol code props. */
|
||||
if (sym->props[kind].code)
|
||||
return &sym->props[kind];
|
||||
if (sym->content->props[kind].code)
|
||||
return &sym->content->props[kind];
|
||||
|
||||
/* Per-type code props. */
|
||||
if (sym->type_name)
|
||||
if (sym->content->type_name)
|
||||
{
|
||||
code_props *code =
|
||||
&semantic_type_get (sym->type_name, NULL)->props[kind];
|
||||
&semantic_type_get (sym->content->type_name, NULL)->props[kind];
|
||||
if (code->code)
|
||||
return code;
|
||||
}
|
||||
@@ -308,8 +348,8 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
|
||||
/* Apply default code props's only to user-defined symbols. */
|
||||
if (sym->tag[0] != '$' && sym != errtoken)
|
||||
{
|
||||
code_props *code =
|
||||
&semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind];
|
||||
code_props *code = &semantic_type_get (sym->content->type_name ? "*" : "",
|
||||
NULL)->props[kind];
|
||||
if (code->code)
|
||||
return code;
|
||||
}
|
||||
@@ -324,16 +364,17 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
|
||||
void
|
||||
symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
|
||||
{
|
||||
sym_content *s = sym->content;
|
||||
if (a != undef_assoc)
|
||||
{
|
||||
if (sym->prec)
|
||||
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location,
|
||||
loc);
|
||||
if (s->prec)
|
||||
symbol_redeclaration (sym, assoc_to_string (a),
|
||||
s->prec_location, loc);
|
||||
else
|
||||
{
|
||||
sym->prec = prec;
|
||||
sym->assoc = a;
|
||||
sym->prec_location = loc;
|
||||
s->prec = prec;
|
||||
s->assoc = a;
|
||||
s->prec_location = loc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,26 +391,26 @@ void
|
||||
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
|
||||
{
|
||||
bool warned = false;
|
||||
if (sym->class != unknown_sym && sym->class != class)
|
||||
if (sym->content->class != unknown_sym && sym->content->class != class)
|
||||
{
|
||||
complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
|
||||
/* Don't report both "redefined" and "redeclared". */
|
||||
warned = true;
|
||||
}
|
||||
|
||||
if (class == nterm_sym && sym->class != nterm_sym)
|
||||
sym->number = nvars++;
|
||||
else if (class == token_sym && sym->number == NUMBER_UNDEFINED)
|
||||
sym->number = ntokens++;
|
||||
if (class == nterm_sym && sym->content->class != nterm_sym)
|
||||
sym->content->number = nvars++;
|
||||
else if (class == token_sym && sym->content->number == NUMBER_UNDEFINED)
|
||||
sym->content->number = ntokens++;
|
||||
|
||||
sym->class = class;
|
||||
sym->content->class = class;
|
||||
|
||||
if (declaring)
|
||||
{
|
||||
if (sym->status == declared && !warned)
|
||||
if (sym->content->status == declared && !warned)
|
||||
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
|
||||
else
|
||||
sym->status = declared;
|
||||
sym->content->status = declared;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,10 +424,7 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
|
||||
{
|
||||
int *user_token_numberp;
|
||||
|
||||
if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
|
||||
user_token_numberp = &sym->user_token_number;
|
||||
else
|
||||
user_token_numberp = &sym->alias->user_token_number;
|
||||
user_token_numberp = &sym->content->user_token_number;
|
||||
if (*user_token_numberp != USER_NUMBER_UNDEFINED
|
||||
&& *user_token_numberp != user_token_number)
|
||||
complain (&loc, complaint, _("redefining user token number of %s"),
|
||||
@@ -396,12 +434,12 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
|
||||
/* User defined $end token? */
|
||||
if (user_token_number == 0)
|
||||
{
|
||||
endtoken = sym;
|
||||
endtoken = sym->content->symbol;
|
||||
/* It is always mapped to 0, so it was already counted in
|
||||
NTOKENS. */
|
||||
if (endtoken->number != NUMBER_UNDEFINED)
|
||||
if (endtoken->content->number != NUMBER_UNDEFINED)
|
||||
--ntokens;
|
||||
endtoken->number = 0;
|
||||
endtoken->content->number = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,16 +452,17 @@ symbol_user_token_number_set (symbol *sym, int user_token_number, location loc)
|
||||
static inline bool
|
||||
symbol_check_defined (symbol *sym)
|
||||
{
|
||||
if (sym->class == unknown_sym)
|
||||
sym_content *s = sym->content;
|
||||
if (s->class == unknown_sym)
|
||||
{
|
||||
assert (sym->status != declared);
|
||||
assert (s->status != declared);
|
||||
complain (&sym->location,
|
||||
sym->status == needed ? complaint : Wother,
|
||||
s->status == needed ? complaint : Wother,
|
||||
_("symbol %s is used, but is not defined as a token"
|
||||
" and has no rules"),
|
||||
sym->tag);
|
||||
sym->class = nterm_sym;
|
||||
sym->number = nvars++;
|
||||
s->class = nterm_sym;
|
||||
s->number = nvars++;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -434,9 +473,9 @@ symbol_check_defined (symbol *sym)
|
||||
|
||||
/* Set the semantic type status associated to the current symbol to
|
||||
'declared' so that we could check semantic types unnecessary uses. */
|
||||
if (sym->type_name)
|
||||
if (s->type_name)
|
||||
{
|
||||
semantic_type *sem_type = semantic_type_get (sym->type_name, NULL);
|
||||
semantic_type *sem_type = semantic_type_get (s->type_name, NULL);
|
||||
if (sem_type)
|
||||
sem_type->status = declared;
|
||||
}
|
||||
@@ -493,71 +532,16 @@ symbol_make_alias (symbol *sym, symbol *str, location loc)
|
||||
_("symbol %s given more than one literal string"), sym->tag);
|
||||
else
|
||||
{
|
||||
str->class = token_sym;
|
||||
str->user_token_number = sym->user_token_number;
|
||||
sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS;
|
||||
sym_content_free (str->content);
|
||||
str->content = sym->content;
|
||||
str->content->symbol = str;
|
||||
str->is_alias = true;
|
||||
str->alias = sym;
|
||||
sym->alias = str;
|
||||
str->number = sym->number;
|
||||
symbol_type_set (str, sym->type_name, loc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------.
|
||||
| Check that THIS, and its alias, have same precedence and |
|
||||
| associativity. |
|
||||
`---------------------------------------------------------*/
|
||||
|
||||
static inline void
|
||||
symbol_check_alias_consistency (symbol *this)
|
||||
{
|
||||
symbol *sym = this;
|
||||
symbol *str = this->alias;
|
||||
|
||||
/* Check only the symbol in the symbol-string pair. */
|
||||
if (!(this->alias
|
||||
&& this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS))
|
||||
return;
|
||||
|
||||
if (str->type_name != sym->type_name)
|
||||
{
|
||||
if (str->type_name)
|
||||
symbol_type_set (sym, str->type_name, str->type_location);
|
||||
else
|
||||
symbol_type_set (str, sym->type_name, sym->type_location);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < CODE_PROPS_SIZE; ++i)
|
||||
if (str->props[i].code)
|
||||
symbol_code_props_set (sym, i, &str->props[i]);
|
||||
else if (sym->props[i].code)
|
||||
symbol_code_props_set (str, i, &sym->props[i]);
|
||||
}
|
||||
|
||||
if (sym->prec || str->prec)
|
||||
{
|
||||
if (str->prec)
|
||||
symbol_precedence_set (sym, str->prec, str->assoc,
|
||||
str->prec_location);
|
||||
else
|
||||
symbol_precedence_set (str, sym->prec, sym->assoc,
|
||||
sym->prec_location);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
symbol_check_alias_consistency_processor (void *this,
|
||||
void *null ATTRIBUTE_UNUSED)
|
||||
{
|
||||
symbol_check_alias_consistency (this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------.
|
||||
| Assign a symbol number, and write the definition of the token name |
|
||||
| into FDEFINES. Put in SYMBOLS. |
|
||||
@@ -566,13 +550,13 @@ symbol_check_alias_consistency_processor (void *this,
|
||||
static inline bool
|
||||
symbol_pack (symbol *this)
|
||||
{
|
||||
aver (this->number != NUMBER_UNDEFINED);
|
||||
if (this->class == nterm_sym)
|
||||
this->number += ntokens;
|
||||
else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
|
||||
aver (this->content->number != NUMBER_UNDEFINED);
|
||||
if (this->content->class == nterm_sym)
|
||||
this->content->number += ntokens;
|
||||
else if (this->content->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
|
||||
return true;
|
||||
|
||||
symbols[this->number] = this;
|
||||
symbols[this->content->number] = this->content->symbol;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -582,7 +566,6 @@ symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
|
||||
return symbol_pack (this);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
user_token_number_redeclaration (int num, symbol *first, symbol *second)
|
||||
{
|
||||
@@ -615,17 +598,18 @@ static inline bool
|
||||
symbol_translation (symbol *this)
|
||||
{
|
||||
/* Non-terminal? */
|
||||
if (this->class == token_sym
|
||||
&& this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS)
|
||||
if (this->content->class == token_sym
|
||||
&& !this->is_alias)
|
||||
{
|
||||
/* A token which translation has already been set? */
|
||||
if (token_translations[this->user_token_number] != undeftoken->number)
|
||||
/* A token which translation has already been set?*/
|
||||
if (token_translations[this->content->user_token_number]
|
||||
!= undeftoken->content->number)
|
||||
user_token_number_redeclaration
|
||||
(this->user_token_number,
|
||||
symbols[token_translations[this->user_token_number]],
|
||||
this);
|
||||
(this->content->user_token_number,
|
||||
symbols[token_translations[this->content->user_token_number]], this);
|
||||
else
|
||||
token_translations[this->user_token_number] = this->number;
|
||||
token_translations[this->content->user_token_number]
|
||||
= this->content->number;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -711,7 +695,7 @@ symbols_new (void)
|
||||
NULL,
|
||||
hash_symbol_hasher,
|
||||
hash_symbol_comparator,
|
||||
free);
|
||||
symbol_free);
|
||||
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
|
||||
NULL,
|
||||
hash_semantic_type_hasher,
|
||||
@@ -811,8 +795,8 @@ dummy_symbol_get (location loc)
|
||||
|
||||
sprintf (buf, "$@%d", ++dummy_count);
|
||||
sym = symbol_get (buf, loc);
|
||||
sym->class = nterm_sym;
|
||||
sym->number = nvars++;
|
||||
sym->content->class = nterm_sym;
|
||||
sym->content->number = nvars++;
|
||||
return sym;
|
||||
}
|
||||
|
||||
@@ -902,7 +886,7 @@ symbols_token_translations_init (void)
|
||||
max_user_token_number = 0;
|
||||
for (i = 0; i < ntokens; ++i)
|
||||
{
|
||||
symbol *this = symbols[i];
|
||||
sym_content *this = symbols[i]->content;
|
||||
if (this->user_token_number != USER_NUMBER_UNDEFINED)
|
||||
{
|
||||
if (this->user_token_number > max_user_token_number)
|
||||
@@ -914,8 +898,8 @@ symbols_token_translations_init (void)
|
||||
|
||||
/* If 256 is not used, assign it to error, to follow POSIX. */
|
||||
if (num_256_available_p
|
||||
&& errtoken->user_token_number == USER_NUMBER_UNDEFINED)
|
||||
errtoken->user_token_number = 256;
|
||||
&& errtoken->content->user_token_number == USER_NUMBER_UNDEFINED)
|
||||
errtoken->content->user_token_number = 256;
|
||||
|
||||
/* Set the missing user numbers. */
|
||||
if (max_user_token_number < 256)
|
||||
@@ -923,7 +907,7 @@ symbols_token_translations_init (void)
|
||||
|
||||
for (i = 0; i < ntokens; ++i)
|
||||
{
|
||||
symbol *this = symbols[i];
|
||||
sym_content *this = symbols[i]->content;
|
||||
if (this->user_token_number == USER_NUMBER_UNDEFINED)
|
||||
this->user_token_number = ++max_user_token_number;
|
||||
if (this->user_token_number > max_user_token_number)
|
||||
@@ -936,7 +920,7 @@ symbols_token_translations_init (void)
|
||||
/* Initialize all entries for literal tokens to the internal token
|
||||
number for $undefined, which represents all invalid inputs. */
|
||||
for (i = 0; i < max_user_token_number + 1; i++)
|
||||
token_translations[i] = undeftoken->number;
|
||||
token_translations[i] = undeftoken->content->number;
|
||||
symbols_do (symbol_translation_processor, NULL,
|
||||
symbol_table, &symbols_sorted);
|
||||
}
|
||||
@@ -950,9 +934,6 @@ symbols_token_translations_init (void)
|
||||
void
|
||||
symbols_pack (void)
|
||||
{
|
||||
symbols_do (symbol_check_alias_consistency_processor, NULL,
|
||||
symbol_table, &symbols_sorted);
|
||||
|
||||
symbols = xcalloc (nsyms, sizeof *symbols);
|
||||
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
|
||||
|
||||
@@ -971,9 +952,7 @@ symbols_pack (void)
|
||||
else
|
||||
{
|
||||
symbols[writei] = symbols[readi];
|
||||
symbols[writei]->number = writei;
|
||||
if (symbols[writei]->alias)
|
||||
symbols[writei]->alias->number = writei;
|
||||
symbols[writei]->content->number = writei;
|
||||
writei += 1;
|
||||
}
|
||||
}
|
||||
@@ -982,11 +961,11 @@ symbols_pack (void)
|
||||
|
||||
symbols_token_translations_init ();
|
||||
|
||||
if (startsymbol->class == unknown_sym)
|
||||
if (startsymbol->content->class == unknown_sym)
|
||||
complain (&startsymbol_location, fatal,
|
||||
_("the start symbol %s is undefined"),
|
||||
startsymbol->tag);
|
||||
else if (startsymbol->class == token_sym)
|
||||
else if (startsymbol->content->class == token_sym)
|
||||
complain (&startsymbol_location, fatal,
|
||||
_("the start symbol %s is a token"),
|
||||
startsymbol->tag);
|
||||
@@ -1123,9 +1102,9 @@ static inline bool
|
||||
is_assoc_useless (symbol *s)
|
||||
{
|
||||
return s
|
||||
&& s->assoc != undef_assoc
|
||||
&& s->assoc != precedence_assoc
|
||||
&& !used_assoc[s->number];
|
||||
&& s->content->assoc != undef_assoc
|
||||
&& s->content->assoc != precedence_assoc
|
||||
&& !used_assoc[s->content->number];
|
||||
}
|
||||
|
||||
/*-------------------------------.
|
||||
@@ -1157,19 +1136,19 @@ print_precedence_warnings (void)
|
||||
{
|
||||
symbol *s = symbols[i];
|
||||
if (s
|
||||
&& s->prec != 0
|
||||
&& s->content->prec != 0
|
||||
&& !prec_nodes[i]->pred
|
||||
&& !prec_nodes[i]->succ)
|
||||
{
|
||||
if (is_assoc_useless (s))
|
||||
complain (&s->prec_location, Wprecedence,
|
||||
complain (&s->content->prec_location, Wprecedence,
|
||||
_("useless precedence and associativity for %s"), s->tag);
|
||||
else if (s->assoc == precedence_assoc)
|
||||
complain (&s->prec_location, Wprecedence,
|
||||
else if (s->content->assoc == precedence_assoc)
|
||||
complain (&s->content->prec_location, Wprecedence,
|
||||
_("useless precedence for %s"), s->tag);
|
||||
}
|
||||
else if (is_assoc_useless (s))
|
||||
complain (&s->prec_location, Wprecedence,
|
||||
complain (&s->content->prec_location, Wprecedence,
|
||||
_("useless associativity for %s, use %%precedence"), s->tag);
|
||||
}
|
||||
free (used_assoc);
|
||||
|
||||
21
src/symtab.h
21
src/symtab.h
@@ -50,6 +50,7 @@ typedef int symbol_number;
|
||||
|
||||
|
||||
typedef struct symbol symbol;
|
||||
typedef struct sym_content sym_content;
|
||||
|
||||
/* Declaration status of a symbol.
|
||||
|
||||
@@ -82,8 +83,6 @@ enum code_props_type
|
||||
|
||||
enum { CODE_PROPS_SIZE = 2 };
|
||||
|
||||
/* When extending this structure, be sure to complete
|
||||
symbol_check_alias_consistency. */
|
||||
struct symbol
|
||||
{
|
||||
/** The key, name of the symbol. */
|
||||
@@ -91,6 +90,20 @@ struct symbol
|
||||
/** The location of its first occurrence. */
|
||||
location location;
|
||||
|
||||
/* Points to the other in the symbol-string pair for an alias. */
|
||||
symbol *alias;
|
||||
|
||||
/** Whether this symbol is the alias of another or not. */
|
||||
bool is_alias;
|
||||
|
||||
/** All the info about the pointed symbol is there. */
|
||||
sym_content *content;
|
||||
};
|
||||
|
||||
struct sym_content
|
||||
{
|
||||
symbol *symbol;
|
||||
|
||||
/** Its \c \%type.
|
||||
|
||||
Beware that this is the type_name as was entered by the user,
|
||||
@@ -117,10 +130,6 @@ struct symbol
|
||||
assoc assoc;
|
||||
int user_token_number;
|
||||
|
||||
/* Points to the other in the symbol-string pair for an alias.
|
||||
Special value USER_NUMBER_HAS_STRING_ALIAS in the symbol half of the
|
||||
symbol-string pair for an alias. */
|
||||
symbol *alias;
|
||||
symbol_class class;
|
||||
status status;
|
||||
};
|
||||
|
||||
@@ -290,7 +290,7 @@ action_row (state *s)
|
||||
|
||||
/* Do not use any default reduction if there is a shift for
|
||||
error */
|
||||
if (sym == errtoken->number)
|
||||
if (sym == errtoken->content->number)
|
||||
nodefault = true;
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ action_row (state *s)
|
||||
for (i = 0; i < errp->num; i++)
|
||||
{
|
||||
symbol *sym = errp->symbols[i];
|
||||
actrow[sym->number] = ACTION_NUMBER_MINIMUM;
|
||||
actrow[sym->content->number] = ACTION_NUMBER_MINIMUM;
|
||||
}
|
||||
|
||||
/* Turn off default reductions where requested by the user. See
|
||||
|
||||
@@ -672,25 +672,25 @@ exp: foo;
|
||||
]])
|
||||
|
||||
AT_BISON_CHECK([-fcaret input.y], [1], [],
|
||||
[[input.y:8.7-11: error: %type redeclaration for foo
|
||||
[[input.y:8.7-11: error: %type redeclaration for "foo"
|
||||
%type <baz> "foo"
|
||||
^^^^^
|
||||
input.y:3.7-11: previous declaration
|
||||
%type <bar> foo
|
||||
^^^^^
|
||||
input.y:10.13-17: error: %destructor redeclaration for foo
|
||||
%destructor {baz} "foo"
|
||||
^^^^^
|
||||
input.y:5.13-17: previous declaration
|
||||
%destructor {bar} foo
|
||||
^^^^^
|
||||
input.y:9.10-14: error: %printer redeclaration for foo
|
||||
input.y:9.10-14: error: %printer redeclaration for "foo"
|
||||
%printer {baz} "foo"
|
||||
^^^^^
|
||||
input.y:4.10-14: previous declaration
|
||||
%printer {bar} foo
|
||||
^^^^^
|
||||
input.y:11.1-5: error: %left redeclaration for foo
|
||||
input.y:10.13-17: error: %destructor redeclaration for "foo"
|
||||
%destructor {baz} "foo"
|
||||
^^^^^
|
||||
input.y:5.13-17: previous declaration
|
||||
%destructor {bar} foo
|
||||
^^^^^
|
||||
input.y:11.1-5: error: %left redeclaration for "foo"
|
||||
%left "foo"
|
||||
^^^^^
|
||||
input.y:6.1-5: previous declaration
|
||||
|
||||
Reference in New Issue
Block a user