calc_lex.l
%%
------------------------------------------------------------------------------------------
calc_yacc.y
-------------------------------------------------------------------
/* DEFINITION SECTION */
%{
#include "calc_yacc.h"
#include <math.h>
extern double yylval;
%}
WHITE_SPACE [ \t]+
END_MARKER "$"
DOUBLE_VAL ([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?)
%%
/* RULE SECTION */
{DOUBLE_VAL} { yylval = atof(yytext); return NUMBER; }
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULT; }
"/" { return DIV; }
"abs" { return ABS; }
"sqrt" { return SQRT; }
"log" { return LOG; }
"!" { return FAC; }
"^" { return POW; }
"sin" { return SIN; }
"cos" { return COS; }
"tan" { return TAN; }
"mod" { return MOD; }
"div" { return NAMO; }
"(" { return OPEN; }
")" { return CLOSE; }
"round" { return ROUND; }
"ceil" { return CEIL; }
"fix" { return FIX; }
"floor" { return FLOOR; }
{WHITE_SPACE} { ; }
{END_MARKER} { return 0;}
\n { return '\n';}
. { return(yytext[0]);}
------------------------------------------------------------------------------------------
calc_yacc.y
/* Definition Section */
%{
#include <stdio.h>
#include <math.h>
#define YYSTYPE double
double absfunction(double i){
if ( i < 0 ) return -i;
else return i;
}
int round(double i){
double a = i;
double b = (int) i;
if ( i >= 0 ){
if ( a - b >= 0.5 ){
return (int)i + 1;
}else{
return (int) i;
}
}else{
if ( a - b < -0.5 ){
return (int)i -1;
}else{
return (int)i;
}
}
}
int isinteger(double i){
double a = i;
double b = (int) i;
if ( a - b == 0 ) return 1;
else return 0;
}
int fac(double num){
int i;
int result = 1;
for ( i = 1 ; i <= num ; i++ ){
result *= i;
}
return result;
}
%}
%token NUMBER
%left PLUS, MINUS
%left MULT, DIV, MOD, NAMO
%left ABS, SQRT, LOG, SIN, COS, TAN
%right POW
%left FAC
%left ROUND, CEIL, FIX, FLOOR
%left OPEN, CLOSE
%%
/* Rule Section */
statement :statement expr '\n' { printf(" = %g\n", $2); }
|statement '\n' { printf("Insert Formula.\n"); }
|error '\n' { yyerror("Error! Review Formula!\n"); yyerrok(); }
|{}
;
expr : expr PLUS term { $$ = $1 + $3; }
| expr MINUS term { $$ = $1 - $3; }
| term
;
term : term MULT oper { $$ = $1 * $3; }
| term DIV oper {
if ( $3 == 0 ) yyerror("Divide by Zero(0)\n");
else $$ = $1 / $3;
}
| term MOD oper {
if ( $3 == 0 ) yyerror("Divide by Zero(0)\n");
else $$ = (int)$1 % (int)$3;
}
| term NAMO oper {
if ( $3 == 0 ) yyerror("Divide by Zero(0)\n");
else $$ = (int)($1 / $3);
}
| oper
;
oper : ABS ants { $$ = absfunction($3); }
| SQRT ants { $$ = sqrt($3); }
| LOG ants{
if ( $3 <= 0 ) yyerror("Log(n), n is upper than Zero(0)\n");
else $$ = log($3);
}
| SIN ants { $$ = sin($3); }
| COS ants { $$ = cos($3); }
| TAN ants { $$ = tan($3); }
| ants
;
ants : ruds POW ants { $$ = pow($1,$3); }
| ruds FAC {
if ( $1 <= 0 ) yyerror("Factorial(n), n is upper than Zero(0)\n");
else if ( isinteger($1) == 0 ) yyerror("Factorial(n), n must be inserted integer\n");
else $$ = fac($1);
}
| ruds
;
ruds : ROUND upup { $$ = round($3); }
| CEIL upup {
if ( $3 <= 0 ) yyerror("Ceil(n), n is upper than zero(0)\n");
else $$ = ceil($3);
}
| FIX upup { $$ = (int)$3; }
| FLOOR upup {
if ( $3 >= 0 ) yyerror("Floor(n), n is downer than zero(0)\n");
else $$ = floor($3);
}
| upup
;
upup : OPEN expr CLOSE { $$ = $2; }
| MINUS expr { $$ = -$2; }
| NUMBER { $$ = $1; }
;
%% -------------------------------------------------------------------