📄 bis1.y
字号:
/* Reverse polish notation calculator. */
%{
#include "calc.h" /* Contains definition of `symrec' */
typedef union {
double val; /* For returning numbers. */
symrec *tptr; /* For returning symbol-table pointers */
} YYSTYPE;
#include <math.h>
#include <ctype.h>
#include "lex.c"
%}
%token <val> NUM /* Simple double precision number */
%token <tptr> VAR FNCT /* Variable and Function */
%type <val> exp
%token EQ
%token ADD
%token SUB
%token MUL
%token DIV
%token ENDLINE
%token LBRO
%token RBRO
%right EQ
%left SUB ADD
%left MUL DIV
%left NEG /* negation--unary minus */
%right POW /* exponentiation */
%% /* Grammar rules and actions follow */
input: /* empty */
| input line
;
line: ENDLINE
| exp ENDLINE { printf ("The result is:\t%.10g\n", $1); }
| error ENDLINE { yyerrok; }
;
exp: NUM { $$ = $1; }
| VAR { $$ = $1->value.var; if(strcmp($1->name,"quit")==0){printf("\n********Bye-bye************\n");exit(0);} }
| VAR EQ exp { $$ = $3; $1->value.var = $3; }
| FNCT LBRO exp RBRO { $$ = (*($1->value.fnctptr))($3); }
| exp ADD exp { $$ = $1 + $3; }
| exp SUB exp { $$ = $1 - $3; }
| exp MUL exp { $$ = $1 * $3; }
| exp DIV exp { if($3==0){printf("The Zero flowover\n");$$=0;} else $$ = $1 / $3; }
| SUB exp %prec NEG { $$ = -$2; }
| exp POW exp { $$ = pow ($1, $3); }
| LBRO exp RBRO { $$ = $2; }
%%
yyerror (s) /* Called by yyparse on error */
char *s;
{
printf ("%s\n", s);
printf ("Now word is: %s\n", yylval);
}
struct init
{
char *fname;
double (*fnct)();
};
struct init arith_fncts[]
= {
"sin", sin,
"cos", cos,
"atan", atan,
"ln", log,
"exp", exp,
"sqrt", sqrt,
0, 0
};
/* The symbol table: a chain of `struct symrec'. */
symrec *sym_table = (symrec *)0;
init_table () /* puts arithmetic functions in table. */
{
int i;
symrec *ptr;
for (i = 0; arith_fncts[i].fname != 0; i++)
{
ptr = putsym (arith_fncts[i].fname, FNCT);
ptr->value.fnctptr = arith_fncts[i].fnct;
}
}
symrec *
putsym (sym_name,sym_type)
char *sym_name;
int sym_type;
{
symrec *ptr;
ptr = (symrec *) malloc (sizeof (symrec));
ptr->name = (char *) malloc (strlen (sym_name) + 1);
strcpy (ptr->name,sym_name);
ptr->type = sym_type;
ptr->value.var = 0; /* set value to 0 even if fctn. */
ptr->next = (struct symrec *)sym_table;
sym_table = ptr;
return ptr;
}
symrec *
getsym (sym_name)
char *sym_name;
{
symrec *ptr;
for (ptr = sym_table; ptr != (symrec *) 0;
ptr = (symrec *)ptr->next)
if (strcmp (ptr->name,sym_name) == 0)
return ptr;
return 0;
}
main ()
{
init_table ();
printf("\n******Begin you can type 'quit' to exit anytime you want***********\n");
yyparse ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -