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