Caculator. y
% {
# Include <math. h>
# Include <stdio. h>
# Include <stdlib. h>
# Include "calc. h"
Void yyerror (char * s)
{
Fprintf (stderr, "% s/n", s );
}
%}
% Union {
Double val;
Symrec * tptr;
}
% Token <val> NUM
% Token <tptr> VAR FNCT
% Type <val> exp
% Right' ='
% Left '-''+'
% Left '*''/'
% Left NEG
% Right '^'
%
Input:/* empty */
| Input line
;
Line: '/N'
| Exp '/N' {printf ("/t %. 10g/n", $1 );}
| Error '/N' {yyerrok ;}
;
Exp: NUM {$ = $1 ;}
| VAR {$ = $1-> value. var ;}
| VAR '= 'exp {$ = $3; $1-> value. var = $3 ;}
| FNCT '('exp')' {$ $ = (* ($1-> value. fnctptr) ($3 );}
| Exp '+ 'exp {$ = $1 + $3 ;}
| Exp '-'exp {$ = =$ 1-$3 ;}
| Exp '*' exp {$ = =$ 1*$3 ;}
| Exp '/'exp {$ $ = $1/$3 ;}
| '-' Exp % prec NEG {$ =- $2 ;}
| Exp '^' exp {$ $ = pow ($1, $3 );}
| '('Exp') '{$ = $2 ;}
;
%
# Include <ctype. h>
# Include <stdlib. h>
Int yylex (void)
{
Int c;
While (c = getchar () = ''| c = '/t ');
If (C = EOF) return 0;
/* Number */
If (C = '.' | isdigit (c )){
Ungetc (C, stdin );
Scanf ("% lf", & yylval );
Return num;
}
/* Identifier */
If (isalpha (c )){
Symrec * s;
Static char * symbuf = NULL;
Static int length = 0;
Int I;
If (length = 0 ){
Length = 40;
Symbuf = malloc (Length + 1 );
}
I = 0;
Do {
/* Grow buffer if necessary */
If (I = length ){
Length * = 2;
Symbuf = realloc (symbuf, length + 1 );
}
/* Add character */
Symbuf [I ++] = c;
/* Get next character */
C = getchar ();
} While (c! = EOF & isalnum (c ));
Ungetc (c, stdin );
Symbuf [I] = '/0 ';
S = getsym (symbuf );
If (s = NULL) s = putsym (symbuf, VAR );
Yylval. tptr = s;
Return s-> type;
}
/* Any other character is its own token */
Return c;
}
Int main (void)
{
Init_table ();
Yyparse ();
Return EXIT_SUCCESS;
}
Struct {
Char * fname;
Double (* fnct )();
} Arith_fncts [] = {
"Sin", sin,
"Cos", cos,
"Tan", tan,
"Atan", atan,
"Ln", log,
"Exp", exp,
"Sqrt", sqrt,
0, 0
};
Symrec * sym_table = NULL;
Void init_table (void)
{
Int I;
Symrec * ptr;
For (I = 0; arith_fncts [I]. fname! = NULL; I ++ ){
Ptr = putsym (arith_fncts [I]. fname, FNCT );
Ptr-> value. fnctptr = arith_fncts [I]. fnct;
}
}
Symrec * putsym (char * sym_name, int sym_type)
{
Symrec * ptr;
Ptr = malloc (sizeof (symrec ));
Ptr-> name = malloc (strlen (sym_name) + 1 );
Strcpy (ptr-> name, sym_name );
Ptr-> type = sym_type;
Ptr-> value. var = 0;
Ptr-> next = sym_table;
Sym_table = ptr;
Return ptr;
}
Symrec * getsym (char * sym_name)
{
Symrec * ptr;
For (ptr = sym_table; ptr! = NULL; ptr = ptr-> next)
If (strcmp (ptr-> name, sym_name) = 0) return ptr;
Return NULL;
}
Calc. h
# Ifndef SEEN_CALC_H
# Define SEEN_CALC_H
Typedef struct symrec;
Struct symrec {
Char * name;
Int type;
Union {
Double var;
Double (* fnctptr )();
} Value;
Symrec * next;
};
Extern symrec * sym_table;
Extern void init_table (void );
Extern symrec * putsym (char * sym_name, int sym_type );
Extern symrec * getsym (char * sym_name );
# Endif
--------------------------
By caculator. y