help-bison
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: %type'd non-terminal produces a `has no declared type' error


From: Akim Demaille
Subject: Re: %type'd non-terminal produces a `has no declared type' error
Date: Wed, 21 Jan 2009 10:18:10 +0100


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


_______________________________________________
address@hidden http://lists.gnu.org/mailman/listinfo/help-bison





reply via email to

[Prev in Thread] Current Thread [Next in Thread]