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

Flex/Bison中动态vector在fold操作中的使用问题求助

Flex/Bison解释器开发中动态Vector的类型转换问题

问题背景

正在用Flex/Bison开发课程作业的解释器,需实现fold操作的计算函数。为支持任意数量参数,列表类型定义为动态vector<double>*,但遇到类型转换与使用障碍。

核心代码定义

Bison联合类型与类型声明

%union {
    CharPtr iden;
    Operators oper;
    double value;
    vector<double>* list;
}

%type <list> list expressions list_choice

Fold规则定义

FOLD direction operator list_choice ENDFOLD SEMICOLON {$$ = evaluateFold($2, $3, $4);}

具体报错与问题

  1. 范围for循环失效:用range-based for循环遍历vector指针时,报错:
    this range-based 'for' statement requires a suitable "begin" function and none was foundC/C++(2291)
    
  2. 指针转引用失败:尝试将vector<double>*传递给参数为const std::vector<double>&的evaluateFold()时,编译报错:
    parser.y: In function ‘int yyparse()’: parser.y:127:146: error: invalid initialization of reference of type ‘std::vector<double>&’ from expression of type ‘std::vector<double>*’
    
    In file included from parser.y:21: values.h:18:76: note: in passing argument 3 of ‘double evaluateFold(Operators, Operators, std::vector<double>&)’
    

尝试过的实现方案

方案1:指针参数的evaluateFold函数

double evaluateFold(Operators direction, Operators action, vector<double>* values){

    double result = 0;
    switch(direction){
        case LFOLD:
            switch(action){
                case SUBTRACT:
                    subFromLeft(values);
                    for (auto i : values) // 此处触发报错
                        cout << i << endl;
                    break;
            }
        case RFOLD:
            switch(action){
                case SUBTRACT:
                    for (auto i : values) // 此处触发报错
                        cout << i << endl;
                    break;
            }
            break;
    }
    return result;
}

方案2:变参模板实现fold逻辑

无法适配vector参数:

template <typename ...Args>
auto subFromLeft(Args ...args)
{
    return (... - args);
}

方案3:引用参数的subFromLeft函数

但无法解决vector指针到引用的转换问题:

double subFromLeft(const std::vector<double>& values) {
    if (values.empty()) return 0;  // Handle empty vector
    double result = values[0];

    for (size_t i = 1; i < values.size(); i++) {
        result -= values[i];
    }

    return result;
}

测试样例

// Test Left Fold

function main returns integer;
begin
    fold left - (3, 2, 1) endfold;
end;

解决方案

1. 修复指针转引用的调用问题

在Bison动作代码中对vector指针解引用,同时添加空指针检查避免崩溃:

FOLD direction operator list_choice ENDFOLD SEMICOLON {
    if ($4) { // 先确保指针有效
        $$ = evaluateFold($2, $3, *$4); 
    } else {
        // 处理空指针错误,比如返回默认值或抛出异常
        $$ = nullptr; // 需匹配你的返回类型定义
    }
}

2. 修复range-based for循环

若坚持使用指针参数的evaluateFold,遍历前必须解引用指针:

// 错误写法
for (auto i : values)

// 正确写法
for (auto i : *values)

3. 适配subFromLeft的调用

如果subFromLeft接受引用参数,调用时同样需要解引用指针:

subFromLeft(*values);

4. 内存管理提示

Bison union中使用指针需注意内存泄漏问题,确保在vector不再使用时手动释放内存(比如解释器执行完fold操作后)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:27:35