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

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表示没有更多输入需要处理
}

这样链接器就能找到这个符号,也能解决问题。


额外注意:你的代码还有两个潜在问题需要修复

  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; }
      ;
    %%
    
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 08:47:59