Вы находитесь на странице: 1из 3

/**************************************/

Program for scientific calculator


/**************************************/
/******************cal.l program*******/
%{
# include<stdio.h>
# include<stdlib.h>
# include "y_tab.h"
%}
digit [0-9]+
num {digit}(\.{digit})?([eE][-+]?{digit})?
bop [-+*/^]
%%
[ \t] { }
"sin" {return SIN;}
"cos" {return COS;}
"tan" {return TAN;}
"exp" {return EXP;}
"sqrt" {return SQRT;}
[A-Za-z][A-Za-z0-9]* {yylval.p=insert_sym(yytext); return id;}
{num} {yylval.val=atof(yytext);return digit;}
{bop} {return yytext[0];}
.|\n {return yytext[0];}
%%
int yywrap()
{
return 1;
}
/******************end of cal.l program*******/
/******************cal.y program*******/
%{
# include<stdio.h>
# include<ctype.h>
# include<math.h>
# include "symt.h"
struct symtab SYM[20];
void dispsym();
%}
%union{
double val;
struct symtab *p;
}
%token <val> digit
%token <p> id
%token SIN COS TAN EXP SQRT
%nonassoc '='
%left '+' '-'
%left '*' '/'
%right '^'
%nonassoc UMINUS
%type <val> E
%%
lines :lines st
| st
;
st: id '=' E '\n' { $1->value=$3;}
| E '\n' {printf("ans=%lf\n",$1);}
;
E : E '+' E {$$=$1+$3;}
| E '-' E {$$=$1-$3;}
| E '*' E {$$=$1*$3;}
| E '/' E {$$=$1/$3;}
| E '^' E {$$=pow($1,$3);}
| '-' E %prec UMINUS {$$=-$2;}
|SIN'('E')' {$$=sin(($3*3.14)/180);}
|COS'('E')' {$$=cos(($3*3.14)/180);}
|TAN'('E')'{ $$=tan(($3*3.14)/180);}
|EXP'('E','E')' {$$=pow($3,$5);}
|SQRT'('E')' {$$=sqrt($3);}
| digit
|id {$$=$1->value;}
;
%%
main()
{
yyparse();
dispsym();
}
int yyerror()
{
return 1;
}
struct symtab *insert_sym(char *s)
{
struct symtab *p;
for(p=SYM;p<&SYM[20];p++)
{
if((p->name) &&(!strcmp(p->name,s)))
return p;
else
{
if(!p->name)
{
p->name=strdup(s);
return p;
}
}
}
}
void dispsym()
{
int i;
printf("symbol table\n");
for(i=0;i<20;i++)
{ if(SYM[i].name)
printf("%s\t%lf\n",SYM[i].name,SYM[i].value);
}
}
/******************end of cal.y program*******/
/****************** symbol table symt.h**************/
struct symtab
{
char *name;
double value;
};
struct symtab * insert_id(char *s);
/****************** end of symbol table symt.h**************/
$yacc -d -v cal.l
$lex cal.l
$cc lex.yy.c y.tab.c
$./a.out
3+5
ans=8.000000
3*5
ans=15.000000
2+6/3
ans=4.000000
a=3+6*4/2;
symbol table
a 0.000000
a=3+2
b=a+10
b+3
ans=18.000000
2+3*4^2
ans=50.000000
cos(30)
ans=0.866158
sin(30)
ans=0.499770
^Z
symbol table
a 5.000000
b 15.000000