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

如何将PackCC的输入从标准输入(stdin)改为读取文件内容?

解决PackCC忽略传入缓冲区、仍读取标准输入的问题

你的核心问题在于PackCC自动生成的解析器默认绑定了标准输入(stdin),仅把缓冲区传入上下文是不够的——必须修改PEG定义和解析器调用逻辑,强制让解析器从你提供的缓冲区读取数据。

关键修正步骤

1. 修改PEG文件,指定自定义输入源

在你的.peg文件中,需要替换默认的输入读取逻辑,改用辅助数据(缓冲区)作为输入源。通过%input指令覆盖默认行为:

%{
#include <string.h>
// 自定义读取函数:从上下文的缓冲区取字符
static int read_from_buffer(scheme_context_t* ctx) {
    if (ctx->pos >= ctx->buffer_len) {
        return EOF; // 缓冲区读取完毕
    }
    return ctx->buffer[ctx->pos++];
}
%}

// 告诉PackCC用自定义函数替代默认的stdin读取
%input{ read_from_buffer(ctx) }

// 你的语法规则继续写在这里
scheme <- ...

2. 完善上下文结构体定义

确保scheme_context_t包含缓冲区、读取位置和长度三个关键字段:

typedef struct {
    const char* buffer;
    size_t buffer_len;
    size_t pos; // 当前读取到的位置
} scheme_context_t;

3. 修正scheme_create初始化逻辑

初始化上下文时要正确设置缓冲区参数:

scheme_context_t* scheme_create(const char* buffer) {
    scheme_context_t* ctx = malloc(sizeof(scheme_context_t));
    ctx->buffer = buffer;
    ctx->buffer_len = strlen(buffer);
    ctx->pos = 0; // 从缓冲区起始位置开始读取
    return ctx;
}

4. 修复文件读取的潜在问题

你原来用fgets只能读取一行数据,若文件有多行会丢失内容,建议改为读取整个文件:

static void parser_read(const char *contents, int mode) {
    FILE *fp = fopen(contents, "r");
    if (fp == NULL) {
        perror("Error opening file");
        exit(EXIT_FAILURE);
    }

    // 获取文件大小
    fseek(fp, 0, SEEK_END);
    long file_size = ftell(fp);
    fseek(fp, 0, SEEK_SET);

    // 分配足够的缓冲区(+1用于字符串终止符)
    char* buffer = malloc(file_size + 1);
    if (!buffer) {
        perror("Failed to allocate buffer");
        fclose(fp);
        exit(EXIT_FAILURE);
    }

    // 读取整个文件内容
    size_t read_bytes = fread(buffer, 1, file_size, fp);
    buffer[read_bytes] = '\0';
    fclose(fp);

    scheme_context_t *ctx = scheme_create(buffer);
    ast *my_ast = NULL;
    scheme_parse(ctx, &my_ast);
    ast_print(my_ast);
    eval_ast(my_ast);

    // 释放资源
    free(buffer);
    free(ctx);
    // 记得释放AST相关内存
}

无效原因说明

PackCC生成的解析器默认会调用标准输入的读取函数(比如fgetc(stdin)),不会自动识别你传入的上下文缓冲区。必须通过%input指令在PEG文件中显式指定自定义读取逻辑,才能让解析器从你的缓冲区取数据,而非标准输入。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:20:34