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.
答案 0 :(得分:1)
#define YYSTYPE double
extern int yylval;
哪个是语义类型int
或double
?
由于您使用atof
和printf("%g", $$)
,我认为您的意图是语义类型是浮点数。但是你的声明并没有实现这个目标:
定义宏YYSTYPE仅在解析器中有效。扫描仪从不使用该宏。在解析器中,默认类型为int
。
yylval
在解析器中声明(根据该文件中的定义,类型为YYSTYPE
)。所以它绝对是int
并且扫描仪中的extern
声明是正确的,但不受欢迎。
使用格式代码%g
打印int
是未定义的行为。所有数字似乎打印为0.0的事实并不令人惊讶,但随后UB没有任何行为令人惊讶。如果您在编译解析器时甚至启用了编译器警告,那么这可能是您忽略的警告之一。你应该启用这些警告并认真对待它们;这种习惯会帮助你解决自己的问题。