kolibrios-gitea/programs/other/graph/parser.cpp
barsuk 9166e950b4 uploaded graph
git-svn-id: svn://kolibrios.org@1005 a494cfbc-eb01-0410-851d-a64ba20cac60
2009-01-28 15:13:38 +00:00

493 lines
7.0 KiB
C++

#include "func.h"
#include "parser.h"
// token types
#define DELIMITER 1
#define VARIABLE 2
#define NUMBER 3
#define FUNCTION 4
#define FINISHED 10
// error codes
#define ERR_BADFUNCTION -1
#define ERR_BADNUMER -2
#define ERR_GENERAL -3
#define ERR_NOBRACKET -4
#define ERR_BADVARIABLE -5
#define ERR_OVERFLOW -6
double tg(double d)
{
return sin(d) / cos(d);
}
double ctg(double d)
{
return cos(d) / sin(d);
}
double exp(double x)
{
__asm {
fld x
FLDL2E
FMUL
FLD st(0)
FLD1
FXCH
FPREM
F2XM1
fadd
FSCALE
FSTP st(1)
}
}
double log(double x)
{
//return 0.0;
__asm {
FLD1
FLD x
FYL2X
FLDLN2
FMUL
}
}
double sqrt(double x)
{
__asm {
fld x
fsqrt
}
}
double atan(double x)
{
return 0.0; // â ëîì
}
double pow(double x, double y)
{
return 0.0; // â ëîì, ïóñêàé ñ÷èòàþò ÷åðåõ exp è log
}
// represents general mathematical function
typedef double(*matfunc)(double);
// used to link function name to the function
typedef struct
{
char name[10];
matfunc f;
} func;
// the list of functions
const int max_func = 12;
func functions[max_func] =
{
"", NULL,
"sin", &sin,
"cos", &cos,
"exp", &exp,
"sqrt", &sqrt,
"log", &log,
"tg", &tg,
"ctg", &ctg,
"arcsin", &asin,
"arccos", &acos,
"arctg", &atan,
"abs", &fabs
};
// all delimiters
const char *delim="+-*^/%=;(),><"; // not bad words
// structure for most parser functions
char token[80];
int token_type;
char *prog;
double x_value;
int code; // error code
int isdelim(char c)
{
//return strchr(delim, c) != 0;
for (int i = 0; i < 14; i++)
if (c == delim[i])
return 1;
return 0;
}
int isdigit(char c)
{
return (c >= '0' && c <= '9');
}
int isalpha2(char c)
{
return ((c >= 'a' && c <= 'z')
|| (c >= 'A' && c <= 'Z'));
}
int iswhite(char c)
{
return (c==' ' || c=='\t');
}
void serror(int code)
{
::code = code;
// longjmp(j, code);
}
void set_exp(char *exp, double x)
{
prog = exp;
x_value = x;
}
int get_token()
{
int tok;
char *temp;
(token_type) = 0;
tok = 0;
temp = (token);
if (*(prog) == '\0')
{
*(token) = 0;
tok = FINISHED;
return ((token_type) = DELIMITER);
}
while (iswhite(*(prog))) ++(prog);
if (isdelim(*(prog)))
{
*temp = *(prog);
(prog)++;
temp++;
*temp = 0;
return ((token_type) = DELIMITER);
}
if (isdigit(*(prog)))
{
while (!isdelim(*(prog)))
*temp++=*(prog)++;
*temp = '\0';
return ((token_type) = NUMBER);
}
if (isalpha2(*(prog)))
{
while (!isdelim(*(prog)))
*temp++=*(prog)++;
(token_type) = VARIABLE;
}
*temp = '\0';
if ((token_type) == VARIABLE)
{
tok = look_up((token));
if (tok)
(token_type) = FUNCTION;
}
return (token_type);
}
int sign(double d)
{
if (d > 0.0)
return 1.0;
if (d < 0.0)
return -1.0;
return 0.0;
}
void putback()
{
char *t;
t = (token);
for (;*t;t++)
(prog)--;
}
int get_exp(double *hold)
{
int res;
code = 0;
// if (res = setjmp(j) != 0)
// return code;
get_token();
if (!*(token))
{
return 0;
}
level2( hold);
putback();
return 0;
}
void level2(double *hold)
{
char op;
double h;
level3( hold);
while ((op=*(token)) == '+' || op == '-')
{
get_token();
level3( &h);
arith(op, hold, &h);
}
}
void level3(double *hold)
{
char op;
double h;
level4( hold);
while ((op=*(token)) == '*' || op == '/' || op == '%')
{
get_token();
level4( &h);
arith( op, hold, &h);
}
}
void level4(double *hold)
{
double h;
level5( hold);
if (*(token) == '^')
{
get_token();
level5( &h);
arith( '^', hold, &h);
}
}
void level5(double *hold)
{
char op;
op = 0;
if (((token_type) == DELIMITER) && *(token) == '+' || *(token) == '-')
{
op = *(token);
get_token();
}
level6( hold);
if (op)
unary(op, hold);
}
void level6(double *hold)
{
if ((*(token) == '(') && ((token_type) == DELIMITER))
{
get_token();
level2( hold);
if (*(token) != ')')
serror( ERR_NOBRACKET);
get_token();
}
else
primitive( hold);
}
void calc_function(double *hold)
{
double d;
int i;
i = look_up(token);
if (i == 0)
serror(ERR_BADFUNCTION); // error
get_token();
if (*(token) != '(')
serror(ERR_NOBRACKET); // error
get_token();
level2(hold);
get_token();
d = functions[i].f(*hold);
*hold = (functions[i].f)(*hold);
// else
// serror( ERR_OVERFLOW);
}
void primitive(double *hold)
{
switch (token_type)
{
case VARIABLE:
*hold = find_var(token);
get_token();
return;
case NUMBER:
//
//*hold = atof((token));
//if (sscanf(token, "%lf", hold) != 1)
*hold = convert(token);
if (*hold == ERROR)
serror( ERR_BADNUMER);
get_token();
return;
case FUNCTION:
calc_function( hold);
return;
default: // error
return;
}
}
void arith(char op, double *r, double *h)
{
double t;
switch(op)
{
case '-':
*r = *r - *h;
break;
case '+':
*r = *r + *h;
break;
case '*':
*r = *r * *h;
break;
case '/':
if (*h == 0)
serror( ERR_OVERFLOW);
else
*r = (*r) / (*h);
break;
case '%':
t = (*r) / (*h);
*r = *r - (t * (*h));
break;
case '^':
*r = pow(*r, *h);
break;
}
}
void unary(char op, double *r)
{
if (op == '-')
*r = -(*r);
}
double find_var(char *s)
{
//return 0; // not imp
//int i;
//for (i = 0; i < kvar; i++)
// if (strcmp(vars[i].name, s) == 0)
// return vars[i].value;
if (s[1] == '\0' && (s[0] == 'x' || s[0] == 'X'))
//if (strcmp(s,"x") == 0 || strcmp(s,"X") == 0)
return x_value;
serror( ERR_BADVARIABLE);
return 0; // to make compiler very happy
//printf("\nPlease enter value for variable \"%s\": ", s);
//scanf("%lf", &vars[kvar].value);
//strcpy(vars[kvar].name, s);
//kvar++;
//return vars[kvar - 1].value;
}
bool strcmp(char *s1, char *s2)
{
int i;
for (i = 0;;i++)
{
if (s1[i] == '\0')
if (s2[i] == '\0')
return 0;
else
return 1;
else
if (s2[i] == '\0')
return 1;
else
{
if (s1[i] != s2[i])
return 1;
}
}
}
int look_up(char *s)
{
int i;
for (i = 0; i < max_func; i++)
if (strcmp(s, functions[i].name) == 0)
return i;
return 0; // search command/function name
}
/*
void delete_white(char *buf)
{
int len = strlen(buf);
char *d = (char *)malloc(len + 1);
char *t = buf;
strcpy(d, buf);
d[len] = '\0';
int i;
for (i = 0; i < len; i++)
if (!iswhite(d[i]))
*t++=d[i];
*t++='\0';
free(d);
}
*/
/*
void main(void)
{
= (parser_struct)malloc(sizeof(parser_struct));
double a;
char buffer[256];
printf("Enter expression: ");
memset(buffer, 0, 256);
gets(buffer);
prog = buffer;
delete_white(buffer);
a = 0;
x_value = 3;
get_exp( &a);
printf("result: %lg\n", a);
getch();
}
*/