lex/bison program to evaluate an expression

时间:2016-04-15 11:11:29

标签: bison flex-lexer yacc lex

The following is yacc code:

%{
#include<stdio.h>
#include<math.h>
%}
%token NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%%
statement:expression {printf("Answer=%g\n",$1);}
;
expression:expression'+'expression {$$=$1+$3;}
|expression'-'expression {$$=$1-$3;}
|expression'*'expression {$$=$1*$3;}
|expression'/'expression {if($3==0)
yyerror("Divide by Zero");
else
$$=$1/$3;
}
|'-'expression %prec UMINUS {$$= -$2;}
|'('expression')' {$$=$2;}
|NUMBER {$$=$1;}
;
%% 
int main(void)
{
printf("Enter the Expression");
yyparse();
printf("\n\n");
return 0;
}
int yyerror(char *error)
{
printf("%s\n",error);
return 0;
}

The following is lex code:

%{
#include<stdio.h>
#include "y.tab.h"
#define YYSTYPE double
extern int yylval;
%}
%%
[0-9]+|[0-9]*\.[0-9]+   { yylval=atof(yytext); return NUM;}
'\n'                    { return 0;}
'\t'                    {}
.                       {return yytext[0]; }
%%
int yywrap()
{
    return 1;
}

I compiled both lex and yacc code. There are no explicit errors except a few warnings. But when I run the executable file it shows no value but 0.000000.

1 个答案:

答案 0 :(得分:1)

#define YYSTYPE double
extern int yylval;

哪个是语义类型intdouble

由于您使用atofprintf("%g", $$),我认为您的意图是语义类型是浮点数。但是你的声明并没有实现这个目标:

  • 定义宏YYSTYPE仅在解析器中有效。扫描仪从不使用该宏。在解析器中,默认类型为int

  • yylval在解析器中声明(根据该文件中的定义,类型为YYSTYPE)。所以它绝对是int并且扫描仪中的extern声明是正确的,但不受欢迎。

  • 使用格式代码%g打印int是未定义的行为。所有数字似乎打印为0.0的事实并不令人惊讶,但随后UB没有任何行为令人惊讶。如果您在编译解析器时甚至启用了编译器警告,那么这可能是您忽略的警告之一。你应该启用这些警告并认真对待它们;这种习惯会帮助你解决自己的问题。