Le 20 janv. 09 à 21:53, Alexander Sorockin a écrit :
Hi,
Has anyone besides me noticed that $n with n zero or negative always
triggers a "$n ... has no declared type" error when a %union is used?
And it's normal: since you are looking deep in the stack, Bison cannot
figure out (in the general case) what the kind of symbol is there. So
it can't guess the field of the union it needs to use to decode the
semantic value.
Cosider this grammar, which is a slightly modified example from the
manual:
%union {
int val;
}
%token <val> NUM
%start foo
%%
foo
: expr bar '+' expr
| expr bar '-' expr
bar: /* empty */
{ previous_expr = $0; } /* <-- "test.y:16.27-28: $0 of `bar' has no
declared type" */
;
expr
: NUM;
%%
Yes, here it could.
The error persists even if you insert "%type <val> expr". I know
this can be worked around by using "$<val>0", but I think this error
shouldn't appear at all.
You're asking for completely new developments here. There is nothing
in the internals to have this work (yet it would be nice if it could).
In case anyone is interested, here's the piece of code that issues
the error.
File scan-gram.l:
...
static inline bool
handle_action_dollar (char *text, location loc)
{
const char *type_name = NULL;
...
/* Get the type name if explicit. */
if (*cp == '<')
{
type_name = ++cp;
while (*cp != '>')
++cp;
*cp = '\0';
++cp;
}
if (*cp == '$')
{
...
}
else
{
long int num = strtol (cp, NULL, 10);
if (1 - INT_MAX + rule_length <= num && num <= rule_length)
{
int n = num;
...
if (!type_name && 0 < n)
//!!!
//!!! Because n <= 0 in our case, type_name is never retrieved.
//!!!
type_name = symbol_list_n_type_name_get (current_rule, loc, n);
The runtime parser-stack and the compile-time analysis of the grammar
are two different things. At compile time the information you're
asking for is not available. If you let n become negative, you will
find other rules sitting there in memory just because of
implementation details. You will not find symbols "beneath in the
parser stack".
//!!!
//!!! Thus, unless the type name is referred to explicitly, zero
//!!! or negative semantic contexts can't coexist with %union's.
//!!!
if (!type_name && typed)
complain_at (loc, _("$%d of `%s' has no declared type"),
n, current_rule->sym->tag);
...
}
...
}
That was an extract from version 2.3 code, but this piece doesn't
seem to have changed much in version 2.4.1.
Best,
Sandy
_______________________________________________
help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison
_______________________________________________
help-bison@gnu.org http://lists.gnu.org/mailman/listinfo/help-bison