编译基本示例 (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,您可以通过在使用前放置定义(声明)或在使用前放置单独的声明来实现。