mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-10 04:43:03 +00:00
declarations appear after the rules. Don't mistake the type of $$ in a midrule to be that of its parent rule's $$. * src/reader.c (grammar_current_rule_end): Don't invoke grammar_rule_check yet since not all symbol declarations may have been parsed yet. (grammar_midrule_action): Likewise. Don't record whether the midrule's $$ has been used yet since actions haven't been translated yet. Record the midrule's parent rule and its RHS index within the parent rule. (grammar_current_rule_action_append): Don't translate the action yet since not all symbol declarations may have been parsed yet and, thus, warnings about types for $$, $n, @$, and @n can't be reported yet. (packgram): Translate the action and invoke grammar_rule_check now that all symbol declarations have been parsed. * src/scan-code.l (handle_action_dollar): Now that this is invoked after parsing the entire grammar file, the symbol list here in the case of a midrule is actually the midrule's empty RHS, so reference its parent rule's RHS where necessary. On the other hand, now that you can already know it's a midrule, you aren't forced to think $$ has the same type as its parent rule's $$. (handle_action_at): In the case of a midrule, reference the parent rule where necessary. * src/symlist.c (symbol_list_new): Initialize new midrule-related members. (symbol_list_length): Now that this is invoked after all rules have been parsed, a NULL symbol (rather than a NULL symbol list node) terminates a rule. symbol_list_print already does this correctly. * src/symlist.h (symbol_list.midrule_parent_rule, symbol_list.midrule_parent_rhs_index): New members so that midrules can remember their relationships with their parents. * tests/input.at (Type Clashes): Extend to catch the midrule $$ error fixed by the above patch. (_AT_UNUSED_VALUES_DECLARATIONS, AT_CHECK_UNUSED_VALUES): New m4 macros implementing... (Unused values): ... this old test case and... (Unused values before symbol declarations): ... this new test case. This one is the same as `Unused values' except that all symbol declarations appear after the rules in order to catch the rest of the errors fixed by the above patch.
165 lines
3.5 KiB
C
165 lines
3.5 KiB
C
/* Lists of symbols for Bison
|
|
|
|
Copyright (C) 2002, 2005, 2006 Free Software Foundation, Inc.
|
|
|
|
This file is part of Bison, the GNU Compiler Compiler.
|
|
|
|
Bison is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
Bison is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Bison; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA. */
|
|
|
|
#include <config.h>
|
|
#include "system.h"
|
|
|
|
#include "complain.h"
|
|
#include "symlist.h"
|
|
|
|
|
|
/*--------------------------------------.
|
|
| Create a list containing SYM at LOC. |
|
|
`--------------------------------------*/
|
|
|
|
symbol_list *
|
|
symbol_list_new (symbol *sym, location loc)
|
|
{
|
|
symbol_list *res = xmalloc (sizeof *res);
|
|
|
|
res->sym = sym;
|
|
res->location = loc;
|
|
|
|
res->midrule = NULL;
|
|
res->midrule_parent_rule = NULL;
|
|
res->midrule_parent_rhs_index = 0;
|
|
|
|
res->action = NULL;
|
|
res->used = false;
|
|
|
|
res->ruleprec = NULL;
|
|
res->dprec = 0;
|
|
res->merger = 0;
|
|
|
|
res->next = NULL;
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
/*------------------.
|
|
| Print this list. |
|
|
`------------------*/
|
|
|
|
void
|
|
symbol_list_print (const symbol_list *l, FILE *f)
|
|
{
|
|
for (/* Nothing. */; l && l->sym; l = l->next)
|
|
{
|
|
symbol_print (l->sym, f);
|
|
fprintf (stderr, l->used ? " used" : " unused");
|
|
if (l && l->sym)
|
|
fprintf (f, ", ");
|
|
}
|
|
}
|
|
|
|
|
|
/*---------------------------------.
|
|
| Prepend SYM at LOC to the LIST. |
|
|
`---------------------------------*/
|
|
|
|
symbol_list *
|
|
symbol_list_prepend (symbol_list *list, symbol *sym, location loc)
|
|
{
|
|
symbol_list *res = symbol_list_new (sym, loc);
|
|
res->next = list;
|
|
return res;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------.
|
|
| Free the LIST, but not the symbols it contains. |
|
|
`-------------------------------------------------*/
|
|
|
|
void
|
|
symbol_list_free (symbol_list *list)
|
|
{
|
|
LIST_FREE (symbol_list, list);
|
|
}
|
|
|
|
|
|
/*--------------------.
|
|
| Return its length. |
|
|
`--------------------*/
|
|
|
|
unsigned int
|
|
symbol_list_length (const symbol_list *l)
|
|
{
|
|
int res = 0;
|
|
for (/* Nothing. */; l && l->sym; l = l->next)
|
|
++res;
|
|
return res;
|
|
}
|
|
|
|
|
|
/*--------------------------------.
|
|
| Get symbol N in symbol list L. |
|
|
`--------------------------------*/
|
|
|
|
symbol_list *
|
|
symbol_list_n_get (symbol_list *l, int n)
|
|
{
|
|
int i;
|
|
|
|
if (n < 0)
|
|
return NULL;
|
|
|
|
for (i = 0; i < n; ++i)
|
|
{
|
|
l = l->next;
|
|
if (l == NULL || l->sym == NULL)
|
|
return NULL;
|
|
}
|
|
|
|
return l;
|
|
}
|
|
|
|
|
|
/*--------------------------------------------------------------.
|
|
| Get the data type (alternative in the union) of the value for |
|
|
| symbol N in symbol list L. |
|
|
`--------------------------------------------------------------*/
|
|
|
|
uniqstr
|
|
symbol_list_n_type_name_get (symbol_list *l, location loc, int n)
|
|
{
|
|
l = symbol_list_n_get (l, n);
|
|
if (!l)
|
|
{
|
|
complain_at (loc, _("invalid $ value: $%d"), n);
|
|
return NULL;
|
|
}
|
|
return l->sym->type_name;
|
|
}
|
|
|
|
|
|
/*----------------------------------------.
|
|
| The symbol N in symbol list L is USED. |
|
|
`----------------------------------------*/
|
|
|
|
void
|
|
symbol_list_n_used_set (symbol_list *l, int n, bool used)
|
|
{
|
|
l = symbol_list_n_get (l, n);
|
|
if (l)
|
|
l->used = used;
|
|
}
|