[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/6] %merge: let mergers record a typing-symbol, rather than a ty
From: |
Akim Demaille |
Subject: |
[PATCH 2/6] %merge: let mergers record a typing-symbol, rather than a type |
Date: |
Thu, 31 Dec 2020 08:14:34 +0100 |
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.
---
src/output.c | 14 ++++++--------
src/reader.c | 29 +++++++++++++++--------------
src/reader.h | 5 ++++-
3 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/src/output.c b/src/output.c
index 2ed4a5be..e58d8b75 100644
--- a/src/output.c
+++ b/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);
}
diff --git a/src/reader.c b/src/reader.c
index 786e38f6..57c25d26 100644
--- a/src/reader.c
+++ b/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
diff --git a/src/reader.h b/src/reader.h
index c640dba0..7b08906b 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;
--
2.29.2
- [PATCH 0/6] glr: fix compatibility bw %merge and api.value.type=union, Akim Demaille, 2020/12/31
- [PATCH 1/6] %merge: clearer tests on diagnostics, Akim Demaille, 2020/12/31
- [PATCH 2/6] %merge: let mergers record a typing-symbol, rather than a type,
Akim Demaille <=
- [PATCH 3/6] %merge: delegate the generation of calls to mergers to m4, Akim Demaille, 2020/12/31
- [PATCH 5/6] %merge: test support for api.value.type=union, Akim Demaille, 2020/12/31
- [PATCH 4/6] %merge: fix compatibility with api.value.type=union, Akim Demaille, 2020/12/31
- [PATCH 6/6] %merge: associate it to its first definition, not the latest, Akim Demaille, 2020/12/31