Как решить предупреждение Bison & # 8220; & # 8230; не имеет объявленного типа & # 8221;

StackOverflow https://stackoverflow.com/questions/1014619

  •  06-07-2019
  •  | 
  •  

Вопрос

Запуск 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' нет объявленного типа.

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

Это было полезно?

Решение

Определенный союз (% 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;}
;

%%

Другие советы

В качестве дальнейшей мысли, если вы хотите быть более явными со своими сокращениями (если вы делаете аннотацию 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 для стека.

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

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

Надеюсь, это поможет вашим будущим пользователям Bison / Lex и ...

Удачи

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top