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

Bison编译报错:%yacc与%define api.value.type union无法共存

解决Bison中%define api.value.type union与%yacc冲突的问题

首先,咱们先搞清楚%yacc是什么:
这是Bison提供的一个兼容指令,用来让Bison尽可能模拟传统Yacc的行为模式。传统Yacc有很多固定约定,比如默认会生成一个名为YYSTYPE的全局union类型,用来存储语法符号的值——这和你想用的现代Bison值类型机制是直接冲突的。

报错原因

当你添加%define api.value.type union时,你是在告诉Bison使用它的现代值类型系统:允许你自定义union的成员,甚至可以不用union改用结构体等类型。但%yacc指令强制Bison回到旧Yacc的行为逻辑,其中就包括锁定值类型为传统的YYSTYPE,这两个设置在值类型的处理规则上完全矛盾,所以Bison会抛出这个错误。

解决办法

你有两个选择,根据你的开发需求来选:

  1. 移除%yacc指令(推荐,适合新开发的编译器)
    既然你是在开发全新的简易编译器,没必要兼容旧Yacc的行为。直接删掉代码中的%yacc指令,然后继续使用%define api.value.type union,接下来你可以通过%token和%type直接指定每个符号的具体类型,示例如下:

    %define api.value.type union
    %token <int> INT
    %token <char*> STRING
    %type <int> expr
    

    这种方式下Bison会自动生成包含对应成员的union,比传统Yacc的写法更灵活清晰。

  2. 保留%yacc,改用传统Yacc的方式定义值类型
    如果你因为某些原因必须保留%yacc(比如要兼容旧的Yacc代码结构),那就要放弃%define api.value.type union,转而手动定义YYSTYPE:

    %yacc
    %{
    #include <stdio.h>
    // 手动定义YYSTYPE union
    typedef union {
        int ival;
        char* sval;
    } YYSTYPE;
    // 告诉Bison使用这个自定义的YYSTYPE
    #define YYSTYPE_IS_DECLARED 1
    %}
    %token INT STRING
    %type expr
    

    这种方式是传统Yacc的标准做法,需要手动管理union的定义和成员。

内容的提问来源于stack exchange,提问作者Kamal El-Saaid

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:32:06