Saya mengikuti Kernighan & Pike klasik Lingkungan Pemrograman Unix; khususnya bab yang membahas yacc. Pada contoh pertama, kalkulator dasar bernama hoc1 disiapkan dengan yacc.

Berikut buku saya siapkan kode berikut:

%{
#define YYSTYPE double
%}
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
list:
    | list '\n'
    | list expr '\n'    { printf("\t%.8g\n", $2); }
    ;
expr:     NUMBER        { $$ = $1; }
    | expr '+' expr     { $$ = $1 + $3; }
    | expr '-' expr     { $$ = $1 - $3; }
    | expr '*' expr     { $$ = $1 * $3; }
    | expr '/' expr     { $$ = $1 / $3; }
    | '(' expr ')'      { $$ = $2; }
    ;
%%

#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);

}

Tapi saya mendapatkan kesalahan berikut saat mengkompilasi program:

~/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.

Saya tidak mengerti baik peringatan maupun kesalahannya.

Sunting: menggunakan yacc di FreeBSD 12.1

1
M.E. 5 Juli 2020, 02:55

1 menjawab

Jawaban Terbaik

Pindahkan definisi fungsi yyerror setelah definisi fungsi warning atau letakkan baris ini sebelum fungsi yyerror:

void warning(char *, char *);

Pesan kompiler ini:

hoc1.y:64:2: warning: implicit declaration of function 'warning' is invalid in C99 [-Wimplicit-function-declaration]

Memberitahu Anda bahwa fungsi warning sedang digunakan sebelum deklarasi apa pun terlihat. Ini menghasilkan deklarasi implisit karena sejarah bahasa C.

Pesan kompiler ini:

hoc1.y:68:6: error: conflicting types for 'warning'

Memberi tahu Anda bahwa definisi sebenarnya dari warning memiliki tipe yang berbeda dari definisi implisit dari atas.

Solusi untuk ini adalah dengan mendeklarasikan warning sebelum menggunakannya, yang dapat Anda lakukan dengan meletakkan definisi (yang merupakan deklarasi) sebelum penggunaan atau dengan meletakkan deklarasi terpisah sebelum penggunaan.

2
Eric Postpischil 5 Juli 2020, 00:08