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

Windows下Bison/Flex生成的布尔计算器EXE运行异常求助

布尔计算器运行异常的问题排查与修复

核心问题分析

  • 语义动作与栈逻辑混乱:
    你自定义了bool stack[]存储布尔值,但处理IDENTIFIER时错误操作Bison内部的yystack而非自己的栈;同时完全缺失标识符到布尔值的映射逻辑——程序不知道输入的变量(如a、b)是true还是false,直接操作栈会触发未定义行为。另外expression的%type被定义为<identifier>,但实际需要布尔值结果,类型不匹配导致后续printf("%s", $1)完全错误。
  • 语法规则错误:
    input规则的空规则会让程序无输入时直接结束,且line '\n'的动作里用字符串格式打印布尔值,类型不匹配引发错误;同时缺少表达式结果的正确输出逻辑,无法将计算后的布尔值转为"True"/"False"输出。
  • 缺失关键函数实现:
    仅声明yyerror但未实现,语法错误时Bison无法正确处理,可能导致程序崩溃。
  • Flex错误处理不完整:
    遇到无效字符时仅打印提示但未终止解析,可能导致后续解析混乱。

修正后的代码

Flex文件(boolcalc.l)

%{
#include "boolcalc.tab.h"
%}

%%

[a-zA-Z][a-zA-Z0-9]*  { yylval.identifier = strdup(yytext); return IDENTIFIER; }
"and"                 { return AND; }
"or"                  { return OR; }
"not"                 { return NOT; }
"true"                { yylval.bool_val = true; return BOOL_LITERAL; }
"false"               { yylval.bool_val = false; return BOOL_LITERAL; }

[ \t]                 ; /* 跳过空白符 */
\n                    { return '\n'; }

.                     { fprintf(stderr, "Invalid character: %c\n", *yytext); exit(1); }
%%

int yywrap() {
    return 1;
}

Bison文件(boolcalc.y)

%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_EXPR_LENGTH 100

int yylex();
void yyerror(const char *msg) {
    fprintf(stderr, "Syntax error: %s\n", msg);
}

// 变量映射表(示例),可扩展为动态哈希表
typedef struct {
    char* name;
    bool value;
} VarMap;
VarMap vars[MAX_EXPR_LENGTH];
int var_count = 0;

bool get_var_value(char* name) {
    for (int i = 0; i < var_count; i++) {
        if (strcmp(vars[i].name, name) == 0) {
            return vars[i].value;
        }
    }
    fprintf(stderr, "Undefined variable: %s\n", name);
    exit(1);
}

%}

%union {
    char* identifier;
    bool bool_val;
}

%token <identifier> IDENTIFIER
%token <bool_val> BOOL_LITERAL
%token AND OR NOT

%left OR
%left AND
%right NOT

%type <bool_val> expression

%%

input:
    | input line '\n' { printf("%s\n", $2 ? "True" : "False"); }
    ;

line: expression { $$ = $1; }
    | error { $$ = false; fprintf(stderr, "Invalid expression\n"); }
    ;

expression:
        IDENTIFIER     { $$ = get_var_value($1); free($1); }
    |   BOOL_LITERAL   { $$ = $1; }
    |   expression AND expression { $$ = $1 && $2; }
    |   expression OR expression  { $$ = $1 || $2; }
    |   NOT expression            { $$ = !$2; }
    |   '(' expression ')'        { $$ = $2; }
    ;

%%

int main(int argc, char **argv) {
    // 预定义示例变量
    vars[var_count].name = strdup("a");
    vars[var_count].value = true;
    var_count++;
    vars[var_count].name = strdup("b");
    vars[var_count].value = false;
    var_count++;

    printf("Boolean Calculator (supports variables a=true, b=false, true/false, and/or/not, parentheses)\n");
    printf("Enter expression, press Enter to calculate:\n");

    yyparse();

    // 释放变量内存
    for (int i = 0; i < var_count; i++) {
        free(vars[i].name);
    }

    printf("\nPress any key to exit...");
    getchar();
    getchar();
    return 0;
}

编译与运行说明

  1. 生成词法分析器:flex boolcalc.l
  2. 生成语法分析器:bison -d boolcalc.y
  3. 编译生成EXE:gcc -o boolcalc.exe lex.yy.c boolcalc.tab.c
  4. 运行程序:直接双击boolcalc.exe或在控制台执行boolcalc.exe

关键改进点

  • 添加布尔字面量(true/false)支持,保留变量映射功能
  • 修正语义动作,直接在语法规则中计算布尔值,无需手动维护栈
  • 实现yyerror函数,规范语法错误处理
  • 修复内存泄漏问题,释放strdup分配的内存
  • 优化退出逻辑,确保程序运行后等待用户输入再关闭

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:35:13