如何解决野牛警告“…没有声明types”

在这个文件上运行野牛:

%{ #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'没有声明的types。

这是什么意思,我该如何解决?

定义的联合(%联合)不打算直接使用。 相反,你需要告诉野牛哪个成员使用哪个expression。

这是通过%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;} ; %% 

作为进一步的想法,如果你想更加明确你的减less(如果你正在做AST annoation,这可以很方便),那么你可以让你的栈值指针,然后自己处理types值。 很像标量types:

 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的堆栈。

当你移动到更复杂的编译器前端时,它可以帮助你这样构build你的AST,这样当你遍历树时你有更好的元数据,你也可以用翻译的语义types来扩充翻译。 然后它归结为您的叶生产,如身份证洗牌lexeme到正确的标量有效载荷。

不是一个完整的解释,但你明白了。

希望这有助于你未来的Bison / Lex前端和…

祝你好运