C++ bison/flex:计算器将双精度值解释为整数,因此我添加了#define YYSTYPE double,但我发现了多个编译错误

C++ bison/flex:计算器将双精度值解释为整数,因此我添加了#define YYSTYPE double,但我发现了多个编译错误,c++,parsing,bison,flex-lexer,C++,Parsing,Bison,Flex Lexer,我正在使用flex和bison实现计算器,但双值被解释为整数,然后我在互联网上寻找答案,我意识到错误可能是bison将数字解释为整数,所以如果我在*yylval=atof(yytext)中输入“1.2”,则是1而不是1.2。因此,我尝试在parser.ypp中添加#define YYSTYPE double,但出现编译错误。 我知道有几个类似的问题,但都没有真正帮助我。 这是我的lex和ypp文件以及我得到的编译错误 提前谢谢 lexer.lex: %option noyywrap %optio

我正在使用flex和bison实现计算器,但双值被解释为整数,然后我在互联网上寻找答案,我意识到错误可能是bison将数字解释为整数,所以如果我在*yylval=atof(yytext)中输入“1.2”,则是1而不是1.2。因此,我尝试在parser.ypp中添加#define YYSTYPE double,但出现编译错误。 我知道有几个类似的问题,但都没有真正帮助我。 这是我的lex和ypp文件以及我得到的编译错误
提前谢谢

lexer.lex:

%option noyywrap
%option noinput
%option nounput

%{
    #include <iostream>
    #include <cstdlib>
    #include <string>
    #include <fstream>

    #include "parser.tab.hpp"

%}

%%

[0-9]+([.][0-9]+)? {
    *yylval = atof(yytext);
        return NUMBER;
}



sin {
    return SIN;
}

cos {
    return COS;
}

tan {
    return TG;
}

tg {
    return TG;
}

ctan {
    return CTG;
}

ctg {
    return CTG;
}

asin {
    return ASIN;
}

acos {
    return ACOS;
}

atan {
    return ATG;
}

actan {
    return ACTG;
}

ln {
    return LN;
}

log {
    return LOG;
}

exp {
    return EXP;
}

sqrt {
    return SQRT;
}

abs {
    return ABS;
}

mod {
    return MOD;
}

[a-z] {
    return VARIABLE;
}

[-+*/^()%!,] {
    return *yytext;
}


[ \t\n] ;

. {

}

%选项noyywrap
%无输入选项
%期权看跌期权
%{
#包括
#包括
#包括
#包括
#包括“parser.tab.hpp”
%}
%%
[0-9]+([.][0-9]+)? {
*yylval=atof(yytext);
返回号码;
}
罪{
归罪;
}
因为{
返回COS;
}
棕褐色{
返回TG;
}
甘油三酯{
返回TG;
}
ctan{
返回CTG;
}
ctg{
返回CTG;
}
阿辛{
返回ASIN;
}
acos{
返回ACOS;
}
阿坦{
返回ATG;
}
阿克坦{
返回ACTG;
}
项次{
返回项次;
}
日志{
返回日志;
}
经验{
返回经验;
}
sqrt{
返回SQRT;
}
腹肌{
返回ABS;
}
国防部{
返回模式;
}
[a-z]{
返回变量;
}
[-+*/^()%!,] {
返回*文本;
}
[\t\n];
. {
}
parser.ypp:


%{

#define YYSTYPE double


#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>

 bool indicator_calculating_value ;

extern int yylex();

void yyerror(double *return_value, std::string s);

%}




%parse-param  { double *return_value}

%left '+' '-'
%left '*' '/' '%'
%left SIN COS TG CTG ASIN ACOS ATG ACTG LN LOG MOD
%left UMINUS
%left '^' EXP SQRT
%left ABS
%left '!'


%type <double> E
%token <double> NUMBER
%token <char> VARIABLE;
%start pocetak

%%
pocetak
    : E {
       *return_value = $1;

    };

E   
    : E '+' E {
        if (indicator_calculating_value) {
            $$ = $1 + $3;
        }
    } 
    | E '*' E {

        if (indicator_calculating_value) {
            $$ = $1 * $3;
        }
    }
    | E '-' E {
        if (indicator_calculating_value) {
            $$ = $1 - $3;
        }
    }
    | E '/' E {

        if(indicator_calculating_value) {
            if ($3 == 0) {
                yyerror(0, "divide by zero");
            }
            $$ = $1 / $3;
        }
    }
    | MOD '(' E ',' E ')' {
        if(indicator_calculating_value) {
            if ($5 == 0) {
                yyerror(0, "divide by zero");
            }
            $$ = static_cast<int>($3) % static_cast<int>($5);
        }
    }
    | SIN '(' E ')' {
        if(indicator_calculating_value) {
            $$ = sin($3);
        }
    }
    | COS '(' E ')' {
        if(indicator_calculating_value) {
            $$ = cos($3);
        }
    }
    | TG '(' E ')' {
        if(indicator_calculating_value) {
            $$ = tan($3);
        }
    }
    | CTG '(' E ')' {
        if(indicator_calculating_value) {
            $$ = 1 / tan($3);
        }
    }
    | ASIN '(' E ')' {
        if(indicator_calculating_value) {
            $$ = asin($3);
        }
    }
    | ACOS '(' E ')' {
        if(indicator_calculating_value) {
            $$ = acos($3);
        }
    }       
    | ATG '(' E ')' {
        if(indicator_calculating_value) {
            $$ = atan($3);
        }
    }
    | ACTG '(' E ')' {
        if(indicator_calculating_value) {
            $$ = 1 / atan($3);
        }
    }
    | LN '(' E ')' {
        if(indicator_calculating_value) {
            $$ = log($3);
        }
    }
    | LOG '(' E ',' E ')' {
        if(indicator_calculating_value) {
            $$ = log($5) / log($3);
        }
    }
    | EXP '(' E ')' {
        if(indicator_calculating_value) {
            $$ = exp($3);
        }
    }
    | SQRT '(' E ')' {
        if(indicator_calculating_value) {
            $$ = sqrt($3);
        }
    }
    | E '^' E {
        if(indicator_calculating_value) {
            $$ = pow($1, $3);
        }
    }
    | '-' E %prec UMINUS {
        if(indicator_calculating_value) {
            $$ = -$2;
        }
    } 
    | ABS '(' E ')' {
        if(indicator_calculating_value) {
            $$ = fabs($3);
        }
    }
    | E '!' {
        if(indicator_calculating_value) {
            $$ = 1;
            for (int i = 1; i <= static_cast<int>($1); i++) {
                $$ = $$ * i;
            }
        }
    }
    | '(' E ')' {
        if(indicator_calculating_value) {
            $$ = $2;
        }
    }
    | NUMBER {
        if(indicator_calculating_value) {
            $$ = $1;
        }
    }
    | VARIABLE {

    }
    ;
