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:
Valentin Tolmer
2013-07-31 11:51:59 +02:00
committed by Akim Demaille
parent c4aa4ff541
commit a728075710
18 changed files with 262 additions and 267 deletions

View File

@@ -242,7 +242,7 @@ AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s,
{ {
symbol_number contribution_token = symbol_number contribution_token =
InadequacyList__getContributionToken (self->inadequacyNode, ci) InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number; ->content->number;
if (AnnotationList__isContributionAlways (self, ci)) if (AnnotationList__isContributionAlways (self, ci))
{ {
annotation_node->contributions[ci] = NULL; annotation_node->contributions[ci] = NULL;
@@ -549,7 +549,7 @@ AnnotationList__compute_from_inadequacies (
does discard annotations in the simplest case of a S/R does discard annotations in the simplest case of a S/R
conflict with no token precedence. */ conflict with no token precedence. */
aver (!bitset_test (shift_tokens, conflicted_token) aver (!bitset_test (shift_tokens, conflicted_token)
|| symbols[conflicted_token]->prec); || symbols[conflicted_token]->content->prec);
++annotation_counts[s->number]; ++annotation_counts[s->number];
if (contribution_count > *max_contributionsp) if (contribution_count > *max_contributionsp)
*max_contributionsp = contribution_count; *max_contributionsp = contribution_count;
@@ -595,7 +595,7 @@ AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces)
{ {
symbol_number token = symbol_number token =
InadequacyList__getContributionToken (a->inadequacyNode, ci) InadequacyList__getContributionToken (a->inadequacyNode, ci)
->number; ->content->number;
{ {
int j; int j;
for (j = 0; j < spaces+2; ++j) for (j = 0; j < spaces+2; ++j)
@@ -644,7 +644,7 @@ AnnotationList__computeLookaheadFilter (AnnotationList const *self,
Sbitset biter; Sbitset biter;
symbol_number token = symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci) InadequacyList__getContributionToken (self->inadequacyNode, ci)
->number; ->content->number;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item) SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
bitset_set (lookahead_filter[item], token); bitset_set (lookahead_filter[item], token);
} }
@@ -679,7 +679,8 @@ AnnotationList__stateMakesContribution (AnnotationList const *self,
return false; return false;
{ {
symbol_number token = symbol_number token =
InadequacyList__getContributionToken (self->inadequacyNode, ci)->number; InadequacyList__getContributionToken (self->inadequacyNode, ci)
->content->number;
Sbitset__Index item; Sbitset__Index item;
Sbitset biter; Sbitset biter;
SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item) SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item)
@@ -709,7 +710,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
ContributionIndex ci; ContributionIndex ci;
int actioni; int actioni;
ContributionIndex ci_rr_dominator = ContributionIndex__none; 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 the token has no precedence set, shift is always chosen. */
if (!shift_precedence) if (!shift_precedence)
@@ -739,7 +740,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
if (reduce_precedence if (reduce_precedence
&& (reduce_precedence < shift_precedence && (reduce_precedence < shift_precedence
|| (reduce_precedence == shift_precedence || (reduce_precedence == shift_precedence
&& token->assoc == right_assoc))) && token->content->assoc == right_assoc)))
continue; continue;
if (!AnnotationList__stateMakesContribution (self, nitems, ci, if (!AnnotationList__stateMakesContribution (self, nitems, ci,
lookaheads)) lookaheads))
@@ -747,7 +748,7 @@ AnnotationList__computeDominantContribution (AnnotationList const *self,
/* This uneliminated reduction contributes, so see if it can cause /* This uneliminated reduction contributes, so see if it can cause
an error action. */ an error action. */
if (reduce_precedence == shift_precedence if (reduce_precedence == shift_precedence
&& token->assoc == non_assoc) && token->content->assoc == non_assoc)
{ {
/* It's not possible to find split-stable domination over /* It's not possible to find split-stable domination over
shift after a potential %nonassoc. */ shift after a potential %nonassoc. */

View File

@@ -104,7 +104,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution: case shift_resolution:
obstack_printf (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%s < %s)", " (%s < %s)",
r->prec->tag, r->prec->symbol->tag,
symbols[token]->tag); symbols[token]->tag);
break; break;
@@ -112,7 +112,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_obstack, obstack_printf (&solved_conflicts_obstack,
" (%s < %s)", " (%s < %s)",
symbols[token]->tag, symbols[token]->tag,
r->prec->tag); r->prec->symbol->tag);
break; break;
case left_resolution: case left_resolution:
@@ -176,7 +176,7 @@ log_resolution (rule *r, symbol_number token,
case shift_resolution: case shift_resolution:
obstack_printf (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s", "%s &lt; %s",
xml_escape_n (0, r->prec->tag), xml_escape_n (0, r->prec->symbol->tag),
xml_escape_n (1, symbols[token]->tag)); xml_escape_n (1, symbols[token]->tag));
break; break;
@@ -184,7 +184,7 @@ log_resolution (rule *r, symbol_number token,
obstack_printf (&solved_conflicts_xml_obstack, obstack_printf (&solved_conflicts_xml_obstack,
"%s &lt; %s", "%s &lt; %s",
xml_escape_n (0, symbols[token]->tag), xml_escape_n (0, symbols[token]->tag),
xml_escape_n (1, r->prec->tag)); xml_escape_n (1, r->prec->symbol->tag));
break; break;
case left_resolution: case left_resolution:
@@ -269,18 +269,18 @@ resolve_sr_conflict (state *s, int ruleno, symbol **errors, int *nerrs)
for (i = 0; i < ntokens; i++) for (i = 0; i < ntokens; i++)
if (bitset_test (lookahead_tokens, i) if (bitset_test (lookahead_tokens, i)
&& bitset_test (lookahead_set, i) && bitset_test (lookahead_set, i)
&& symbols[i]->prec) && symbols[i]->content->prec)
{ {
/* Shift-reduce conflict occurs for token number i /* Shift-reduce conflict occurs for token number i
and it has a precedence. and it has a precedence.
The precedence of shifting is that of token i. */ 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); register_precedence (redrule->prec->number, i);
log_resolution (redrule, i, reduce_resolution); log_resolution (redrule, i, reduce_resolution);
flush_shift (s, i); flush_shift (s, i);
} }
else if (symbols[i]->prec > redprec) else if (symbols[i]->content->prec > redprec)
{ {
register_precedence (i, redrule->prec->number); register_precedence (i, redrule->prec->number);
log_resolution (redrule, i, shift_resolution); 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 right associativity, keep only the shift.
For nonassociativity, keep neither. */ For nonassociativity, keep neither. */
switch (symbols[i]->assoc) switch (symbols[i]->content->assoc)
{ {
case undef_assoc: case undef_assoc:
abort (); abort ();

View File

@@ -65,19 +65,19 @@ rule_useless_in_parser_p (rule const *r)
} }
void 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); fprintf (out, " %3d ", r->number);
if (previous_lhs != r->lhs) if (previous_lhs != r->lhs)
fprintf (out, "%s:", r->lhs->tag); fprintf (out, "%s:", r->lhs->symbol->tag);
else else
fprintf (out, "%*s|", (int) strlen (previous_lhs->tag), ""); fprintf (out, "%*s|", (int) strlen (previous_lhs->symbol->tag), "");
} }
void void
rule_lhs_print_xml (rule const *r, FILE *out, int level) 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 size_t
@@ -158,7 +158,7 @@ grammar_rules_partial_print (FILE *out, const char *title,
{ {
rule_number r; rule_number r;
bool first = true; bool first = true;
symbol *previous_lhs = NULL; sym_content *previous_lhs = NULL;
/* rule # : LHS -> RHS */ /* rule # : LHS -> RHS */
for (r = 0; r < nrules + nuseless_productions; r++) for (r = 0; r < nrules + nuseless_productions; r++)
@@ -209,7 +209,7 @@ grammar_rules_print_xml (FILE *out, int level)
rules[r].number, usefulness); rules[r].number, usefulness);
if (rules[r].precsym) if (rules[r].precsym)
fprintf (out, " percent_prec=\"%s\"", fprintf (out, " percent_prec=\"%s\"",
xml_escape (rules[r].precsym->tag)); xml_escape (rules[r].precsym->symbol->tag));
fputs (">\n", out); fputs (">\n", out);
} }
rule_lhs_print_xml (&rules[r], out, level + 3); 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++) for (i = ntokens; i < nsyms; i++)
fprintf (out, "%5d %5d %5d %s\n", fprintf (out, "%5d %5d %5d %s\n",
i, i,
symbols[i]->prec, symbols[i]->assoc, symbols[i]->content->prec, symbols[i]->content->assoc,
symbols[i]->tag); symbols[i]->tag);
fprintf (out, "\n\n"); fprintf (out, "\n\n");
} }
@@ -280,7 +280,7 @@ grammar_dump (FILE *out, const char *title)
rule_number r; rule_number r;
for (r = 0; r < nrules + nuseless_productions; 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); rule_rhs_print (&rules[r], out);
fprintf (out, "\n"); fprintf (out, "\n");
} }

