Bison表达式类型转换问题:实现浮点与整数混合运算
搞定Bison整数与浮点混合运算的小调整
嘿,我来帮你解决这个混合运算的问题!你现在的Bison代码能正常处理纯整数或纯浮点的运算,但一碰到1.0 + 1这种混合类型就卡壳了,咱们不用大改现有代码结构,只需要做几个针对性的调整就能实现需求。
先把你提供的代码补全并修改(完全保留你原来的格式框架):
%{ #include <stdio.h> #include <math.h> #include <ctype.h> #include <string.h> #include <errno.h> /* Prototypes */ int yylex(void); void yyerror(char *); int isFloat = 0; %} %union { int iVal; double fVal; } %token <iVal> INTEGER %token <fVal> FLOAT %type <iVal> expr_int %type <fVal> expr_float %type <fVal> expr // 新增顶层表达式类型,统一为浮点 %% input: | input line ; line: '\n' | expr '\n' { printf("计算结果: %f\n", $1); } ; // 核心调整:让expr兼容整数和浮点,并统一转成浮点运算 expr: expr_int { $$ = (double)$1; } // 整数自动转为浮点 | expr_float { $$ = $1; } | expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { if ($3 == 0.0) { yyerror("除数不能为0"); $$ = 0.0; } else { $$ = $1 / $3; } } | '(' expr ')' { $$ = $2; } ; expr_int: INTEGER { $$ = $1; } ; expr_float: FLOAT { $$ = $1; } ; %% // 补全词法分析部分,正确识别整数和浮点 int yylex(void) { int c; // 跳过空白符 while ((c = getchar()) == ' ' || c == '\t'); if (isdigit(c)) { int int_part = 0; double frac_part = 0.0; int has_decimal = 0; double decimal_scale = 0.1; // 处理数字和小数点 while (isdigit(c) || c == '.') { if (c == '.') { if (has_decimal) { yyerror("无效的浮点数格式(多个小数点)"); return 0; } has_decimal = 1; } else if (has_decimal) { frac_part += (c - '0') * decimal_scale; decimal_scale *= 0.1; } else { int_part = int_part * 10 + (c - '0'); } c = getchar(); } ungetc(c, stdin); // 判断是整数还是浮点数 if (has_decimal) { yylval.fVal = (double)int_part + frac_part; return FLOAT; } else { yylval.iVal = int_part; return INTEGER; } } if (c == EOF) return 0; return c; } void yyerror(char *s) { fprintf(stderr, "错误: %s\n", s); } int main(void) { printf("请输入表达式(支持整数、浮点数混合运算):\n"); yyparse(); return 0; }
关键修改说明(完全保留你原有代码结构):
- 新增了一个顶层的
expr非终结符,类型设为<fVal>(浮点类型),让所有运算结果都统一为浮点,这样混合类型的运算就有了统一的计算基准。 - 给
expr添加了expr_int的分支,把整数结果强制转成浮点类型,这样整数和浮点就能在同一个规则下运算了。 - 调整了词法分析部分,确保能正确识别整数和浮点数,并分别返回对应的token和值。
现在测试一下:
输入1.0 + 1,会输出计算结果: 2.000000;输入3 * 2.5,输出计算结果: 7.500000,完全满足混合运算的需求,而且代码结构和你原来的几乎一致,没有做破坏性修改。
内容的提问来源于stack exchange,提问作者Siech0
相关产品推荐
相关产品推荐

