编译基本示例 (hoc1) yacc 程序时 'warning' 的隐式 declaration/conflicting 类型
Implicit declaration/conflicting types for 'warning' while compiling a basic sample (hoc1) yacc program
我正在关注经典的 Kernighan & Pike The Unix Programming Environment;特别是涵盖 yacc 的章节。
在第一个示例中,使用 yacc.
准备了一个名为 hoc1 的基本计算器
根据本书我准备了以下代码:
%{
#define YYSTYPE double
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
list:
| list '\n'
| list expr '\n' { printf("\t%.8g\n", ); }
;
expr: NUMBER { $$ = ; }
| expr '+' expr { $$ = + ; }
| expr '-' expr { $$ = - ; }
| expr '*' expr { $$ = * ; }
| expr '/' expr { $$ = / ; }
| '(' expr ')' { $$ = ; }
;
%%
#include <stdio.h>
#include <ctype.h>
char *progname;
int lineno = 1;
int main(int argc, char *argv[]) {
progname = argv[0];
yyparse();
}
int yylex(void) {
int c;
/* Left trim all spaces/tabs */
while((c=getchar()) == ' ' || c == '\t');
/* Return 0 if EOF */
if(c== EOF) {
return 0;
}
/* Return NUMBER if number */
if(c=='.' || isdigit(c)) {
ungetc(c,stdin);
scanf("%lf", &yylval);
return NUMBER;
}
/* Count lines */
if(c=='\n') {
lineno++;
}
return c;
}
void yyerror(char *s) {
warning(s, (char *)0);
}
void warning(char *s, char *t) {
fprintf(stderr, "%s: %s", progname, s);
if(t) {
fprintf(stderr, " %s", t);
}
fprintf(stderr, " near line %d\n", lineno);
}
但是我在编译程序的时候出现如下错误:
~/tutorials/unix_programming_environment/hoc1 % yacc hoc1.y
~/tutorials/unix_programming_environment/hoc1 % cc y.tab.c -o hoc1
hoc1.y:64:2: warning: implicit declaration of function 'warning' is invalid in C99 [-Wimplicit-function-declaration]
warning(s, (char *)0);
^
hoc1.y:68:6: error: conflicting types for 'warning'
void warning(char *s, char *t) {
^
hoc1.y:64:2: note: previous implicit declaration is here
warning(s, (char *)0);
^
1 warning and 1 error generated.
我不明白警告或错误。
编辑:在 FreeBSD 12.1 中使用 yacc
将yyerror
函数的定义移到warning
函数的定义之后或将此行放在yyerror
函数之前:
void warning(char *, char *);
此编译器消息:
hoc1.y:64:2: warning: implicit declaration of function 'warning' is invalid in C99 [-Wimplicit-function-declaration]
告诉您函数 warning
在看到它的任何声明之前正在被使用。由于 C 语言的历史,这导致隐式声明。
此编译器消息:
hoc1.y:68:6: error: conflicting types for 'warning'
告诉您 warning
的实际定义与上面隐式声明的类型不同。
此解决方案是在使用前声明 warning
,您可以通过在使用前放置定义(声明)或在使用前放置单独的声明来实现。
我正在关注经典的 Kernighan & Pike The Unix Programming Environment;特别是涵盖 yacc 的章节。 在第一个示例中,使用 yacc.
准备了一个名为 hoc1 的基本计算器根据本书我准备了以下代码:
%{
#define YYSTYPE double
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
list:
| list '\n'
| list expr '\n' { printf("\t%.8g\n", ); }
;
expr: NUMBER { $$ = ; }
| expr '+' expr { $$ = + ; }
| expr '-' expr { $$ = - ; }
| expr '*' expr { $$ = * ; }
| expr '/' expr { $$ = / ; }
| '(' expr ')' { $$ = ; }
;
%%
#include <stdio.h>
#include <ctype.h>
char *progname;
int lineno = 1;
int main(int argc, char *argv[]) {
progname = argv[0];
yyparse();
}
int yylex(void) {
int c;
/* Left trim all spaces/tabs */
while((c=getchar()) == ' ' || c == '\t');
/* Return 0 if EOF */
if(c== EOF) {
return 0;
}
/* Return NUMBER if number */
if(c=='.' || isdigit(c)) {
ungetc(c,stdin);
scanf("%lf", &yylval);
return NUMBER;
}
/* Count lines */
if(c=='\n') {
lineno++;
}
return c;
}
void yyerror(char *s) {
warning(s, (char *)0);
}
void warning(char *s, char *t) {
fprintf(stderr, "%s: %s", progname, s);
if(t) {
fprintf(stderr, " %s", t);
}
fprintf(stderr, " near line %d\n", lineno);
}
但是我在编译程序的时候出现如下错误:
~/tutorials/unix_programming_environment/hoc1 % yacc hoc1.y
~/tutorials/unix_programming_environment/hoc1 % cc y.tab.c -o hoc1
hoc1.y:64:2: warning: implicit declaration of function 'warning' is invalid in C99 [-Wimplicit-function-declaration]
warning(s, (char *)0);
^
hoc1.y:68:6: error: conflicting types for 'warning'
void warning(char *s, char *t) {
^
hoc1.y:64:2: note: previous implicit declaration is here
warning(s, (char *)0);
^
1 warning and 1 error generated.
我不明白警告或错误。
编辑:在 FreeBSD 12.1 中使用 yacc
将yyerror
函数的定义移到warning
函数的定义之后或将此行放在yyerror
函数之前:
void warning(char *, char *);
此编译器消息:
hoc1.y:64:2: warning: implicit declaration of function 'warning' is invalid in C99 [-Wimplicit-function-declaration]
告诉您函数 warning
在看到它的任何声明之前正在被使用。由于 C 语言的历史,这导致隐式声明。
此编译器消息:
hoc1.y:68:6: error: conflicting types for 'warning'
告诉您 warning
的实际定义与上面隐式声明的类型不同。
此解决方案是在使用前声明 warning
,您可以通过在使用前放置定义(声明)或在使用前放置单独的声明来实现。