Xcode 16.1中Swift集成Lex和Bison生成的解析器时,出现arm64架构下_yywrap符号未定义的链接错误
Xcode 16.1中Swift集成Lex和Bison生成的解析器时,出现arm64架构下_yywrap符号未定义的链接错误
这个链接错误其实是Flex的默认行为导致的——当Flex生成的词法分析器(yylex)读到输入末尾时,会自动调用yywrap()函数来判断是否有更多输入需要处理,但你当前的代码既没有实现这个函数,也没有禁用它,所以链接器找不到这个符号。
下面给你几个直接可行的解决方法,按推荐程度排序:
方法1:在Flex代码中禁用yywrap调用(最简单)
修改你的calc.l文件,在%{...%}块之后添加%option noyywrap选项,这样Flex就不会生成对yywrap()的调用了:
%{ #include "calc.tab.h" #include <stdlib.h> %} %option noyywrap // 新增这一行,禁用yywrap机制 %% [0-9]+ { yylval.num = atoi(yytext); return NUMBER; } [ \t\n]+ ; "+" return '+'; "-" return '-'; "*" return '*'; "/" return '/'; "(" return '('; ")" return ')'; . return yytext[0]; %%
修改后重新运行flex -o lex.yy.c calc.l和bison -d calc.y -o calc.tab.c生成新的代码,再编译项目,这个链接错误应该就消失了。
方法2:手动实现yywrap函数
如果不想禁用yywrap,也可以在你的代码里手动实现这个函数,比如在calc.c中添加:
int yywrap(void) { return 1; // 返回1表示没有更多输入需要处理 }
这样链接器就能找到这个符号,也能解决问题。
额外注意:你的代码还有两个潜在问题需要修复
result变量未被正确赋值
你当前的calc.y里定义了int result;,但在语法规则里从来没有给它赋值,所以parseExpression()返回的result值是未定义的。需要修改calc.y的语法规则,添加一个顶层规则来设置result:%% // 新增顶层规则calc,用来捕获最终表达式的结果 calc: expr { result = $1; } ; expr: expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | '(' expr ')' { $$ = $2; } | NUMBER { $$ = $1; } ; %%Swift代码中操作stdin的方式错误
你当前在Swift的evaluate函数里用fputs(cString, stdin)是不对的——stdin是输入流,不能用fputs往里面写内容。正确的做法可以用管道来给lex/bison提供输入:func evaluate(expression: String) -> Int32 { let pipe = Pipe() let readHandle = pipe.fileHandleForReading let writeHandle = pipe.fileHandleForWriting // 保存原始stdin的文件描述符 let originalStdin = dup(STDIN_FILENO) // 将stdin重定向到管道的读端 dup2(readHandle.fileDescriptor, STDIN_FILENO) // 往管道写端写入表达式内容 if let data = expression.data(using: .utf8) { writeHandle.write(data) writeHandle.closeFile() } // 调用解析函数 let calculationResult = parseExpression() // 恢复原始stdin dup2(originalStdin, STDIN_FILENO) close(originalStdin) readHandle.closeFile() return calculationResult }
备注:内容来源于stack exchange,提问作者Fab
相关产品推荐
相关产品推荐

