Flex/Bison将数字解释为浮点数



我正在尝试实现一个可以进行浮点运算的flex/bison计算器。我的弹性代码看起来像这样

%{
#include "calc.tab.h"
#include <stdlib.h>
void yyerror(char *s);
%}
digit [0-9]
integer {digit}+
real ({digit}+[.]{digit}*)|({digit}*[.]{digit}+)
exp ({integer}|{real})[eE]-?{integer}
%%
({integer}|{real}|{exp}) { yylval = atof(yytext); return NUMBER; }
[-+*/n]                 { return *yytext; }
[ tvfr]              { }
.                        { yyerror("Unknown Character"); }
%%
int yywrap(void)
{
  return 1;
}

我的野牛代码看起来像这样

%{
#include <stdio.h>
typedef double YYSTYPE;
#define YYSTYPE_IS_DECLARED
void yyerror(char *s);
extern char *yytext;
extern int yylineno;
%} 
%token NUMBER
%left '+' '-'
%left '*' '/'
%%
program: program expr 'n' { printf("%gn", $2); }
       | program 'n'
       |
       ;
expr: expr '+' expr { $$ = $1 + $3; }
    | expr '-' expr { $$ = $1 - $3; }
    | expr '*' expr { $$ = $1 * $3; }
    | expr '/' expr { $$ = $1 / $3; }
    | NUMBER { $$ = $1; }
    ;
%%
void yyerror(char *s)
{
  fprintf(stderr, "error: %s at %s, line %dn", s, yytext, yylineno);
}
int main(int argc, char *argv[])
{
  yyparse();
  return 0;
}

这不会产生正确的输出。即使词法分析器将字符串解释为双精度并将它们正确存储在 yylval 变量中,当解析器将数字相加时,它只会吐出0.0000。但是,如果我通过仅包含一个double lf_val;变量的 %union 指令将yylval声明为联合,并将atof输出存储在词法分析器中的此yylval字段中,并在解析器中声明%token <lf_val> NUMBER%type <lf_val> expr,事情似乎有效。

但是,为什么typedef YYSTYPE的简单方法不起作用呢?我也试过#define YYSTYPE double.那也没用。

关于%code,Bison的文档指出:

%code requires [...] is the best place to override Bison's default YYSTYPE
and YYLTYPE definitions.

因此,只需在野牛文件的顶部添加以下内容:

%code requires
  {
    #define YYSTYPE double
  }

您还需要删除以下两行:

typedef double YYSTYPE;
#define YYSTYPE_IS_DECLARED

请注意,据我所知,YYSTYPE_IS_DECLARED没有记录在任何地方,因此仅供野牛内部使用。

如果您不熟悉Bison的%code指令在简单的%{序言中的使用,您可能会发现文档的这一部分很有趣。

最新更新