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

Flex&Bison逻辑表达式工具异常:输入无响应且报语法错误

问题分析与修复方案

核心问题

你的代码存在两个关键错误,导致程序无输出或报错:

  1. 重复定义函数引发编译问题
    Bison文件中重复定义了main和yyerror函数,位于两个%%块之后,这会触发编译器的「重复定义」错误(你当前的编译步骤理论上会失败,可能是你粘贴代码时的冗余内容)。

  2. Lexer吃掉换行符,Parser无法触发输出
    Flex规则里[ \t\n]+将换行符视为空白字符直接跳过,但Bison的输入规则input: input expr '\n'需要接收换行符来触发结果打印,导致输入表达式后按回车无任何输出。


修正后的代码

1. 修正Flex文件 lexer.l

调整空白字符处理规则,仅跳过空格和制表符,把换行符返回给Parser:

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

%%

"&&"        { return AND; }
"||"        { return OR; }
"!"         { return NOT; }
"=="        { return EQ; }
"!="        { return NEQ; }
"<="        { return LEQ; }
">="        { return GEQ; }
"<"         { return LT; }
">"         { return GT; }
"("         { return LPAREN; }
")"         { return RPAREN; }
[0-9]+      { yylval = atoi(yytext); return NUM; }
"true"      { return TRUE; }
"false"     { return FALSE; }
[ \t]+      { /* 仅跳过空格和制表符 */ }
"\n"        { return '\n'; } // 将换行符返回给Parser,触发输出动作
.           { return yytext[0]; }

%%

int yywrap() {
    return 1;
}

2. 修正Bison文件 parser.y

删除重复的main和yyerror定义,同时添加计数重置逻辑,避免多次输入后累计计数:

%{
#include <stdio.h>

int comparisons = 0;
int actual_comparisons = 0;

void yyerror(const char *s);
int yylex(void);
%}

%token AND OR NOT EQ NEQ LEQ GEQ LT GT LPAREN RPAREN NUM TRUE FALSE

%left OR
%left AND
%right NOT
%nonassoc EQ NEQ LEQ LT GT GEQ

%%

input: input expr '\n' { 
    printf("%s, %d, %d\n", $2 ? "TRUE" : "FALSE", comparisons, actual_comparisons);
    // 每次求值后重置计数,避免累计
    comparisons = 0;
    actual_comparisons = 0;
}
    | /* empty */      { /* 空规则,处理初始输入 */ }
    ;

expr: expr OR expr       { $$ = $1 || $3; comparisons += 1; actual_comparisons += ($1 ? 0 : 1); }
    | expr AND expr      { $$ = $1 && $3; comparisons += 1; actual_comparisons += ($1 ? 1 : 0); }
    | NOT expr           { $$ = !$2; }
    | expr EQ expr       { $$ = $1 == $3; comparisons += 1; actual_comparisons += 1; }
    | expr NEQ expr      { $$ = $1 != $3; comparisons += 1; actual_comparisons += 1; }
    | expr LEQ expr      { $$ = $1 <= $3; comparisons += 1; actual_comparisons += 1; }
    | expr GEQ expr      { $$ = $1 >= $3; comparisons += 1; actual_comparisons += 1; }
    | expr LT expr       { $$ = $1 < $3; comparisons += 1; actual_comparisons += 1; }
    | expr GT expr       { $$ = $1 > $3; comparisons += 1; actual_comparisons += 1; }
    | LPAREN expr RPAREN { $$ = $2; }
    | NUM                { $$ = $1; }
    | TRUE               { $$ = 1; }  
    | FALSE              { $$ = 0; }  
    ;

%%

void yyerror(const char *s) {
    fprintf(stderr, "Error: %s\n", s);
    // 错误后重置计数
    comparisons = 0;
    actual_comparisons = 0;
}

int main(void) {
    return yyparse();
}

编译与测试

使用你原来的编译步骤即可:

bison -d parser.y
flex lexer.l
gcc parser.tab.c lex.yy.c -o logic_eval -lm
./logic_eval

测试示例:

  • 输入 true && false 并回车,输出 FALSE, 1, 1
  • 输入 10 > 5 || false 并回车,输出 TRUE, 2, 1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:11:01