%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:
Akim Demaille
2020-12-30 08:27:24 +01:00
parent edfcca8481
commit ac3d5b76f7
3 changed files with 25 additions and 23 deletions

View File

@@ -554,14 +554,12 @@ merger_output (FILE *out)
int n; int n;
merger_list* p; merger_list* p;
for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next) for (n = 1, p = merge_functions; p != NULL; n += 1, p = p->next)
{ if (p->sym && p->sym->content->type_name)
if (p->type[0] == '\0') fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n",
fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n", n, p->sym->content->type_name, p->name);
n, p->name); else
else fprintf (out, " case %d: *yy0 = %s (*yy0, *yy1); break;\n",
fprintf (out, " case %d: yy0->%s = %s (*yy0, *yy1); break;\n", n, p->name);
n, p->type, p->name);
}
fputs ("]])\n\n", out); fputs ("]])\n\n", out);
} }

View File

@@ -42,7 +42,7 @@ static void check_and_convert_grammar (void);
static symbol_list *grammar = NULL; static symbol_list *grammar = NULL;
symbol_list *start_symbols = NULL; symbol_list *start_symbols = NULL;
merger_list *merge_functions; merger_list *merge_functions = NULL;
/* Was %union seen? */ /* Was %union seen? */
bool union_seen = false; bool union_seen = false;
@@ -114,27 +114,27 @@ get_merge_function (uniqstr name)
syms->next->name = uniqstr_new (name); syms->next->name = uniqstr_new (name);
/* After all symbol type declarations have been parsed, packgram invokes /* After all symbol type declarations have been parsed, packgram invokes
record_merge_function_type to set the type. */ record_merge_function_type to set the type. */
syms->next->type = NULL; syms->next->sym = NULL;
syms->next->next = NULL; syms->next->next = NULL;
merge_functions = head.next; merge_functions = head.next;
} }
return n; return n;
} }
/*-------------------------------------------------------------------------. /*-------------------------------------------------------------------.
| For the existing merging function with index MERGER, record the result | | For the existing merging function with index MERGER, record that |
| type as TYPE as required by the lhs of the rule whose %merge declaration | | the result type is that of SYM, as required by the lhs (i.e., SYM) |
| is at DECLARATION_LOC. | | of the rule whose %merge declaration is at DECLARATION_LOC. |
`-------------------------------------------------------------------------*/ `-------------------------------------------------------------------*/
static void 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) if (merger <= 0)
return; return;
if (type == NULL) uniqstr type
type = uniqstr_new (""); = sym->content->type_name ? sym->content->type_name : uniqstr_new ("");
merger_list *merge_function; merger_list *merge_function;
int merger_find = 1; int merger_find = 1;
@@ -143,17 +143,18 @@ record_merge_function_type (int merger, uniqstr type, location declaration_loc)
merge_function = merge_function->next) merge_function = merge_function->next)
merger_find += 1; merger_find += 1;
aver (merge_function != NULL && merger_find == merger); 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, complain (&declaration_loc, complaint,
_("result type clash on merge function %s: " _("result type clash on merge function %s: "
"<%s> != <%s>"), "<%s> != <%s>"),
quote (merge_function->name), type, quote (merge_function->name), type,
merge_function->type); merge_function->sym->content->type_name);
subcomplain (&merge_function->type_declaration_loc, complaint, subcomplain (&merge_function->type_declaration_loc, complaint,
_("previous declaration")); _("previous declaration"));
} }
merge_function->type = uniqstr_new (type); merge_function->sym = sym;
merge_function->type_declaration_loc = declaration_loc; merge_function->type_declaration_loc = declaration_loc;
} }
@@ -668,7 +669,7 @@ packgram (void)
for (symbol_list *p = grammar; p; p = p->next) for (symbol_list *p = grammar; p; p = p->next)
{ {
symbol_list *lhs = p; 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); lhs->merger_declaration_loc);
/* If the midrule's $$ is set or its $n is used, remove the '$' from the /* 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 symbol name so that it's a user-defined symbol so that the default

View File

@@ -31,7 +31,10 @@ typedef struct merger_list
{ {
struct merger_list* next; struct merger_list* next;
uniqstr name; 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; location type_declaration_loc;
} merger_list; } merger_list;