View File

@@ -180,17 +180,17 @@ typedef struct
except if some rules are useless. */ except if some rules are useless. */
rule_number number; rule_number number;
symbol *lhs; sym_content *lhs;
item_number *rhs; item_number *rhs;
/* This symbol provides both the associativity, and the precedence. */ /* This symbol provides both the associativity, and the precedence. */
symbol *prec; sym_content *prec;
int dprec; int dprec;
int merger; int merger;
/* This symbol was attached to the rule via %prec. */ /* This symbol was attached to the rule via %prec. */
symbol *precsym; sym_content *precsym;
location location; location location;
bool useful; 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 /* Print this rule's number and lhs on OUT. If a PREVIOUS_LHS was
already displayed (by a previous call for another rule), avoid already displayed (by a previous call for another rule), avoid
useless repetitions. */ 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); void rule_lhs_print_xml (rule const *r, FILE *out, int level);
/* Return the length of the RHS. */ /* Return the length of the RHS. */

View File

@@ -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)); bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
for (n = 0; n < s->errs->num; ++n) for (n = 0; n < s->errs->num; ++n)
if (s->errs->symbols[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 static void

View File

@@ -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])) if (item_number_is_rule_number (ritem[s->items[item] - 2]))
{ {
state **predecessor; state **predecessor;
aver (lhs != accept->number); aver (lhs != accept->content->number);
for (predecessor = predecessors[s->number]; for (predecessor = predecessors[s->number];
*predecessor; *predecessor;
++predecessor) ++predecessor)
@@ -580,7 +580,7 @@ typedef struct state_list {
static void static void
ielr_compute_goto_follow_set (bitsetv follow_kernel_items, ielr_compute_goto_follow_set (bitsetv follow_kernel_items,
bitsetv always_follows, state_list *s, 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); goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number);
bitset_copy (follow_set, always_follows[n_goto]); bitset_copy (follow_set, always_follows[n_goto]);

View File

@@ -149,7 +149,7 @@ prepare_symbols (void)
MUSCLE_INSERT_INT ("tokens_number", ntokens); MUSCLE_INSERT_INT ("tokens_number", ntokens);
MUSCLE_INSERT_INT ("nterms_number", nvars); MUSCLE_INSERT_INT ("nterms_number", nvars);
MUSCLE_INSERT_INT ("symbols_number", nsyms); 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_INT ("user_token_number_max", max_user_token_number);
muscle_insert_symbol_number_table ("translate", muscle_insert_symbol_number_table ("translate",
@@ -197,7 +197,7 @@ prepare_symbols (void)
int i; int i;
int *values = xnmalloc (ntokens, sizeof *values); int *values = xnmalloc (ntokens, sizeof *values);
for (i = 0; i < ntokens; ++i) 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, muscle_insert_int_table ("toknum", values,
values[0], 1, ntokens); values[0], 1, ntokens);
free (values); free (values);
@@ -283,9 +283,9 @@ prepare_states (void)
static int static int
symbol_type_name_cmp (const symbol **lhs, const symbol **rhs) 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) if (!res)
res = (*lhs)->number - (*rhs)->number; res = (*lhs)->content->number - (*rhs)->content->number;
return res; return res;
} }
@@ -320,8 +320,9 @@ type_names_output (FILE *out)
/* The index of the first symbol of the current type-name. */ /* The index of the first symbol of the current type-name. */
int i0 = i; int i0 = i;
fputs (i ? ",\n[" : "[", out); fputs (i ? ",\n[" : "[", out);
for (; i < nsyms && syms[i]->type_name == syms[i0]->type_name; ++i) for (; i < nsyms
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->number); && syms[i]->content->type_name == syms[i0]->content->type_name; ++i)
fprintf (out, "%s%d", i != i0 ? ", " : "", syms[i]->content->number);
fputs ("]", out); fputs ("]", out);
} }
fputs ("])\n\n", out); fputs ("])\n\n", out);
@@ -428,20 +429,21 @@ prepare_symbol_definitions (void)
MUSCLE_INSERT_STRING (key, sym->tag); MUSCLE_INSERT_STRING (key, sym->tag);
SET_KEY ("user_number"); 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"); SET_KEY ("is_token");
MUSCLE_INSERT_INT (key, MUSCLE_INSERT_INT (key,
i < ntokens && sym != errtoken && sym != undeftoken); i < ntokens && sym != errtoken && sym != undeftoken);
SET_KEY ("number"); SET_KEY ("number");
MUSCLE_INSERT_INT (key, sym->number); MUSCLE_INSERT_INT (key, sym->content->number);
SET_KEY ("has_type"); SET_KEY ("has_type");
MUSCLE_INSERT_INT (key, !!sym->type_name); MUSCLE_INSERT_INT (key, !!sym->content->type_name);
SET_KEY ("type"); 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; int j;

