Bison 如何解决野牛警告问题;。。。“没有声明的类型”;

Bison 如何解决野牛警告问题;。。。“没有声明的类型”;,bison,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

在此文件上运行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;}
;

%%
%{
#包括
int-yylex();
无效错误(常量字符*);
%}
%联合
{
字符名[100];
int-val;
}
%令牌编号ID
%对“=”
%左'+''-'
%左'*'
%%
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;}
;
%%
导致以下类型的警告:

警告:$$of'exp'没有声明的类型

它是什么意思?我如何解决它?

定义的联合(%union)不打算直接使用。相反,您需要告诉Bison,哪个表达式使用的是联盟的哪个成员

这是通过以下步骤完成的

代码的固定版本为:

%{
    #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;}
;

%%
%{
#包括
int-yylex();
无效错误(常量字符*);
%}
%联合
{
字符名[100];
int-val;
}
%令牌编号ID
%对“=”
%左'+''-'
%左'*'
%类型exp NUM
%类型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前端和


祝你好运

+1:当谷歌搜索
野牛错误没有声明类型时,首先出现
只有一点清晰。我有
%union{int intValue;int floatValue;}
但它不允许我使用
$.intValue
$1.intValue
。它表示
错误:请求非结构或联合中的成员“floatValue”
。为什么?你能再解释一下吗。。我不明白
%type
是如何工作的。一个小问题是:符号
%type exp NUM
并不意味着特定的缩减
exp NUM
具有type
val
;这意味着
exp
具有类型
VAL
NUM
具有类型
VAL
。顺便说一句,这个发布的答案比类型指令的官方文档更有用,因为它没有示例。@Reb.cab在哪里定义了
VAL
?或者你是说
val