用Flex和 Bison实现一个功能更为强大的计算器,包含以下运算:
a) 加、减、乘、除运算
b) 乘方、开方运算
c) 位运算
– 与 & 、或 |、非 ~...
d) 阶乘运算 ! 对数运算log
1.进一步完善计算器功能,实现对以下语法结构的分析。还可以进一步扩充功能。
12+23*34+sin(45)/cos(56)-67
1.Calc.lex源程序如下:
%{
/*
* 一个简单计算器的Lex词法文件
*/
#include <stdlib.h>
void yyerror(char*);
/* #include "calc.tab.h" */
%}
%%
/* a-z为变量 */
[a-z] {
yylval = *yytext - 'a';
return VARIABLE;
}
/* 整数 */
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
/* 运算符 */
[-+()=/*^&|~[!SCTL#\n] {return *yytext;}
/* 空白被忽略 */
[ \t] ;
/* 其他字符都是非法的 */
. yyerror("无效的输入字符");
%%
int yywrap(void)
{
return 1;
}
(2)calc.y的源程序如下:
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
%left '^' '['
%left '!' '&'
%left '|' '~'
%left 'S' 'C''T'
%left 'L' '#'
%{
#define YYSTYPE double
#define w (0.017453292519943)
#include <math.h>
#define __STDC__ 0
void yyerror(char*);
int yylex(void);
double sym[26];
%}
%%
program:
program statement '\n'
|
;
statement:
expr {printf("%f\n", $1);}
|VARIABLE '=' expr {sym[(int)$1] = $3;}
;
expr:
INTEGER
|VARIABLE{$$ = sym[(int)$1];}
|expr '+' expr {$$ = $1 + $3;}
|expr '-' expr {$$ = $1 - $3;}
|expr '*' expr {$$ = $1 * $3;}
|expr '/' expr {$$ = $1 / $3;}
|expr '^' expr {$$ = pow($1,$3);}
|expr '[' expr {$$ = pow($3,1.0/$1);}
|expr '!' {int i,s=1;
for(i=1;i<=$1;i++)
s=s*i;
$$=s; }
|expr '&' expr { $$ = (int)($1)&(int)($3);}
|expr '|' expr { $$ = (int)($1)|(int)($3);}
|'~'expr { $$ = ~(int)($2);}
|'S''('expr')' { $$=sin($3*(w));}
|'C''('expr')' { $$=cos($3*(w));}
|'T''('expr')' { $$ = tan($3*(w));}
|'L''('expr')' { $$ = log($3);}
|expr '#' expr { $$ = (int)($1)%(int)($3);}
|'('expr')' {$$ = $2;}
;
%%
void yyerror(char* s)
{
fprintf(stderr, "%s\n", s);
}
#include "lex.yy.c"
int main(void)
{
printf("A simple calculator.\n");
printf("加(+),减(-),乘(*),除(/),乘方(^),开方([),阶乘(!).\n");
printf("与(&),或(|),非(~)\n");
printf("S (sin)、C (cos)、T (tan):三角函数\n");
printf("求对数(L),求模(#)\n");
printf("START:\n");
yyparse();
return 0;
}
心得体会:
经过这次的实验,我学到了很多新的知识和好的学习方法。第一次实验做成功了给了我很大的信心,开始很顺利,后来遇到文法相关的知识,我就又收到了挫败。不断的失败不断的重复实验,不会的问同学内部是怎么传值的,看书看相关的文法知识,百度,总之就是不断重复。终于,修改了很多次,我做出来了。这离不开同学的耐心讲解和一直坚持的自己。有时候别人告诉我放弃,可我还是选择了坚持。我一定要坚守原则坚持下去。或许,有些事开始认为不可能,只有在自己坚持做了,才会取得成果!下次继续努力吧!