diff options
author | Akim Demaille <akim.demaille@gmail.com> | 2020-12-30 08:27:24 +0100 |
---|---|---|
committer | Akim Demaille <akim.demaille@gmail.com> | 2021-01-23 10:43:25 +0100 |
commit | a26f7cf98fcfe9fa1a3077dafdbff0687c22c039 (patch) | |
tree | f0ec3c1e5bb3195c60c7e068e20559daea8c5a7e /src | |
parent | 0317055bb06d69b74005273955eddaa345cd1eca (diff) | |
download | bison-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.c | 14 | ||||
-rw-r--r-- | src/reader.c | 29 | ||||
-rw-r--r-- | src/reader.h | 5 |
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; |