%%

void yyerror(double *return_value, std::string s)
{
   std::cout << s << std::endl;

}

int main() {

    indicator_calculating_value = true;

    double value = 0.0;
    yyparse(&value);

    std::cout << value << std::endl;



    return 0;
}









%{
#定义YYSTYPE双精度
#包括
#包括
#包括
#包括
布尔指示符计算值;
extern int yylex();
无效错误(双*返回值,标准::字符串s);
%}
%解析参数{double*返回值}
%左'+''-'
%左'*''/''%
%左单轴TG CTG ASIN ACOS ATG ACTG LN LOG MOD
%左耳门
%左“^”EXP SQRT
%左腹肌
%左‘!’
%E型
%令牌号
%令牌变量;
%启动pocetak
%%
波切塔克
:E{
*返回值=1美元;
};
E
:E'+'E{
if(指示灯\计算\值){
$$ = $1 + $3;
}
} 
|E'*'E{
if(指示灯\计算\值){
$$ = $1 * $3;
}
}
|E'-'E{
if(指示灯\计算\值){
$$ = $1 - $3;
}
}
|E'/'E{
if(指示灯\计算\值){
如果($3==0){
yyerror(0,“除以零”);
}
$$ = $1 / $3;
}
}
|MOD'('E','E')'{
if(指示灯\计算\值){
如果($5==0){
yyerror(0,“除以零”);
}
$$=静态演员阵容($3)%静态演员阵容($5);
}
}
|SIN'('E')'{
if(指示灯\计算\值){
$$=sin(3美元);
}
}
|COS'('E')'{
if(指示灯\计算\值){
$$=cos(3美元);
}
}
|TG'('E')'{
if(指示灯\计算\值){
$$=tan(3美元);
}
}
|CTG'('E')'{
if(指示灯\计算\值){
$$=1/吨(3美元);
}
}
|ASIN'('E')'{
if(指示灯\计算\值){
$$=asin(3美元);
}
}
|ACOS'('E')'{
if(指示灯\计算\值){
$$=ACO(3美元);
}
}       
|ATG'('E')'{
if(指示灯\计算\值){
$$=atan(3美元);
}
}
|ACTG'('E')'{
if(指示灯\计算\值){
$$=1/澳大利亚元(3美元);
}
}
|LN'('E')'{
if(指示灯\计算\值){
$$=对数($3);
}
}
|日志'('E','E')'{
if(指示灯\计算\值){
$$=对数($5)/对数($3);
}
}
|EXP'('E')'{
if(指示灯\计算\值){
$$=exp(3美元);
}
}
|SQRT'('E')'{
if(指示灯\计算\值){
$$=平方米(3美元);
}
}
|"^"E{
if(指示灯\计算\值){
$$=战俘($1,$3);
}
}
|“-”E%前白蛋白{
if(指示灯\计算\值){
$$ = -$2;
}
} 
|ABS'('E')'{
if(指示灯\计算\值){
$$=晶圆厂(3美元);
}
}
|E'!'{
if(指示灯\计算\值){
$$ = 1;

对于(inti=1;i,bison文件定义了两种不同类型的符号:

%type <double> E
%token <double> NUMBER
%token <char> VARIABLE;
通过该声明,bison将声明一个包含两个名为
number
id
的成员的
union
类型。它将自动使
$n
引用正确的成员(如果
$n
引用的符号具有已知类型)通过附加成员选择器。换句话说,如果
$1
引用了一个
数字
,bison将在生成的代码中用类似于
堆栈[top-2+1]的东西替换它。数字
(如果没有
%union
和类型声明,替换将类似于
堆栈[top-2+1]

Bison不要求您使用
%union
。如果您不这样做,并且您仍然为您的令牌和非终端声明类型,Bison将假定您知道您在做什么,并且您以某种方式将
YYSTYPE
声明为复合类型。它将执行完全相同的替换,向堆栈的引用添加成员选择器具有已知类型的值

因此,在您的例子中,您已经声明了
%typee
,因此bison将在
$1
引用符号
E
的动作中替换
$1
,类似于
堆栈[top-4+1]。double

当然,这会导致编译器阻塞。
double
是一个保留字,不能用作复合成员名,而且无论如何
YYSTYPE
是一个标量(一个
double
),因为这是您定义它的方式

您还没有尝试编译扫描仪,但在那里您将遇到类似的问题
%type <double> E
%token <double> NUMBER
%token <char> VARIABLE;
%union {
     double number;
     char id;
}
%token <number> NUMBER
#ifndef YYSTYPE
#define YYSTYPE int
#endif