我正在尝试一个可以进行浮点运算的flex / bison计算器。我的flex代码看起来像这样
%{
#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; }
[ \t\v\f\r] { }
. { 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("%g\n", $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 %d\n", s, yytext, yylineno);
}
int main(int argc, char *argv[])
{
yyparse();
return 0;
}
这不会产生正确的输出。即使词法分析器将字符串解释为双精度并将它们正确地存储在yylval
变量中,但当解析器将数字相加时,它只会吐出0.0000
。但是,如果我通过仅包含一个yylval
变量的%union
指令将double lf_val;
声明为联合,并将atof
输出存储在yylval
的此字段中在词法分析器中,并在解析器中声明%token <lf_val> NUMBER
和%type <lf_val> expr
,事情似乎有效。
但是,为什么typedef
YYSTYPE
的直截了当的方法不起作用?我也试过了#define YYSTYPE double
。这也不起作用。
答案 0 :(得分:5)
关于%code
,Bison's documentation州:
%code requires [...] is the best place to override Bison's default YYSTYPE
and YYLTYPE definitions.
所以juste在你的野牛文件的顶部添加以下内容:
%code requires
{
#define YYSTYPE double
}
您还需要删除这两行:
typedef double YYSTYPE;
#define YYSTYPE_IS_DECLARED
请注意,就我所知,YYSTYPE_IS_DECLARED在任何地方都没有记录,因此仅供Bison内部使用。
如果您不熟悉使用Bison的%code
指令而不是简单的%{
序言,您可能会发现this section of the documentation很有趣。