gpt4 book ai didi

c - Bison 在表达式类型之间进行转换

转载 作者:行者123 更新时间:2023-11-30 14:49:02 32 4
gpt4 key购买 nike

我有以下 Bison 代码,并且以下语句工作正常。

1 + 1
1.0 + 1.0

但我希望以下语句起作用

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> expri termi utermi factori parti
%type <fVal> exprf termf utermf factorf partf

%%
command : expri {printf("%d\n", $1); return;}
| exprf {printf("%f\n", $1); return;}
;

expri : expri '+' termi {$$ = $1 + $3;}
| expri '-' termi {$$ = $1 - $3;}
| utermi {$$ = $1;}
;
termi : termi '*' factori {$$ = $1 * $3;}
| termi '/' factori {$$ = $1 / $3;}
| termi '%' factori {$$ = $1 % $3;}
| factori {$$ = $1;}
;
utermi : utermi '*' factori {$$ = $1 * $3;}
| utermi '/' factori {$$ = $1 / $3;}
| utermi '%' factori {$$ = $1 % $3;}
| '-' factori {$$ = -$2;}
| factori {$$ = $1;}
;
factori : factori '^' parti {$$ = pow($1, $3);}
| parti {$$ = $1;}
;
parti : '(' expri ')' {$$ = $2;}
| INTEGER {$$ = $1;}
;
/* FLOAT RULES */
exprf : exprf '+' termf {$$ = $1 + $3;}
| exprf '-' termf {$$ = $1 - $3;}
| utermf {$$ = $1;}
;
termf : termf '*' factorf {$$ = $1 * $3;}
| termf '/' factorf {$$ = $1 / $3;}
| termf '%' factorf {$$ = fmodf($1, $3);}
| factorf {$$ = $1;}
;
utermf : utermf '*' factorf {$$ = $1 * $3;}
| utermf '/' factorf {$$ = $1 / $3;}
| utermf '%' factorf {$$ = fmodf($1,$3);}
| '-' factorf {$$ = -$2;}
| factorf {$$ = $1;}
;
factorf : factorf '^' partf {$$ = pow($1, $3);}
| partf {$$ = $1;}
;
partf : '(' exprf ')' {$$ = $2;}
| FLOAT {$$ = $1;}
;
%%

虽然这两种类型在自己的分支中工作得很好,但结构(显然)非常次优,重复较多,但我不知道解决方法,也不知道如何在它们之间进行转换。

最佳答案

还有一些其他方法可以解决此问题:

  1. 最简单的解决方案(如果您不需要类型信息)是使整数适合 double 类型,然后您就可以合并规则 partipartf 等合二为一。然而,这确实会改变结构,所以它可能不是你想要的。

  2. 如果您需要类型信息,正如 Paul Ogilvie 所建议的那样,您可能需要一些 Val 结构来保存整数/ double 与类型标记的并集。同样,这可能不是您想要的,因为它确实需要更多的努力。但是...

  3. 我对此进行了更多思考,也许有一个可能的解决方案可以最大限度地减少对现有语言格式的更改。本质上,我们添加从整数到 float 的“扩大”转换规则:

    exprf: /* other exprf rules */
    | expri { $$ = $1; /* Implicit integer widening conversion*/}
    termf: /* other termf rules */
    | termi { $$ = $1; }
    utermf: /* other utermf rules */
    | utermi { $$ = $1; }
    /* ... */

    这将是一个非常hacky和笨拙的解决方案,因为会出现reduce-reduce和shift-reduce冲突。 (例如,表达式 1 + 1 可以简化为 expriexprf)。您可能想查看glr-parsingmerging glr parses修复一些含糊之处。我希望这可能是您正在寻找的东西。

前两个是更优雅的解决方案,但也许如果您确实需要,第三个选项是一个可行的选择,(我建议使用 bison -v 来尝试调试这些冲突,如果您选择此选项,然后尝试在 bison 中玩一下)。

关于c - Bison 在表达式类型之间进行转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50057492/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com