Flex和Bison似乎不匹配
我正在尝试构建一个简单的计算器,比如键入一个算术表达式,然后按Enter键解析表达式并计算结果 下面的代码(只是野牛)是一个朋友给我的:Flex和Bison似乎不匹配,bison,flex-lexer,Bison,Flex Lexer,我正在尝试构建一个简单的计算器,比如键入一个算术表达式,然后按Enter键解析表达式并计算结果 下面的代码(只是野牛)是一个朋友给我的: %{ #include<stdio.h> #include <math.h>
%{
#include<stdio.h>
#include <math.h>
#define YYSTYPE double
extern int line_number;
int line_number=0;
void yyerror(char *err)
{
printf("Error: %s\n", err);
}
%}
%token NUMBER /* define token type for numbers */
%token PLUS
%token MINUS
%token MULT
%token DIV
%token NEWLINE
%token LPAR
%token RPAR
%% /* Bison grammar rules */
input : /* empty production to allow an empty input */
| line input
;
line : expr NEWLINE { printf("Result is %f\n", $1); }
expr : expr PLUS term { $$ = $1 + $3; }
| expr MINUS term { $$ = $1 - $3; }
| term { $$ = $1; }
;
term : term MULT factor { $$ = $1 * $3; }
| term DIV factor { $$ = $1 / $3; }
| factor { $$ = $1; }
;
factor : LPAR expr RPAR { $$ = $2; }
| NUMBER { $$ = $1; }
;
;
%%
int yylex( void ) {
int c = getchar(); /* read from stdin */
if (c < 0) return 0; /* end of the input*/
while ( c == ' ' || c == '\t' ) c = getchar( );
if ( isdigit(c) || c == '.' ) {
ungetc(c, stdin); /* put c back into input */
scanf_s ("%lf", &yylval); /* get value using scanf */
return NUMBER; /* return the token type */
}
if(c=='+')
return PLUS;
if(c=='-')
return MINUS;
if(c=='*')
return MULT;
if(c=='/')
return DIV;
if(c=='\n')
return NEWLINE;
if(c=='(')
return LPAR;
if(c==')')
return RPAR;
return c; /* anything else... return char itself */
}
main ()
{
yyparse ();
}
计算y:
%{
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define YYSTYPE double
%}
%token NUM
%token PLUS
%token MINUS
%token MUL
%token DIV
%token LP
%token RP
%token NL
%%
Input :
| Line Input
;
Line : Exp NL { printf("Result = %f\n", $1); }
Exp : Exp PLUS Term { $$ = $1 + $3; }
| Exp MINUS Term { $$ = $1 - $3; }
| Term { $$ = $1; }
;
Term : Term MUL Fact { $$ = $1 * $3; }
| Term DIV Fact { $$ = $1 / $3; }
| Fact { $$ = $1; }
;
Fact : LP Exp RP { $$ = $2; }
| NUM { $$ = $1; }
;
%%
int yyerror(char *err)
{
printf("Error: %s\n", err);
}
int main()
{
printf("Hello\n");
yyparse();
}
我哪里出错了?这里有两个问题 首先,您指定:
%option never-interactive
一旦您这样做了,您就不应该期望能够以交互方式使用该程序never interactive
有效地保证了程序不会以交互方式使用,它允许flex
生成稍微高效的代码,缓冲输入,而不是逐个字符读取。因此,在键入大量表达式或通过输入文件结束标记终止程序之前,您不会看到任何输出
第二个问题是,您没有在calc.l
中尽早定义YYSTYPE
:
%{
#include "calc.tab.h"
#include "stdlib.h"
#define YYSTYPE double
%}
yylval
在calc.tab.h
中声明为YYSTYPE-yylval代码>;如果YYSTYPE
未定义为宏(当包含calc.tab.h
时),则将其类型定义为int
,其效果是将yylval
声明为flex生成的C文件中的int
。但是,在由bison
生成的C文件中,yylval
被声明为double
。这是未定义的行为,gcc不会检测到,因为这两个翻译单元是独立编译的,链接器对类型一无所知
该错误的后果是打印的结果将不正确。(它可能打印为0.0,但由于它是未定义的行为,因此任何结果都是可能的。)
因此,您需要将#define
放在#include
之前:
%{
#define YYSTYPE double
#include <stdlib.h>
#include <unistd.h>
#include "calc.tab.h"
%}
%{
#定义YYSTYPE双精度
#包括
#包括
#包括“计算表h”
%}
你太棒了,非常感谢!!在您回复之前,我确实尝试过通过文件提供输入,但我认为所有数字都是0.0,除非我更改整个程序,将它们视为整数。你能告诉我除了ctrl-d
,还有什么方法可以输入文件结束标记吗?@Maverick:输入文件结束标记的唯一方法是ctrl-d。我建议您删除从不交互
选项;执行时间的差异很小。
%{
#include "calc.tab.h"
#include "stdlib.h"
#define YYSTYPE double
%}
%{
#define YYSTYPE double
#include <stdlib.h>
#include <unistd.h>
#include "calc.tab.h"
%}