View File

@@ -260,7 +260,7 @@ print_reductions (FILE *out, int level, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i) for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[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) if (default_reduction)
report = true; report = true;
@@ -388,11 +388,11 @@ print_grammar (FILE *out, int level)
/* Terminals */ /* Terminals */
xml_puts (out, level + 1, "<terminals>"); xml_puts (out, level + 1, "<terminals>");
for (i = 0; i < max_user_token_number + 1; i++) 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; char const *tag = symbols[token_translations[i]]->tag;
int precedence = symbols[token_translations[i]]->prec; int precedence = symbols[token_translations[i]]->content->prec;
assoc associativity = symbols[token_translations[i]]->assoc; assoc associativity = symbols[token_translations[i]]->content->assoc;
xml_indent (out, level + 2); xml_indent (out, level + 2);
fprintf (out, fprintf (out,
"<terminal symbol-number=\"%d\" token-number=\"%d\"" "<terminal symbol-number=\"%d\" token-number=\"%d\""

View File

@@ -72,7 +72,7 @@ print_core (FILE *out, state *s)
size_t i; size_t i;
item_number *sitems = s->items; item_number *sitems = s->items;
size_t snritems = s->nitems; 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. */ /* Output all the items of a state, not only its kernel. */
if (report_flag & report_itemsets) if (report_flag & report_itemsets)
@@ -223,7 +223,8 @@ print_reduction (FILE *out, size_t width,
if (!enabled) if (!enabled)
fputc ('[', out); fputc ('[', out);
if (r->number) 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 else
fprintf (out, _("accept")); fprintf (out, _("accept"));
if (!enabled) if (!enabled)
@@ -257,7 +258,7 @@ print_reductions (FILE *out, state *s)
bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i)); bitset_set (no_reduce_set, TRANSITION_SYMBOL (trans, i));
for (i = 0; i < s->errs->num; ++i) for (i = 0; i < s->errs->num; ++i)
if (s->errs->symbols[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. */ /* Compute the width of the lookahead token column. */
if (default_reduction) if (default_reduction)
@@ -408,7 +409,7 @@ print_grammar (FILE *out)
/* TERMINAL (type #) : rule #s terminal is on RHS */ /* TERMINAL (type #) : rule #s terminal is on RHS */
fprintf (out, "%s\n\n", _("Terminals, with rules where they appear")); fprintf (out, "%s\n\n", _("Terminals, with rules where they appear"));
for (i = 0; i < max_user_token_number + 1; i++) 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; const char *tag = symbols[token_translations[i]]->tag;
rule_number r; rule_number r;

View File

@@ -46,7 +46,7 @@ static void
print_core (struct obstack *oout, state *s) print_core (struct obstack *oout, state *s)
{ {
item_number const *sitems = s->items; item_number const *sitems = s->items;
symbol *previous_lhs = NULL; sym_content *previous_lhs = NULL;
size_t i; size_t i;
size_t snritems = s->nitems; size_t snritems = s->nitems;
@@ -72,11 +72,12 @@ print_core (struct obstack *oout, state *s)
r = &rules[item_number_as_rule_number (*sp)]; r = &rules[item_number_as_rule_number (*sp)];
obstack_printf (oout, "%3d ", r->number); 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| ", obstack_printf (oout, "%*s| ",
(int) strlen (previous_lhs->tag), ""); (int) strlen (previous_lhs->symbol->tag), "");
else else
obstack_printf (oout, "%s: ", escape (r->lhs->tag)); obstack_printf (oout, "%s: ", escape (r->lhs->symbol->tag));
previous_lhs = r->lhs; previous_lhs = r->lhs;
for (sp = r->rhs; sp < sp1; sp++) for (sp = r->rhs; sp < sp1; sp++)

View File

@@ -240,13 +240,13 @@ grammar_current_rule_begin (symbol *lhs, location loc,
current_rule = grammar_end; current_rule = grammar_end;
/* Mark the rule's lhs as a nonterminal if not already so. */ /* 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->content->class = nterm_sym;
lhs->number = nvars; lhs->content->number = nvars;
++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"), complain (&loc, complaint, _("rule given for %s, which is a token"),
lhs->tag); 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 Don't worry about the default action if $$ is untyped, since $$'s
value can't be used. */ 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; symbol *first_rhs = r->next->content.sym;
/* If $$ is being set in default way, report if any type mismatch. */ /* If $$ is being set in default way, report if any type mismatch. */
if (first_rhs) 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 = 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)) if (!UNIQSTR_EQ (lhs_type, rhs_type))
complain (&r->location, Wother, complain (&r->location, Wother,
_("type clash on default action: <%s> != <%s>"), _("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. */ it for char literals and strings, which are always tokens. */
if (r->ruleprec if (r->ruleprec
&& r->ruleprec->tag[0] != '\'' && r->ruleprec->tag[0] != '"' && 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, complain (&r->location, Wother,
_("token for %%prec is not defined: %s"), r->ruleprec->tag); _("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); p = grammar_symbol_append (sym, loc);
if (name) if (name)
assign_named_ref (p, name); assign_named_ref (p, name);
if (sym->status == undeclared || sym->status == used) if (sym->content->status == undeclared || sym->content->status == used)
sym->status = needed; sym->content->status = needed;
} }
/* Attach an ACTION to the current rule. */ /* Attach an ACTION to the current rule. */
@@ -558,11 +559,11 @@ packgram (void)
for (p = grammar; p; p = p->next) for (p = grammar; p; p = p->next)
{ {
symbol *ruleprec = p->ruleprec; 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); p->merger_declaration_location);
rules[ruleno].user_number = ruleno; rules[ruleno].user_number = ruleno;
rules[ruleno].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].rhs = ritem + itemno;
rules[ruleno].prec = NULL; rules[ruleno].prec = NULL;
rules[ruleno].dprec = p->dprec; rules[ruleno].dprec = p->dprec;
@@ -604,11 +605,11 @@ packgram (void)
/* item_number = symbol_number. /* item_number = symbol_number.
But the former needs to contain more: negative rule numbers. */ But the former needs to contain more: negative rule numbers. */
ritem[itemno++] = 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 /* A rule gets by default the precedence and associativity
of its last token. */ of its last token. */
if (p->content.sym->class == token_sym && default_prec) if (p->content.sym->content->class == token_sym && default_prec)
rules[ruleno].prec = p->content.sym; rules[ruleno].prec = p->content.sym->content;
} }
} }
@@ -616,8 +617,8 @@ packgram (void)
the specified symbol's precedence replaces the default. */ the specified symbol's precedence replaces the default. */
if (ruleprec) if (ruleprec)
{ {
rules[ruleno].precsym = ruleprec; rules[ruleno].precsym = ruleprec->content;
rules[ruleno].prec = ruleprec; rules[ruleno].prec = ruleprec->content;
} }
/* An item ends by the rule number (negated). */ /* An item ends by the rule number (negated). */
ritem[itemno++] = rule_number_as_item_number (ruleno); ritem[itemno++] = rule_number_as_item_number (ruleno);
@@ -647,19 +648,19 @@ reader (void)
/* Construct the accept symbol. */ /* Construct the accept symbol. */
accept = symbol_get ("$accept", empty_location); accept = symbol_get ("$accept", empty_location);
accept->class = nterm_sym; accept->content->class = nterm_sym;
accept->number = nvars++; accept->content->number = nvars++;
/* Construct the error token */ /* Construct the error token */
errtoken = symbol_get ("error", empty_location); errtoken = symbol_get ("error", empty_location);
errtoken->class = token_sym; errtoken->content->class = token_sym;
errtoken->number = ntokens++; errtoken->content->number = ntokens++;
/* Construct a token that represents all undefined literal tokens. /* Construct a token that represents all undefined literal tokens.
It is always token number 2. */ It is always token number 2. */
undeftoken = symbol_get ("$undefined", empty_location); undeftoken = symbol_get ("$undefined", empty_location);
undeftoken->class = token_sym; undeftoken->content->class = token_sym;
undeftoken->number = ntokens++; undeftoken->content->number = ntokens++;
gram_in = xfopen (grammar_file, "r"); gram_in = xfopen (grammar_file, "r");
@@ -721,10 +722,10 @@ check_and_convert_grammar (void)
if (!endtoken) if (!endtoken)
{ {
endtoken = symbol_get ("$end", empty_location); endtoken = symbol_get ("$end", empty_location);
endtoken->class = token_sym; endtoken->content->class = token_sym;
endtoken->number = 0; endtoken->content->number = 0;
/* Value specified by POSIX. */ /* Value specified by POSIX. */
endtoken->user_token_number = 0; endtoken->content->user_token_number = 0;
} }
/* Report any undefined symbols and consider them nonterminals. */ /* Report any undefined symbols and consider them nonterminals. */

View File

@@ -163,9 +163,9 @@ inaccessable_symbols (void)
Pp = bitset_create (nrules, BITSET_FIXED); Pp = bitset_create (nrules, BITSET_FIXED);
/* If the start symbol isn't useful, then nothing will be useful. */ /* 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) while (1)
{ {
@@ -196,9 +196,9 @@ inaccessable_symbols (void)
V = Vp; V = Vp;
/* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */ /* Tokens 0, 1, and 2 are internal to Bison. Consider them useful. */
bitset_set (V, endtoken->number); /* end-of-input token */ bitset_set (V, endtoken->content->number); /* end-of-input token */
bitset_set (V, errtoken->number); /* error token */ bitset_set (V, errtoken->content->number); /* error token */
bitset_set (V, undeftoken->number); /* some undefined token */ bitset_set (V, undeftoken->content->number); /* some undefined token */
bitset_free (P); bitset_free (P);
P = Pp; P = Pp;
@@ -298,7 +298,7 @@ nonterminals_reduce (void)
if (!bitset_test (V, i)) if (!bitset_test (V, i))
{ {
nontermmap[i - ntokens] = n++; nontermmap[i - ntokens] = n++;
if (symbols[i]->status != used) if (symbols[i]->content->status != used)
complain (&symbols[i]->location, Wother, complain (&symbols[i]->location, Wother,
_("nonterminal useless in grammar: %s"), _("nonterminal useless in grammar: %s"),
symbols[i]->tag); symbols[i]->tag);
@@ -310,7 +310,7 @@ nonterminals_reduce (void)
symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted); symbol **symbols_sorted = xnmalloc (nvars, sizeof *symbols_sorted);
for (i = ntokens; i < nsyms; i++) 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++) for (i = ntokens; i < nsyms; i++)
symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i]; symbols_sorted[nontermmap[i - ntokens] - ntokens] = symbols[i];
for (i = ntokens; i < nsyms; i++) for (i = ntokens; i < nsyms; i++)
@@ -328,7 +328,7 @@ nonterminals_reduce (void)
*rhsp = symbol_number_as_item_number (nontermmap[*rhsp *rhsp = symbol_number_as_item_number (nontermmap[*rhsp
- ntokens]); - ntokens]);
} }
accept->number = nontermmap[accept->number - ntokens]; accept->content->number = nontermmap[accept->content->number - ntokens];
} }
nsyms -= nuseless_nonterminals; nsyms -= nuseless_nonterminals;
@@ -415,7 +415,7 @@ reduce_grammar (void)
reduce_print (); reduce_print ();
if (!bitset_test (N, accept->number - ntokens)) if (!bitset_test (N, accept->content->number - ntokens))
complain (&startsymbol_location, fatal, complain (&startsymbol_location, fatal,
_("start symbol %s does not derive any sentence"), _("start symbol %s does not derive any sentence"),
startsymbol->tag); startsymbol->tag);

