如何修复函数 'yyerror' 的隐式声明问题
How to fix implicit declaration of function 'yyerror' problem
您好,我正在制作一个使用 Lex 和 yacc 进行简单算术运算的程序,但我遇到了一个特定错误的问题。
ex1.y
%{
#include <stdio.h>
int sym[26];
%}
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/' '%'
%%
program:
program statement '\n'
|
;
statement:
expr {printf("%d\n", );}
| VARIABLE '=' expr {sym[] = ;}
;
expr:
INTEGER
| VARIABLE { $$ = sym[];}
| expr '+' expr { $$ = + ;}
| expr '-' expr { $$ = - ;}
| expr '*' expr { $$ = * ;}
| expr '/' expr { $$ = / ;}
| '(' expr ')' { $$ = ;}
;
%%
main() { return yyparse();}
int yyerror(char *s){
fprintf(stderr,"%s\n",s);
return 0;
}
ex1.l
%{
#include <stdlib.h>
#include "y.tab.h"
%}
%%
/* variables */
[a-z] {
yylval = *yytext -'a';
return VARIABLE;
}
/* integers */
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
/* operators */
[-+()=/*\n] { return *yytext;}
/* skip whitespace */
[ \t] ;
/* anything else is an error */
. yyerror("invalid character");
%%
int yywrap (void){
return 1;
}
当我执行以下指令时
$bison –d -y ex1.y
$lex ex1.l
$gcc lex.yy.c y.tab.c –o ex1
出现以下错误:
ex1.l: In function ‘yylex’:
ex1.l:28:1: warning: implicit declaration of function ‘yyerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
28 |
| ^
| perror
y.tab.c: In function ‘yyparse’:
y.tab.c:1227:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration]
1227 | yychar = yylex ();
| ^~~~~
y.tab.c:1402:7: warning: implicit declaration of function ‘yyerror’; did you mean ‘yyerrok’? [-Wimplicit-function-declaration]
1402 | yyerror (YY_("syntax error"));
| ^~~~~~~
| yyerrok
我不知道我的代码有什么问题。如果您能告诉我如何解决上述错误,我将不胜感激。
您使用的 bison 版本要求您声明 yylex() 和 yyerror 的原型。这些应该紧跟在文件顶部的 #include <stdio.h>
之后:
int yylex(void);
int yyerror(char* s);
我会使用 int yyerror(const char* s)
作为 yyerror
的原型,因为它更准确,但如果您这样做,则必须对定义进行相同的更改。
您在 lex 文件中使用了 yyerror
,因此您也必须在该文件中添加它的声明。
main()
本世纪任何时候都不是有效的原型。 Return 类型在函数声明中是必需的,包括 main()
。所以我猜你的代码是基于一个非常旧的模板。 examples in the bison manual 中有更好的起点。
(如果您没有使用 C 的经验,不要指望使用解析器生成器会很容易。)
您好,我正在制作一个使用 Lex 和 yacc 进行简单算术运算的程序,但我遇到了一个特定错误的问题。
ex1.y
%{
#include <stdio.h>
int sym[26];
%}
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/' '%'
%%
program:
program statement '\n'
|
;
statement:
expr {printf("%d\n", );}
| VARIABLE '=' expr {sym[] = ;}
;
expr:
INTEGER
| VARIABLE { $$ = sym[];}
| expr '+' expr { $$ = + ;}
| expr '-' expr { $$ = - ;}
| expr '*' expr { $$ = * ;}
| expr '/' expr { $$ = / ;}
| '(' expr ')' { $$ = ;}
;
%%
main() { return yyparse();}
int yyerror(char *s){
fprintf(stderr,"%s\n",s);
return 0;
}
ex1.l
%{
#include <stdlib.h>
#include "y.tab.h"
%}
%%
/* variables */
[a-z] {
yylval = *yytext -'a';
return VARIABLE;
}
/* integers */
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
/* operators */
[-+()=/*\n] { return *yytext;}
/* skip whitespace */
[ \t] ;
/* anything else is an error */
. yyerror("invalid character");
%%
int yywrap (void){
return 1;
}
当我执行以下指令时
$bison –d -y ex1.y
$lex ex1.l
$gcc lex.yy.c y.tab.c –o ex1
出现以下错误:
ex1.l: In function ‘yylex’:
ex1.l:28:1: warning: implicit declaration of function ‘yyerror’; did you mean ‘perror’? [-Wimplicit-function-declaration]
28 |
| ^
| perror
y.tab.c: In function ‘yyparse’:
y.tab.c:1227:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration]
1227 | yychar = yylex ();
| ^~~~~
y.tab.c:1402:7: warning: implicit declaration of function ‘yyerror’; did you mean ‘yyerrok’? [-Wimplicit-function-declaration]
1402 | yyerror (YY_("syntax error"));
| ^~~~~~~
| yyerrok
我不知道我的代码有什么问题。如果您能告诉我如何解决上述错误,我将不胜感激。
您使用的 bison 版本要求您声明 yylex() 和 yyerror 的原型。这些应该紧跟在文件顶部的 #include <stdio.h>
之后:
int yylex(void);
int yyerror(char* s);
我会使用 int yyerror(const char* s)
作为 yyerror
的原型,因为它更准确,但如果您这样做,则必须对定义进行相同的更改。
您在 lex 文件中使用了 yyerror
,因此您也必须在该文件中添加它的声明。
main()
本世纪任何时候都不是有效的原型。 Return 类型在函数声明中是必需的,包括 main()
。所以我猜你的代码是基于一个非常旧的模板。 examples in the bison manual 中有更好的起点。
(如果您没有使用 C 的经验,不要指望使用解析器生成器会很容易。)