【问题标题】:How to fix implicit declaration of function 'yyerror' problem如何修复函数“yyerror”问题的隐式声明
【发布时间】:2021-10-19 09:10:08
【问题描述】:

您好,我正在制作一个使用 Lex 和 yacc 进行简单算术运算的程序,但我遇到了一个特定错误的问题。

ex1.y

%{
#include <stdio.h>
int sym[26];
%}

%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/' '%'

%%
program:
    program statement '\n'
    |
    ;

statement:
    expr            {printf("%d\n", $1);}
    | VARIABLE '=' expr {sym[$1] = $3;}
    ;

expr:
    INTEGER
    | VARIABLE      { $$ = sym[$1];}
    | expr '+' expr { $$ = $1 + $3;}
    | expr '-' expr { $$ = $1 - $3;}
    | expr '*' expr     { $$ = $1 * $3;}
    | expr '/' expr { $$ = $1 / $3;}
    | '(' expr ')'      { $$ = $2;}
    ;
%%

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

我不知道我的代码有什么问题。如果您能告诉我如何解决上述错误,我将不胜感激。

【问题讨论】:

    标签: yacc lex


    【解决方案1】:

    您使用的 bison 版本要求您声明 yylex() 和 yyerror 的原型。这些应该紧跟在文件顶部的#include &lt;stdio.h&gt; 之后:

        int yylex(void);
        int yyerror(char* s);
    

    我会使用int yyerror(const char* s) 作为yyerror 的原型,因为它更准确,但如果你这样做,你将不得不对定义进行相同的更改。

    您在 lex 文件中使用 yyerror,因此您还必须在该文件中添加其声明。

    main() 在本世纪的任何时候都不是有效的原型。函数声明中需要返回类型,包括main()。所以我猜你的代码是基于一个非常旧的模板。 examples in the bison manual 有更好的起点。 (如果您没有使用 C 的经验,请不要期望使用解析器生成器会很容易。)

    【讨论】:

      猜你喜欢
      • 2019-10-01
      • 1970-01-01
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多