Подтвердить что ты не робот

Как решить предупреждение Bison "... не имеет объявленного типа"

Запуск Bison в этом файле:

%{
    #include <iostream>
    int yylex();
    void yyerror(const char*);
%}


%union
{
    char    name[100];
    int     val;
}

%token NUM ID
%right '='
%left '+' '-'
%left '*'

%%

exp :   NUM     {$$.val = $1.val;}
    | ID        {$$.val = vars[$1.name];}
    | exp '+' exp   {$$.val = $1.val + $3.val;}
    | ID '=' exp    {$$.val = vars[$1.name] = $3.val;}
;

%%

Приводит к предупреждениям типа:

предупреждение: $$ из 'exp' не имеет объявленного типа.

Что это значит и как его решить?

4b9b3361

Ответ 1

Определенный союз (% union) не предназначен для непосредственного использования. Скорее, вам нужно указать Bison, членом которого является член союза.

Это делается с помощью директивы type%.

Фиксированная версия кода:

%{
    #include <iostream>
    int yylex();
    void yyerror(const char*);
%}


%union
{
    char    name[100];
    int     val;
}

%token NUM ID
%right '='
%left '+' '-'
%left '*'

%type<val> exp NUM
%type<name> ID

%%

exp :   NUM     {$$ = $1;}
    | ID        {$$ = vars[$1];}
    | exp '+' exp   {$$ = $1 + $3;}
    | ID '=' exp    {$$ = vars[$1] = $3;}
;

%%

Ответ 2

В качестве дополнительной мысли, если вы хотите быть более явным с вашими сокращениями (если вы выполняете аннотацию AST, это может быть удобно), тогда вы можете сделать указатели на значения стека, а затем сами обрабатывать значения типов. Подобно скалярным типам:

struct myScalar {
    union {
        int num;
        char *id;
        char *float_lexeme;
    }payload;

    enum {
        TYPE_NUM,
        TYPE_IDENTIFIER,
        TYPE_FLOAT_CHAR
    } type;
    char *orig_lexeme;
};

И у вас есть typedef и scalar_val *val для стека.

Когда вы переходите на более сложные интерфейсы компилятора, это может помочь построить ваш АСТ таким образом, чтобы при пересечении дерева у вас были лучшие метаданные, и вы также можете увеличить перевод с переводами для пред-семантических типов, Затем он сводится к вашим листовым продуктам, таким как ID, чтобы перетасовать лексему в нужную скалярную полезную нагрузку.

Не полное объяснение, но вы получаете идею.

Надеюсь, что это поможет с вашим будущим интерфейсом Bison/Lex и...

Удача