View File

@@ -135,7 +135,7 @@ typedef struct
/* Is the TRANSITIONS->states[Num] labelled by the error token? */ /* Is the TRANSITIONS->states[Num] labelled by the error token? */
# define TRANSITION_IS_ERROR(Transitions, Num) \ # 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 /* When resolving a SR conflicts, if the reduction wins, the shift is
disabled. */ disabled. */

View File

@@ -205,7 +205,7 @@ symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
return NULL; return NULL;
} }
aver (l->content_type == SYMLIST_SYMBOL); aver (l->content_type == SYMLIST_SYMBOL);
return l->content.sym->type_name; return l->content.sym->content->type_name;
} }
bool bool
@@ -223,8 +223,8 @@ symbol_list_code_props_set (symbol_list *node, code_props_type kind,
{ {
case SYMLIST_SYMBOL: case SYMLIST_SYMBOL:
symbol_code_props_set (node->content.sym, kind, cprops); symbol_code_props_set (node->content.sym, kind, cprops);
if (node->content.sym->status == undeclared) if (node->content.sym->content->status == undeclared)
node->content.sym->status = used; node->content.sym->content->status = used;
break; break;
case SYMLIST_TYPE: case SYMLIST_TYPE:
semantic_type_code_props_set semantic_type_code_props_set

View File

@@ -58,6 +58,35 @@ static symgraph **prec_nodes;
bool *used_assoc = NULL; 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. | | Create a new symbol, named TAG. |
`---------------------------------*/ `---------------------------------*/
@@ -76,22 +105,9 @@ symbol_new (uniqstr tag, location loc)
res->tag = tag; res->tag = tag;
res->location = loc; 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->alias = NULL;
res->class = unknown_sym; res->content = sym_content_new (res);
res->status = undeclared; res->is_alias = false;
if (nsyms == SYMBOL_NUMBER_MAXIMUM) if (nsyms == SYMBOL_NUMBER_MAXIMUM)
complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"), complain (NULL, fatal, _("too many symbols in input grammar (limit is %d)"),
@@ -100,6 +116,30 @@ symbol_new (uniqstr tag, location loc)
return res; 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 * char const *
code_props_type_string (code_props_type kind) 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) \ #define SYMBOL_ATTR_PRINT(Attr) \
if (s->Attr) \ if (s->content->Attr) \
fprintf (f, " %s { %s }", #Attr, s->Attr) fprintf (f, " %s { %s }", #Attr, s->content->Attr)
#define SYMBOL_CODE_PRINT(Attr) \ #define SYMBOL_CODE_PRINT(Attr) \
if (s->props[Attr].code) \ if (s->content->props[Attr].code) \
fprintf (f, " %s { %s }", #Attr, s->props[Attr].code) fprintf (f, " %s { %s }", #Attr, s->content->props[Attr].code)
void void
symbol_print (symbol const *s, FILE *f) symbol_print (symbol const *s, FILE *f)
@@ -193,7 +233,7 @@ is_identifier (uniqstr s)
uniqstr uniqstr
symbol_id_get (symbol const *sym) 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) if (sym->alias)
sym = sym->alias; sym = sym->alias;
return is_identifier (sym->tag) ? sym->tag : 0; 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 (type_name)
{ {
if (sym->type_name) if (sym->content->type_name)
symbol_redeclaration (sym, "%type", sym->type_location, loc); symbol_redeclaration (sym, "%type", sym->content->type_location, loc);
else else
{ {
uniqstr_assert (type_name); uniqstr_assert (type_name);
sym->type_name = type_name; sym->content->type_name = type_name;
sym->type_location = loc; sym->content->type_location = loc;
} }
} }
} }
@@ -260,12 +300,12 @@ void
symbol_code_props_set (symbol *sym, code_props_type kind, symbol_code_props_set (symbol *sym, code_props_type kind,
code_props const *code) code_props const *code)
{ {
if (sym->props[kind].code) if (sym->content->props[kind].code)
symbol_redeclaration (sym, code_props_type_string (kind), symbol_redeclaration (sym, code_props_type_string (kind),
sym->props[kind].location, sym->content->props[kind].location,
code->location); code->location);
else 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) symbol_code_props_get (symbol *sym, code_props_type kind)
{ {
/* Per-symbol code props. */ /* Per-symbol code props. */
if (sym->props[kind].code) if (sym->content->props[kind].code)
return &sym->props[kind]; return &sym->content->props[kind];
/* Per-type code props. */ /* Per-type code props. */
if (sym->type_name) if (sym->content->type_name)
{ {
code_props *code = 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) if (code->code)
return 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. */ /* Apply default code props's only to user-defined symbols. */
if (sym->tag[0] != '$' && sym != errtoken) if (sym->tag[0] != '$' && sym != errtoken)
{ {
code_props *code = code_props *code = &semantic_type_get (sym->content->type_name ? "*" : "",
&semantic_type_get (sym->type_name ? "*" : "", NULL)->props[kind]; NULL)->props[kind];
if (code->code) if (code->code)
return code; return code;
} }
@@ -324,16 +364,17 @@ symbol_code_props_get (symbol *sym, code_props_type kind)
void void
symbol_precedence_set (symbol *sym, int prec, assoc a, location loc) symbol_precedence_set (symbol *sym, int prec, assoc a, location loc)
{ {
sym_content *s = sym->content;
if (a != undef_assoc) if (a != undef_assoc)
{ {
if (sym->prec) if (s->prec)
symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, symbol_redeclaration (sym, assoc_to_string (a),
loc); s->prec_location, loc);
else else
{ {
sym->prec = prec; s->prec = prec;
sym->assoc = a; s->assoc = a;
sym->prec_location = loc; s->prec_location = loc;
} }
} }
@@ -350,26 +391,26 @@ void
symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring)
{ {
bool warned = false; 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); complain (&loc, complaint, _("symbol %s redefined"), sym->tag);
/* Don't report both "redefined" and "redeclared". */ /* Don't report both "redefined" and "redeclared". */
warned = true; warned = true;
} }
if (class == nterm_sym && sym->class != nterm_sym) if (class == nterm_sym && sym->content->class != nterm_sym)
sym->number = nvars++; sym->content->number = nvars++;
else if (class == token_sym && sym->number == NUMBER_UNDEFINED) else if (class == token_sym && sym->content->number == NUMBER_UNDEFINED)
sym->number = ntokens++; sym->content->number = ntokens++;
sym->class = class; sym->content->class = class;
if (declaring) if (declaring)
{ {
if (sym->status == declared && !warned) if (sym->content->status == declared && !warned)
complain (&loc, Wother, _("symbol %s redeclared"), sym->tag); complain (&loc, Wother, _("symbol %s redeclared"), sym->tag);
else 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; int *user_token_numberp;
if (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS) user_token_numberp = &sym->content->user_token_number;
user_token_numberp = &sym->user_token_number;
else
user_token_numberp = &sym->alias->user_token_number;
if (*user_token_numberp != USER_NUMBER_UNDEFINED if (*user_token_numberp != USER_NUMBER_UNDEFINED
&& *user_token_numberp != user_token_number) && *user_token_numberp != user_token_number)
complain (&loc, complaint, _("redefining user token number of %s"), 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? */ /* User defined $end token? */
if (user_token_number == 0) if (user_token_number == 0)
{ {
endtoken = sym; endtoken = sym->content->symbol;
/* It is always mapped to 0, so it was already counted in /* It is always mapped to 0, so it was already counted in
NTOKENS. */ NTOKENS. */
if (endtoken->number != NUMBER_UNDEFINED) if (endtoken->content->number != NUMBER_UNDEFINED)
--ntokens; --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 static inline bool
symbol_check_defined (symbol *sym) 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, complain (&sym->location,
sym->status == needed ? complaint : Wother, s->status == needed ? complaint : Wother,
_("symbol %s is used, but is not defined as a token" _("symbol %s is used, but is not defined as a token"
" and has no rules"), " and has no rules"),
sym->tag); sym->tag);
sym->class = nterm_sym; s->class = nterm_sym;
sym->number = nvars++; s->number = nvars++;
} }
{ {
@@ -434,9 +473,9 @@ symbol_check_defined (symbol *sym)
/* Set the semantic type status associated to the current symbol to /* Set the semantic type status associated to the current symbol to
'declared' so that we could check semantic types unnecessary uses. */ '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) if (sem_type)
sem_type->status = declared; 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); _("symbol %s given more than one literal string"), sym->tag);
else else
{ {
str->class = token_sym; sym_content_free (str->content);
str->user_token_number = sym->user_token_number; str->content = sym->content;
sym->user_token_number = USER_NUMBER_HAS_STRING_ALIAS; str->content->symbol = str;
str->is_alias = true;
str->alias = sym; str->alias = sym;
sym->alias = str; 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 | | Assign a symbol number, and write the definition of the token name |
| into FDEFINES. Put in SYMBOLS. | | into FDEFINES. Put in SYMBOLS. |
@@ -566,13 +550,13 @@ symbol_check_alias_consistency_processor (void *this,
static inline bool static inline bool
symbol_pack (symbol *this) symbol_pack (symbol *this)
{ {
aver (this->number != NUMBER_UNDEFINED); aver (this->content->number != NUMBER_UNDEFINED);
if (this->class == nterm_sym) if (this->content->class == nterm_sym)
this->number += ntokens; this->content->number += ntokens;
else if (this->user_token_number == USER_NUMBER_HAS_STRING_ALIAS) else if (this->content->user_token_number == USER_NUMBER_HAS_STRING_ALIAS)
return true; return true;
symbols[this->number] = this; symbols[this->content->number] = this->content->symbol;
return true; return true;
} }
@@ -582,7 +566,6 @@ symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED)
return symbol_pack (this); return symbol_pack (this);
} }
static void static void
user_token_number_redeclaration (int num, symbol *first, symbol *second) user_token_number_redeclaration (int num, symbol *first, symbol *second)
{ {
@@ -615,17 +598,18 @@ static inline bool
symbol_translation (symbol *this) symbol_translation (symbol *this)
{ {
/* Non-terminal? */ /* Non-terminal? */
if (this->class == token_sym if (this->content->class == token_sym
&& this->user_token_number != USER_NUMBER_HAS_STRING_ALIAS) && !this->is_alias)
{ {
/* A token which translation has already been set? */ /* A token which translation has already been set?*/
if (token_translations[this->user_token_number] != undeftoken->number) if (token_translations[this->content->user_token_number]
!= undeftoken->content->number)
user_token_number_redeclaration user_token_number_redeclaration
(this->user_token_number, (this->content->user_token_number,
symbols[token_translations[this->user_token_number]], symbols[token_translations[this->content->user_token_number]], this);
this);
else else
token_translations[this->user_token_number] = this->number; token_translations[this->content->user_token_number]
= this->content->number;
} }
return true; return true;
@@ -711,7 +695,7 @@ symbols_new (void)
NULL, NULL,
hash_symbol_hasher, hash_symbol_hasher,
hash_symbol_comparator, hash_symbol_comparator,
free); symbol_free);
semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY, semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY,
NULL, NULL,
hash_semantic_type_hasher, hash_semantic_type_hasher,
@@ -811,8 +795,8 @@ dummy_symbol_get (location loc)
sprintf (buf, "$@%d", ++dummy_count); sprintf (buf, "$@%d", ++dummy_count);
sym = symbol_get (buf, loc); sym = symbol_get (buf, loc);
sym->class = nterm_sym; sym->content->class = nterm_sym;
sym->number = nvars++; sym->content->number = nvars++;
return sym; return sym;
} }
@@ -902,7 +886,7 @@ symbols_token_translations_init (void)
max_user_token_number = 0; max_user_token_number = 0;
for (i = 0; i < ntokens; ++i) 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 != USER_NUMBER_UNDEFINED)
{ {
if (this->user_token_number > max_user_token_number) 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 256 is not used, assign it to error, to follow POSIX. */
if (num_256_available_p if (num_256_available_p
&& errtoken->user_token_number == USER_NUMBER_UNDEFINED) && errtoken->content->user_token_number == USER_NUMBER_UNDEFINED)
errtoken->user_token_number = 256; errtoken->content->user_token_number = 256;
/* Set the missing user numbers. */ /* Set the missing user numbers. */
if (max_user_token_number < 256) if (max_user_token_number < 256)
@@ -923,7 +907,7 @@ symbols_token_translations_init (void)
for (i = 0; i < ntokens; ++i) 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 == USER_NUMBER_UNDEFINED)
this->user_token_number = ++max_user_token_number; this->user_token_number = ++max_user_token_number;
if (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 /* Initialize all entries for literal tokens to the internal token
number for $undefined, which represents all invalid inputs. */ number for $undefined, which represents all invalid inputs. */
for (i = 0; i < max_user_token_number + 1; i++) 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, symbols_do (symbol_translation_processor, NULL,
symbol_table, &symbols_sorted); symbol_table, &symbols_sorted);
} }
@@ -950,9 +934,6 @@ symbols_token_translations_init (void)
void void
symbols_pack (void) symbols_pack (void)
{ {
symbols_do (symbol_check_alias_consistency_processor, NULL,
symbol_table, &symbols_sorted);
symbols = xcalloc (nsyms, sizeof *symbols); symbols = xcalloc (nsyms, sizeof *symbols);
symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted); symbols_do (symbol_pack_processor, NULL, symbol_table, &symbols_sorted);
@@ -971,9 +952,7 @@ symbols_pack (void)
else else
{ {
symbols[writei] = symbols[readi]; symbols[writei] = symbols[readi];
symbols[writei]->number = writei; symbols[writei]->content->number = writei;
if (symbols[writei]->alias)
symbols[writei]->alias->number = writei;
writei += 1; writei += 1;
} }
} }
@@ -982,11 +961,11 @@ symbols_pack (void)
symbols_token_translations_init (); symbols_token_translations_init ();
if (startsymbol->class == unknown_sym) if (startsymbol->content->class == unknown_sym)
complain (&startsymbol_location, fatal, complain (&startsymbol_location, fatal,
_("the start symbol %s is undefined"), _("the start symbol %s is undefined"),
startsymbol->tag); startsymbol->tag);
else if (startsymbol->class == token_sym) else if (startsymbol->content->class == token_sym)
complain (&startsymbol_location, fatal, complain (&startsymbol_location, fatal,
_("the start symbol %s is a token"), _("the start symbol %s is a token"),
startsymbol->tag); startsymbol->tag);
@@ -1123,9 +1102,9 @@ static inline bool
is_assoc_useless (symbol *s) is_assoc_useless (symbol *s)
{ {
return s return s
&& s->assoc != undef_assoc && s->content->assoc != undef_assoc
&& s->assoc != precedence_assoc && s->content->assoc != precedence_assoc
&& !used_assoc[s->number]; && !used_assoc[s->content->number];
} }
/*-------------------------------. /*-------------------------------.
@@ -1157,19 +1136,19 @@ print_precedence_warnings (void)
{ {
symbol *s = symbols[i]; symbol *s = symbols[i];
if (s if (s
&& s->prec != 0 && s->content->prec != 0
&& !prec_nodes[i]->pred && !prec_nodes[i]->pred
&& !prec_nodes[i]->succ) && !prec_nodes[i]->succ)
{ {
if (is_assoc_useless (s)) if (is_assoc_useless (s))
complain (&s->prec_location, Wprecedence, complain (&s->content->prec_location, Wprecedence,
_("useless precedence and associativity for %s"), s->tag); _("useless precedence and associativity for %s"), s->tag);
else if (s->assoc == precedence_assoc) else if (s->content->assoc == precedence_assoc)
complain (&s->prec_location, Wprecedence, complain (&s->content->prec_location, Wprecedence,
_("useless precedence for %s"), s->tag); _("useless precedence for %s"), s->tag);
} }
else if (is_assoc_useless (s)) 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); _("useless associativity for %s, use %%precedence"), s->tag);
} }
free (used_assoc); free (used_assoc);

View File

@@ -50,6 +50,7 @@ typedef int symbol_number;
typedef struct symbol symbol; typedef struct symbol symbol;
typedef struct sym_content sym_content;
/* Declaration status of a symbol. /* Declaration status of a symbol.
@@ -82,8 +83,6 @@ enum code_props_type
enum { CODE_PROPS_SIZE = 2 }; enum { CODE_PROPS_SIZE = 2 };
/* When extending this structure, be sure to complete
symbol_check_alias_consistency. */
struct symbol struct symbol
{ {
/** The key, name of the symbol. */ /** The key, name of the symbol. */
@@ -91,6 +90,20 @@ struct symbol
/** The location of its first occurrence. */ /** The location of its first occurrence. */
location location; 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. /** Its \c \%type.
Beware that this is the type_name as was entered by the user, Beware that this is the type_name as was entered by the user,
@@ -117,10 +130,6 @@ struct symbol
assoc assoc; assoc assoc;
int user_token_number; 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; symbol_class class;
status status; status status;
}; };

View File

@@ -290,7 +290,7 @@ action_row (state *s)
/* Do not use any default reduction if there is a shift for /* Do not use any default reduction if there is a shift for
error */ error */
if (sym == errtoken->number) if (sym == errtoken->content->number)
nodefault = true; nodefault = true;
} }
@@ -300,7 +300,7 @@ action_row (state *s)
for (i = 0; i < errp->num; i++) for (i = 0; i < errp->num; i++)
{ {
symbol *sym = errp->symbols[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 /* Turn off default reductions where requested by the user. See

View File

@@ -672,25 +672,25 @@ exp: foo;
]]) ]])
AT_BISON_CHECK([-fcaret input.y], [1], [], 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" %type <baz> "foo"
^^^^^ ^^^^^
input.y:3.7-11: previous declaration input.y:3.7-11: previous declaration
%type <bar> foo %type <bar> foo
^^^^^ ^^^^^
input.y:10.13-17: error: %destructor redeclaration for foo input.y:9.10-14: error: %printer 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
%printer {baz} "foo" %printer {baz} "foo"
^^^^^ ^^^^^
input.y:4.10-14: previous declaration input.y:4.10-14: previous declaration
%printer {bar} foo %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" %left "foo"
^^^^^ ^^^^^
input.y:6.1-5: previous declaration input.y:6.1-5: previous declaration