lex/bison 计算表达式的程序

lex/bison program to evaluate an expression

以下为yacc代码:

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

lex代码如下:

%{
#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;
}

我编译了 lex 和 yacc 代码。除了一些警告外,没有明显的错误。但是当我 运行 可执行文件时,它没有显示任何值,而是 0.000000.

#define YYSTYPE double
extern int yylval;

那么语义类型是int还是double

由于您使用了 atofprintf("%g", $$),我想您的意图是语义类型是浮点数。但是你的声明并没有做到这一点:

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

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

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