/* Minimal "scientific" calculator. The system reads and evaluates statements. Statements are either arithmetic expressions (over + and *) or assignements to one or 99 registers (R0-R99). Registers can be used in expressions. All numbers are interpreted as floating point. Example session: [Shell] ./scicalc R10=3*(5+4) > R10 = 27.000000 (3.1415*R10+3) > 87.820500 R9=(3.1415*R10+3) > R9 = 87.820496 R9+R10 > 114.820500 ... Copyright 2014 by Stephan Schulz, schulz@eprover.org. This code is released under the GNU General Public Licence Version 2. */ %{ #include #define MAXREGS 100 double regfile[MAXREGS]; extern int yyerror(char* err); extern int yylex(void); %} %union { double val; int regno; } %start stmtseq %left PLUS %left MULT %token ASSIGN %token OPENPAR %token CLOSEPAR %token NEWLINE %token REGISTER %token FLOAT %token ERROR %% stmtseq: /* Empty */ | NEWLINE stmtseq {} | stmt NEWLINE stmtseq {} | error NEWLINE stmtseq {}; /* After an error, start afresh */ stmt: assign {printf("> RegVal: %f\n", $1);} |expr {printf("> %f\n", $1);}; assign: REGISTER ASSIGN expr {regfile[$1] = $3; $$ = $3;} ; expr: expr PLUS term {$$ = $1 + $3;} | term {$$ = $1;}; term: term MULT factor {$$ = $1 * $3;} | factor {$$ = $1;}; factor: REGISTER {$$ = regfile[$1];} | FLOAT {$$ = $1;} | OPENPAR expr CLOSEPAR {$$ = $2;}; %% int yyerror(char* err) { printf("Error: %s\n", err); return 0; } int main (int argc, char* argv[]) { int i; for(i=0; i