home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 10
/
aminetcdnumber101996.iso
/
Aminet
/
misc
/
math
/
MCalc17.lha
/
MCalc
/
Source
/
Parser.y
< prev
next >
Wrap
Text File
|
1995-11-29
|
21KB
|
682 lines
%{
/*
Auto: smake MCalc
*/
static void __yy_bcopy(char *from, char *to, int count);
#undef alloca
#define alloca(x) AllocVecPool(ParsePool, x)
#undef malloc
#define malloc(x) AllocVecPool(ParsePool, x)
#undef free
#define free(x) FreeVecPool(ParsePool, x)
#undef YYINITDEPTH
#define YYINITDEPTH 512
#undef _STDC_
#define _STDC_
#undef error
#define error
extern APTR ParsePool;
extern double Value;
extern double IMem,
JMem,
KMem,
LMem,
MMem,
NMem,
OMem,
PMem,
QMem,
RMem,
SMem,
TMem,
UMem,
VMem,
WMem,
XMem,
YMem,
ZMem;
extern struct List StandardList;
extern struct List LinearList;
#define outputr(x) {Value = x;}
#define outputmem(x, y) {Value = *(x) = y;}
#define errout(x) ;
#define erroutm(x, y) ;
/**********************************************************************/
/* Chars read and read-position */
/**********************************************************************/
extern UWORD PColumn;
extern UWORD PCharRead;
// This is for the wanted angle
extern UWORD IntAngle;
/**********************************************************************/
/* Error-Value */
/**********************************************************************/
UWORD PError;
%}
/**********************************************************************/
/* Possible Return-Value */
/**********************************************************************/
%union
{
double Real;
double *MemPtr;
}
/**********************************************************************/
/* Token which returns Real */
/**********************************************************************/
%token <Real> INT_CONSTANT
/**********************************************************************/
/* Non-Priority functions */
/**********************************************************************/
%token EQU_OP OPEN_OP CLOSE_OP COMMA SEMICOLON
/**********************************************************************/
/* Set priorities */
/**********************************************************************/
%left AND_OP OR_OP XOR_OP ASL ASR LSL LSR ROL ROR
%left ADD_OP SUB_OP
%left MUL_OP DIV_OP MOD_OP
%left NEG_OP NOT_OP PERCENT CHPERCENT TPERCENT
%left POW
%nonassoc MY_ABS COS SIN TAN ACOS ASIN ATAN EXP LOG LOG10 SQRT SINH COSH TANH FAK COT N_OVER_K YROOT REZ SD_INIT SD_AVERAGE SD_DEVIATION1 SD_DEVIATION2 SD_QSUM SD_SUM SD_NUM LR_INIT LR_XAVERAGE LR_YAVERAGE LR_XDEVIATION1 LR_YDEVIATION1 LR_XDEVIATION2 LR_YDEVIATION2 LR_XQSUM LR_YQSUM LR_XSUM LR_YSUM LR_XNUM LR_YNUM LR_XYSUM LR_ALPHA LR_BETA LR_ASSESSX LR_ASSESSY LR_CORR LR_CRITCORR LR_COVAR EXG_OP
%nonassoc I_MEM J_MEM K_MEM L_MEM M_MEM N_MEM O_MEM P_MEM Q_MEM R_MEM S_MEM T_MEM U_MEM V_MEM W_MEM X_MEM Y_MEM Z_MEM
/**********************************************************************/
/* Return-Value of my terminal */
/**********************************************************************/
%type <Real> int_expr
%type <Real> standard_deviation
%type <Real> linear_regression
%type <MemPtr> memory_name
%%
/**********************************************************************/
/* Main "sentence" */
/**********************************************************************/
eingabe
: int_expr {outputr($1);}
| standard_deviation {UpdateHistoryWindow(FALSE); outputr(0.0);}
| linear_regression {UpdateHistoryWindow(TRUE); outputr(0.0);}
| memory_name EQU_OP int_expr {outputmem($1, $3);}
| error
;
/**********************************************************************/
/* Do the grammar */
/**********************************************************************/
int_expr
: OPEN_OP int_expr CLOSE_OP {$$ = $2;}
| int_expr AND_OP int_expr {$$ = (make_ulong($1)) & (make_ulong($3));}
| int_expr OR_OP int_expr {$$ = (make_ulong($1)) | (make_ulong($3));}
| int_expr XOR_OP int_expr {$$ = MyXOR(make_ulong($1),make_ulong($3));}
| int_expr NOT_OP AND_OP int_expr {$$ = MyNAND(make_ulong($1), make_ulong($4));}
| int_expr NOT_OP OR_OP int_expr {$$ = MyNOR(make_ulong($1), make_ulong($4));}
| int_expr NOT_OP XOR_OP int_expr {$$ = MyNXOR(make_ulong($1), make_ulong($4));}
| int_expr ADD_OP int_expr PERCENT {$$ = ($1 + (($1 * $3) / 100));}
| int_expr SUB_OP int_expr PERCENT {$$ = ($1 - (($1 * $3) / 100));}
| int_expr MUL_OP int_expr PERCENT {$$ = (($1 * $3) / 100);}
| int_expr CHPERCENT int_expr {$$ = ((($3 - $1) * 100) / $1);}
| int_expr TPERCENT int_expr {$$ = (($3 * 100) / $1);}
| int_expr ADD_OP int_expr {$$ = $1 + $3;}
| int_expr SUB_OP int_expr {$$ = $1 - $3;}
| int_expr MUL_OP int_expr {$$ = $1 * $3;}
| int_expr DIV_OP int_expr {if($3 == 0.0) {PError = ERR_DIVBY0; yyerror(NULL); } else $$ = $1 / $3;}
| int_expr MOD_OP int_expr {if($3 == 0.0) {PError = ERR_DIVBY0; yyerror(NULL); } else $$ = fmod($1,$3);}
| SUB_OP int_expr %prec NEG_OP {$$ = -$2; }
| NOT_OP int_expr {$$ = (~make_ulong($2)); }
| int_expr ASL int_expr {$$ = (double)MyASL(make_ulong($1),make_ulong($3)); }
| int_expr ASR int_expr {$$ = (double)MyASR(make_ulong($1),make_ulong($3)); }
| int_expr LSL int_expr {$$ = (double)MyLSL(make_ulong($1),make_ulong($3)); }
| int_expr LSR int_expr {$$ = (double)MyLSR(make_ulong($1),make_ulong($3)); }
| int_expr ROL int_expr {$$ = (double)MyROL(make_ulong($1),make_ulong($3)); }
| int_expr ROR int_expr {$$ = (double)MyROR(make_ulong($1),make_ulong($3)); }
| int_expr POW int_expr {$$ = pow($1,$3); }
| SIN int_expr {$$ = sin(calc_angle($2)); }
| COS int_expr {$$ = cos(calc_angle($2)); }
| TAN int_expr {$$ = tan(calc_angle($2)); }
| ASIN int_expr {$$ = asin(calc_angle($2)); }
| ACOS int_expr {$$ = acos(calc_angle($2)); }
| ATAN int_expr {$$ = atan(calc_angle($2)); }
| COT int_expr {$$ = cot(calc_angle($2)); }
| SINH int_expr {$$ = sinh(calc_angle($2)); }
| COSH int_expr {$$ = cosh(calc_angle($2)); }
| TANH int_expr {$$ = tanh(calc_angle($2)); }
| EXP int_expr {$$ = exp($2); }
| LOG int_expr {$$ = log($2); }
| LOG10 int_expr {$$ = log10($2); }
| MY_ABS int_expr {$$ = fabs($2); }
| SQRT int_expr {if($2 < 0.0) {PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = sqrt($2);}
| int_expr N_OVER_K int_expr {if($1 < 0.0 || ($1 - $3) < 0.0 || $1 > 170.0 || ($1 - $3) > 170.0 || $3 < 0.0 || $3 > 170.0) {PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = (calc_fak($1) / (calc_fak($3) * calc_fak($1 - $3)));}
| int_expr YROOT int_expr {if($1 < 0.0) {PError = ERR_DIVBY0; yyerror(NULL);} else $$ = pow($3, (1/$1));}
| REZ int_expr {if($2 < 0.0) {PError = ERR_DIVBY0; yyerror(NULL);} else $$ = (1.0 / $2);}
| FAK int_expr {if($2 > 170.0) { PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = calc_fak($2);}
| int_expr FAK {if($1 > 170.0) { PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = calc_fak($1);}
| SD_AVERAGE {if(numbers_in_list(&StandardList) < 1) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_average(&StandardList, FALSE);}}
| SD_DEVIATION1 {if(numbers_in_list(&StandardList) < 1) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_population(&StandardList, FALSE);}}
| SD_DEVIATION2 {if(numbers_in_list(&StandardList) < 2) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_sample(&StandardList, FALSE);}}
| SD_QSUM {$$ = calc_powsum(&StandardList, FALSE);}
| SD_SUM {$$ = calc_sum(&StandardList, FALSE);}
| SD_NUM {$$ = (double)numbers_in_list(&StandardList);}
| LR_XAVERAGE {if(numbers_in_list(&LinearList) < 1) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_average(&LinearList, FALSE);}}
| LR_XDEVIATION1 {if(numbers_in_list(&LinearList) < 1) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_population(&LinearList, FALSE);}}
| LR_XDEVIATION2 {if(numbers_in_list(&LinearList) < 2) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_sample(&LinearList, FALSE);}}
| LR_XQSUM {$$ = calc_powsum(&LinearList, FALSE);}
| LR_XSUM {$$ = calc_sum(&LinearList, FALSE);}
| LR_XNUM {$$ = (double)numbers_in_list(&LinearList);}
| LR_YAVERAGE {if(numbers_in_list(&LinearList) < 1) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_average(&LinearList, TRUE);}}
| LR_YDEVIATION1 {if(numbers_in_list(&LinearList) < 1) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_population(&LinearList, TRUE);}}
| LR_YDEVIATION2 {if(numbers_in_list(&LinearList) < 2) {PError = ERR_UNDERFLOW; yyerror(NULL);} else {$$ = calc_sample(&LinearList, TRUE);}}
| LR_YQSUM {$$ = calc_powsum(&LinearList, TRUE);}
| LR_YSUM {$$ = calc_sum(&LinearList, TRUE);}
| LR_YNUM {$$ = (double)numbers_in_list(&LinearList);}
| LR_XYSUM {$$ = calc_xysum();}
| LR_ALPHA {$$ = calc_lralpha(); if(PError) yyerror(NULL);}
| LR_BETA {$$ = calc_lrbeta(); if(PError) yyerror(NULL);}
| LR_ASSESSX int_expr {$$ = calc_lrassessx($2); if(PError) yyerror(NULL);}
| LR_ASSESSY int_expr {$$ = calc_lrassessy($2); if(PError) yyerror(NULL);}
| LR_CORR {$$ = calc_lrcorr(); if(PError) yyerror(NULL);}
| LR_CRITCORR {$$ = pow(calc_lrcorr(), 2.0); if(PError) yyerror(NULL);}
| LR_COVAR {$$ = calc_lrcovar(); if(PError) yyerror(NULL);}
| memory_name {$<Real>$ = (*($1));}
| INT_CONSTANT
| EXG_OP OPEN_OP memory_name COMMA memory_name CLOSE_OP {double Spare; $$ = 0.0; Spare = *($3); *($3) = *($5); *($5) = Spare;}
;
standard_deviation
: SD_INIT OPEN_OP standard_input CLOSE_OP {$$ = 0.0;}
standard_input
: int_expr {if(!add_standard_value($1)) { PError = ERR_NOMEM; yyerror(NULL); }}
| int_expr COMMA standard_input {if(!add_standard_value($1)) { PError = ERR_NOMEM; yyerror(NULL); }}
;
linear_regression
: LR_INIT OPEN_OP linear_input CLOSE_OP {$$ = 0.0;}
linear_input
: int_expr SEMICOLON int_expr {if(!add_linear_value($1, $3)) { PError = ERR_NOMEM; yyerror(NULL); }}
| int_expr SEMICOLON int_expr COMMA linear_input {if(!add_linear_value($1, $3)) { PError = ERR_NOMEM; yyerror(NULL); }}
;
memory_name
: I_MEM {$$ = &IMem;}
| J_MEM {$$ = &JMem;}
| K_MEM {$$ = &KMem;}
| L_MEM {$$ = &LMem;}
| M_MEM {$$ = &MMem;}
| N_MEM {$$ = &NMem;}
| O_MEM {$$ = &OMem;}
| P_MEM {$$ = &PMem;}
| Q_MEM {$$ = &QMem;}
| R_MEM {$$ = &RMem;}
| S_MEM {$$ = &SMem;}
| T_MEM {$$ = &TMem;}
| U_MEM {$$ = &UMem;}
| V_MEM {$$ = &VMem;}
| W_MEM {$$ = &WMem;}
| X_MEM {$$ = &XMem;}
| Y_MEM {$$ = &YMem;}
| Z_MEM {$$ = &ZMem;}
;
%%
/**********************************************************************/
/* Convert a double to a long (the hard way) */
/**********************************************************************/
ULONG make_ulong(double OldVal)
{
char Buffer[26];
ULONG Dummy;
sprintf(Buffer, "%f", OldVal);
stcd_l(Buffer, (LONG *)&Dummy);
return(Dummy);
}
/**********************************************************************/
/* Calculate Fak */
/**********************************************************************/
double calc_fak(double Fak)
{
double RetVal = 1.0, i = 1.0;
while(i <= Fak)
{
RetVal *= i;
i++;
}
return(RetVal);
}
/**********************************************************************/
/* Calculate correct angle value (rad, deg, gra) */
/**********************************************************************/
double calc_angle(double Value)
{
switch(IntAngle)
{
case ID_GRAD :
{
Value = (Value * (9.0 / 10.0));
}
case ID_DEG :
{
Value = (Value / 180.0) * Pi;
break;
}
}
return(Value);
}
/**********************************************************************/
/* Error-Routine ;) */
/**********************************************************************/
int yyerror(char *s)
{
return(0);
}
/**********************************************************************/
/* Add a value to the standard regression array */
/**********************************************************************/
BOOL add_standard_value(double Value)
{
struct DoubleNode *NewNode;
if((NewNode = AllocVec(sizeof(struct DoubleNode), MEMF_CLEAR)))
{
AddHead(&StandardList, (struct Node *)NewNode);
NewNode->ValueX = Value;
return(TRUE);
}
else
return(FALSE);
}
/**********************************************************************/
/* Add a value to linear regression array */
/**********************************************************************/
BOOL add_linear_value(double ValueX, double ValueY)
{
struct DoubleNode *NewNode;
if((NewNode = AllocVec(sizeof(struct DoubleNode), MEMF_CLEAR)))
{
AddHead(&LinearList, (struct Node *)NewNode);
NewNode->ValueX = ValueX;
NewNode->ValueY = ValueY;
return(TRUE);
}
else
return(FALSE);
}
/**********************************************************************/
/* Return the number of entries in a list */
/**********************************************************************/
int numbers_in_list(struct List *Lst)
{
struct Node *CheckNode = Lst->lh_Head;
int Number = 0;
while(CheckNode->ln_Succ)
{
Number++;
CheckNode = CheckNode->ln_Succ;
}
return(Number);
}
/**********************************************************************/
/* Calc average of a list */
/**********************************************************************/
double calc_average(struct List *Lst, BOOL LinearValueY)
{
struct DoubleNode *CheckNode = (struct DoubleNode *)Lst->lh_Head;
int Number = numbers_in_list(Lst);
double Sum = 0;
if(!Number)
return(0.0);
while(CheckNode->Link.ln_Succ)
{
if(!LinearValueY)
Sum += CheckNode->ValueX;
else
Sum += CheckNode->ValueY;
CheckNode = (struct DoubleNode *)CheckNode->Link.ln_Succ;
}
return((Sum / (double)Number));
}
/**********************************************************************/
/* Calc std-deviation of population */
/**********************************************************************/
double calc_population(struct List *Lst, BOOL LinearValueY)
{
struct DoubleNode *CheckNode = (struct DoubleNode *)Lst->lh_Head;
int Number = numbers_in_list(Lst);
double Poss,
Pop = 0,
Ave = calc_average(Lst, LinearValueY),
Value;
Poss = 1.0 / (double)Number;
while(CheckNode->Link.ln_Succ)
{
if(!LinearValueY)
Value = CheckNode->ValueX;
else
Value = CheckNode->ValueY;
Pop += (pow((Value - Ave), 2.0) * Poss);
CheckNode = (struct DoubleNode *)CheckNode->Link.ln_Succ;
}
return(sqrt(Pop));
}
/**********************************************************************/
/* Calc std-deviation of sample */
/**********************************************************************/
double calc_sample(struct List *Lst, BOOL LinearValueY)
{
struct DoubleNode *CheckNode = (struct DoubleNode *)Lst->lh_Head;
int Number = numbers_in_list(Lst);
double Poss,
Pop = 0,
Ave = calc_average(Lst, LinearValueY),
Value;
Poss = 1.0 / ((double)Number - 1);
while(CheckNode->Link.ln_Succ)
{
if(!LinearValueY)
Value = CheckNode->ValueX;
else
Value = CheckNode->ValueY;
Pop += (pow((Value - Ave), 2.0) * Poss);
CheckNode = (struct DoubleNode *)CheckNode->Link.ln_Succ;
}
return(sqrt(Pop));
}
/**********************************************************************/
/* Calc sum of powers of two of entries within list */
/**********************************************************************/
double calc_powsum(struct List *Lst, BOOL LinearValueY)
{
struct DoubleNode *CheckNode = (struct DoubleNode *)Lst->lh_Head;
double Number,
Value = 0;
while(CheckNode->Link.ln_Succ)
{
if(!LinearValueY)
Number = CheckNode->ValueX;
else
Number = CheckNode->ValueY;
Value += (pow(Number, 2.0));
CheckNode = (struct DoubleNode *)CheckNode->Link.ln_Succ;
}
return(Value);
}
/**********************************************************************/
/* Calc sum of entries within list */
/**********************************************************************/
double calc_sum(struct List *Lst, BOOL LinearValueY)
{
struct DoubleNode *CheckNode = (struct DoubleNode *)Lst->lh_Head;
double Number,
Value = 0;
while(CheckNode->Link.ln_Succ)
{
if(!LinearValueY)
Number = CheckNode->ValueX;
else
Number = CheckNode->ValueY;
Value += Number;
CheckNode = (struct DoubleNode *)CheckNode->Link.ln_Succ;
}
return(Value);
}
/**********************************************************************/
/* Calc sum of x and y members */
/**********************************************************************/
double calc_xysum(void)
{
struct DoubleNode *CheckNode = (struct DoubleNode *)LinearList.lh_Head;
double Value = 0;
while(CheckNode->Link.ln_Succ)
{
Value += (CheckNode->ValueX * CheckNode->ValueY);
CheckNode = (struct DoubleNode *)CheckNode->Link.ln_Succ;
}
return(Value);
}
/**********************************************************************/
/* Calc alpha part of formular of regression */
/**********************************************************************/
double calc_lralpha(void)
{
double XSum = calc_sum(&LinearList, FALSE),
XYSum = calc_xysum(),
YSum = calc_sum(&LinearList, TRUE),
XQSum = calc_powsum(&LinearList, FALSE),
Number = (double)numbers_in_list(&LinearList);
if((pow(XSum, 2.0) - (Number * XQSum)) == 0.0)
{
PError = ERR_DIVBY0;
return(0.0);
}
return( (((XSum * XYSum) - (YSum * XQSum)) / (pow(XSum, 2.0) - (Number * XQSum))) );
}
/**********************************************************************/
/* Calc alpha part of formular of regression */
/**********************************************************************/
double calc_lrbeta(void)
{
double XSum = calc_sum(&LinearList, FALSE),
YSum = calc_sum(&LinearList, TRUE),
XYSum = calc_xysum(),
XQSum = calc_powsum(&LinearList, FALSE),
Number = (double)numbers_in_list(&LinearList);
if((pow(XSum, 2.0) - (Number * XQSum)) == 0.0)
{
PError = ERR_DIVBY0;
return(0.0);
}
return( (((XSum * YSum) - (Number * XYSum)) / (pow(XSum, 2.0) - (Number * XQSum))) );
}
/**********************************************************************/
/* Assess x value of linear regression given a y */
/**********************************************************************/
double calc_lrassessx(double y)
{
double Alpha = calc_lralpha(),
Beta = calc_lrbeta();
if(Beta == 0.0)
{
PError = ERR_DIVBY0;
return(0.0);
}
return( ((y - Alpha) / Beta) );
}
/**********************************************************************/
/* Assess y value of linear regression given an x */
/**********************************************************************/
double calc_lrassessy(double x)
{
double Alpha = calc_lralpha(),
Beta = calc_lrbeta();
return( (Alpha + (Beta * x)) );
}
/**********************************************************************/
/* Calc correlation coefficient */
/**********************************************************************/
double calc_lrcorr(void)
{
double XSum = calc_sum(&LinearList, FALSE),
YSum = calc_sum(&LinearList, TRUE),
XYSum = calc_xysum(),
Number = numbers_in_list(&LinearList),
XDev = calc_population(&LinearList, FALSE),
YDev = calc_population(&LinearList, TRUE);
if(Number == 0.0 || XDev == 0.0 || YDev == 0.0)
{
PError = ERR_DIVBY0;
return(0.0);
}
return( ( ((XYSum / Number) - ((XSum / Number) * (YSum / Number))) / (XDev * YDev) ) );
}
/**********************************************************************/
/* Calc covariant of linear regression */
/**********************************************************************/
double calc_lrcovar(void)
{
double XYSum = calc_xysum(),
Number = (double)numbers_in_list(&LinearList),
XAve = calc_average(&LinearList, FALSE),
YAve = calc_average(&LinearList, TRUE);
if(Number == 1.0)
{
PError = ERR_DIVBY0;
return(0.0);
}
return( ( (XYSum - (Number * XAve * YAve)) / (Number - 1) ) );
}