如何解决野牛警告“......没有声明的类型”(How to solve Bison warning

2019-07-28 23:34发布

在这个文件运行野牛:

%{
    #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”的$$没有声明的类型。

这是什么意思?如何解决呢?

Answer 1:

工会(%联盟)定义不意图直接使用。 相反,你需要告诉野牛该工会成员使用由表达。

这与done %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;}
;

%%


Answer 2:

作为进一步的思考,如果你想与你的削减更明确的(如果你正在做AST annoation,这是很方便的),那么你可以让你的堆栈指针的值,然后处理类型值自己。 就像标量类型有:

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为语义洗牌到右侧标有效载荷。

不是一个完整的解释,但你的想法。

希望这有助于你未来的野牛/莱克斯前端和...

祝好运



文章来源: How to solve Bison warning “… has no declared type”
标签: bison