mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
%merge: let mergers record a typing-symbol, rather than a type
Symbols are richer than types, and in M4 it is my simpler (and more common) to deal with symbols rather than types. So let's associate mergers to a symbol rather than a type name. * src/reader.h (merger_list): Replace the 'type' member by a symbol member. * src/reader.c (record_merge_function_type): Take a symbol as argument, rather than a type name. * src/output.c (merger_output): Adjust.
This commit is contained in:
14
src/output.c
14
src/output.c
@@ -554,14 +554,12 @@ merger_output (FILE *out)
|
||||
int n;
|
||||
merger_list* p;
|
||||
for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
|
||||
{
|
||||
if (p->type[0] == '\0')
|
||||
fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
|
||||
n, p->name);
|
||||
else
|
||||
fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
|
||||
n, p->type, p->name);
|
||||
}
|
||||
if (p->sym && p->sym->content->type_name)
|
||||
fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
|
||||
n, p->sym->content->type_name, p->name);
|
||||
else
|
||||
fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
|
||||
n, p->name);
|
||||
fputs ("]])\n\n", out);
|
||||
}
|
||||
|
||||
|
||||
29
src/reader.c
29
src/reader.c
@@ -42,7 +42,7 @@ static void check_and_convert_grammar (void);
|
||||
|
||||
static symbol_list *grammar = NULL;
|
||||
symbol_list *start_symbols = NULL;
|
||||
merger_list *merge_functions;
|
||||
merger_list *merge_functions = NULL;
|
||||
|
||||
/* Was %union seen? */
|
||||
bool union_seen = false;
|
||||
@@ -114,27 +114,27 @@ get_merge_function (uniqstr name)
|
||||
syms->next->name = uniqstr_new (name);
|
||||
/* After all symbol type declarations have been parsed, packgram invokes
|
||||
record_merge_function_type to set the type. */
|
||||
syms->next->type = NULL;
|
||||
syms->next->sym = NULL;
|
||||
syms->next->next = NULL;
|
||||
merge_functions = head.next;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------.
|
||||
| For the existing merging function with index MERGER, record the result |
|
||||
| type as TYPE as required by the lhs of the rule whose %merge declaration |
|
||||
| is at DECLARATION_LOC. |
|
||||
`-------------------------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------.
|
||||
| For the existing merging function with index MERGER, record that |
|
||||
| the result type is that of SYM, as required by the lhs (i.e., SYM) |
|
||||
| of the rule whose %merge declaration is at DECLARATION_LOC. |
|
||||
`-------------------------------------------------------------------*/
|
||||
|
||||
static void
|
||||
record_merge_function_type (int merger, uniqstr type, location declaration_loc)
|
||||
record_merge_function_type (int merger, symbol *sym, location declaration_loc)
|
||||
{
|
||||
if (merger <= 0)
|
||||
return;
|
||||
|
||||
if (type == NULL)
|
||||
type = uniqstr_new ("");
|
||||
uniqstr type
|
||||
= sym->content->type_name ? sym->content->type_name : uniqstr_new ("");
|
||||
|
||||
merger_list *merge_function;
|
||||
int merger_find = 1;
|
||||
@@ -143,17 +143,18 @@ record_merge_function_type (int merger, uniqstr type, location declaration_loc)
|
||||
merge_function = merge_function->next)
|
||||
merger_find += 1;
|
||||
aver (merge_function != NULL && merger_find == merger);
|
||||
if (merge_function->type != NULL && !UNIQSTR_EQ (merge_function->type, type))
|
||||
if (merge_function->sym && merge_function->sym->content->type_name
|
||||
&& !UNIQSTR_EQ (merge_function->sym->content->type_name, type))
|
||||
{
|
||||
complain (&declaration_loc, complaint,
|
||||
_("result type clash on merge function %s: "
|
||||
"<%s> != <%s>"),
|
||||
quote (merge_function->name), type,
|
||||
merge_function->type);
|
||||
merge_function->sym->content->type_name);
|
||||
subcomplain (&merge_function->type_declaration_loc, complaint,
|
||||
_("previous declaration"));
|
||||
}
|
||||
merge_function->type = uniqstr_new (type);
|
||||
merge_function->sym = sym;
|
||||
merge_function->type_declaration_loc = declaration_loc;
|
||||
}
|
||||
|
||||
@@ -668,7 +669,7 @@ packgram (void)
|
||||
for (symbol_list *p = grammar; p; p = p->next)
|
||||
{
|
||||
symbol_list *lhs = p;
|
||||
record_merge_function_type (lhs->merger, lhs->content.sym->content->type_name,
|
||||
record_merge_function_type (lhs->merger, lhs->content.sym,
|
||||
lhs->merger_declaration_loc);
|
||||
/* If the midrule's $$ is set or its $n is used, remove the '$' from the
|
||||
symbol name so that it's a user-defined symbol so that the default
|
||||
|
||||
@@ -31,7 +31,10 @@ typedef struct merger_list
|
||||
{
|
||||
struct merger_list* next;
|
||||
uniqstr name;
|
||||
uniqstr type;
|
||||
/* One symbol whose type is the one used by all the symbols on which
|
||||
this merging function is used. */
|
||||
symbol *sym;
|
||||
/* Where SYM was bound to this merging function. */
|
||||
location type_declaration_loc;
|
||||
} merger_list;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user