summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-12-30 08:27:24 +0100
committerAkim Demaille <akim.demaille@gmail.com>2021-01-23 10:43:25 +0100
commita26f7cf98fcfe9fa1a3077dafdbff0687c22c039 (patch)
treef0ec3c1e5bb3195c60c7e068e20559daea8c5a7e /src
parent0317055bb06d69b74005273955eddaa345cd1eca (diff)
downloadbison-a26f7cf98fcfe9fa1a3077dafdbff0687c22c039.tar.gz
%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.
Diffstat (limited to 'src')
-rw-r--r--src/output.c14
-rw-r--r--src/reader.c29
-rw-r--r--src/reader.h5
3 files changed, 25 insertions, 23 deletions
diff --git a/src/output.c b/src/output.c
index 753b1bd7..19c89cb4 100644
--- a/src/output.c
+++ b/src/output.c
@@ -533,14 +533,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);
}
diff --git a/src/reader.c b/src/reader.c
index 059e9341..b71dd916 100644
--- a/src/reader.c
+++ b/src/reader.c
@@ -41,7 +41,7 @@ static void check_and_convert_grammar (void);
static symbol_list *grammar = NULL;
static bool start_flag = false;
-merger_list *merge_functions;
+merger_list *merge_functions = NULL;
/* Was %union seen? */
bool union_seen = false;
@@ -93,27 +93,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;
@@ -122,17 +122,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;
}
@@ -616,7 +617,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
diff --git a/src/reader.h b/src/reader.h
index 6b4f57ff..2fde52c6 100644
--- a/src/reader.h
+++ b/src/reader.h
@@ -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;