You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Lex/Yacc算术运算程序中的yyerror与yylex隐式声明问题

解决Lex/Yacc算术程序中的隐式声明警告问题

这些警告本质上都是C编译器找不到函数原型导致的隐式声明问题,我来帮你拆解原因并给出修复方案:

问题根源

  1. yyerror 隐式声明:不管是Lex生成的lex.yy.c还是Yacc生成的y.tab.c,编译器都找不到yyerror的函数原型,所以抛出警告。
  2. yylex 隐式声明:Yacc生成的解析器需要调用yylex获取token,但编译器不知道这个函数的签名,同样报隐式声明。
  3. 另外你的Lex代码还有个小语法问题,最后一行的错误处理缺少大括号,虽然不是当前警告的原因,但会导致潜在解析错误。

具体修复步骤

1. 给yyerror和yylex添加原型声明

修改你的ex1.y文件,在顶部的%{ ... %}块里添加两个函数的原型声明,这样Yacc生成的y.tab.h会包含这些声明,而Lex文件已经引用了y.tab.h,两边的代码就能找到正确的函数签名:

%{
#include <stdio.h>
int sym[26];
// 添加函数原型,解决隐式声明问题
int yyerror(char *s);
extern int yylex(void);
%}

另外,原代码里的main()没有返回类型,这不符合C标准,我会在完整代码里一并修复。

2. 修复Lex代码的语法错误

把ex1.l最后一行的错误处理代码加上大括号:

. { yyerror("invalid character"); }

原来的写法缺少大括号,Lex可能无法正确解析这个规则。

修复后的完整代码

ex1.y

%{
#include <stdio.h>
int sym[26];
int yyerror(char *s);
extern int yylex(void);
%}
%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;} ;
%%
int 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

内容的提问来源于stack exchange,提问作者user9178840

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 20:42:51