www.pudn.com > cwin.rar > EXP.C
/*-----------------------------------------------------------
程序模块 Exp.c : 表达式处理
-----------------------------------------------------------*/
#include
#include
#include
/*-- 函数代码定义 -------------------------*/
#define ABS 288
#define SQR 12563
#define EXP 22512
#define POW 32608
#define LG 13824
#define LN 15616
#define SIN 10448
#define COS 12064
#define TAN 12496
#define ATAN 4877
#define MAX 16752
#define MIN 18640
#define INT 3376
#define ROUND 8013
#define MOD 20016
#define HEX 30064
/*-- 全局变量定义 -------------------------*/
extern int _ErrorNo;
int _ResultType='N';
char _ResultString[21];
/*-- 静态变量定义 -------------------------*/
static unsigned char *_Token = NULL;
/*-- 内部函数说明 -------------------------*/
static int _Cdecl func_code (char *fun_name);
static double _Cdecl arith (int op,double n1,double n2);
static int _Cdecl skip_space(void);
static double _Cdecl htof (char *s);
static double _Cdecl primitive (void);
static double _Cdecl level5 (void);
static double _Cdecl level6 (void);
static double _Cdecl level7 (void);
static double _Cdecl level9 (void);
/*-----------------------------------------------------------
函数 expression : 表达式处理
-----------------------------------------------------------*/
double _Cdecl expression(string)
char *string; /* 待处理的表达式字符串 */
{
double result;
_ResultType = 'N';
_ErrorNo = 0;
_Token = string;
skip_space();
if(_Token==NULL || *_Token==0)
_ErrorNo=201;
result = level5();
if(*_Token && _ErrorNo==0)
_ErrorNo= 212;
if(_ErrorNo==0 && _ResultType=='N')
sprintf(_ResultString,"%20.6f",result);
return result;
}
/*-----------------------------------------------------------
内部函数 level5 : 处理加和减
-----------------------------------------------------------*/
static double _Cdecl level5(void)
{
double r1 = level6(),r2;
int op;
if(_ErrorNo==0)
while((op=*_Token)=='+' || op=='-')
{
_Token++;
skip_space();
r2 = level6();
if(_ErrorNo)
break;
r1 = arith(op,r1,r2);
if(_ErrorNo)
break;
}
return r1;
}
/*-----------------------------------------------------------
内部函数 level6 : 处理乘和除
-----------------------------------------------------------*/
static double _Cdecl level6(void)
{
double r1=level7(),r2;
int op;
if(_ErrorNo==0)
while((op=*_Token)=='*' || op=='/')
{
_Token++;
skip_space();
r2 = level7();
if(_ErrorNo)
break;
r1 = arith(op,r1,r2);
if(_ErrorNo)
break;
}
return r1;
}
/*-----------------------------------------------------------
内部函数 level7 : 处理正负号
-----------------------------------------------------------*/
static double _Cdecl level7(void)
{
double r;
int op=*_Token;
if(op=='-' || op=='+')
{
_Token++;
skip_space();
r = level9();
if(_ErrorNo==0)
r = arith(op,0,r);
}
else
r = level9();
return r;
}
/*-----------------------------------------------------------
内部函数 level9 : 处理括号
-----------------------------------------------------------*/
static double _Cdecl level9(void)
{
double r;
if(*_Token=='(')
{
_Token++;
skip_space();
r = level5();
if(*_Token==')')
{
_Token++;
skip_space();
}
else
_ErrorNo = 203;
}
else
r = primitive();
return r;
}
/*-----------------------------------------------------------
内部函数 primitive : 处理运算对象
-----------------------------------------------------------*/
static double _Cdecl primitive(void)
{
double r[2];
int op;
char tmp[21],*p;
skip_space();
if(*_Token==0)
_ErrorNo = 204;
/*-- 如果是数字则按数值处理 -----------*/
else if(isdigit(*_Token))
{
p = tmp;
while(isalnum(*_Token) || *_Token=='.' || *_Token=='H' || *_Token=='h')
*p++=*_Token++;
*p = 0;
if(isdigit(*(_Token-1)))
r[0]=atof(tmp);
else if(*(_Token-1)=='H' || *(_Token-1)=='h')
r[0]=htof(tmp);
else
_ErrorNo=213;
}
/*-- 如果是字母则按函数名处理 ---------*/
else if(isalpha(*_Token))
{
p = tmp;
do
{
*p++=*_Token++;
}while(isalpha(*_Token));
*p = 0;
strupr(tmp);
op = func_code(tmp);
skip_space();
/*-- 如果有括号则处理参数表 -------*/
if(*_Token=='(')
{
int i;
_Token++;
for(i=0;i<2;i++)
{
skip_space();
r[i]=level5();
if(_ErrorNo)
break;
if(*_Token==',')
{
_Token++;
skip_space();
}
else
break;
}
if(_ErrorNo==0)
{
if(*_Token!=')')
_ErrorNo=203;
else
_Token++;
skip_space();
}
if(_ErrorNo==0)
r[0]=arith(op,r[0],r[1]);
}
/*-- 如果没有参数表则出错 ---------*/
else
_ErrorNo=211;
}
else
_ErrorNo=207;
skip_space();
return r[0];
}
/*-----------------------------------------------------------
内部函数 skip_space : 跳过表达式中的空格
-----------------------------------------------------------*/
static int _Cdecl skip_space(void)
{
while(isspace(*_Token))
_Token++;
}
/*-----------------------------------------------------------
内部函数 arith : 运算
-----------------------------------------------------------*/
static double _Cdecl arith(int op,double n1,double n2)
{
if(op!=HEX && _ResultType=='C')
{
_ErrorNo=208;
return n1;
}
switch(op)
{
case '+':
n1+=n2;
break;
case '-':
n1-=n2;
break;
case '*':
n1*=n2;
break;
case '/':
n1/=n2;
break;
case ABS:
n1=fabs(n1);
break;
case SQR:
if(n1>=0)
n1=sqrt(n1);
else
_ErrorNo=209;
break;
case EXP:
n1=exp(n1);
break;
case POW:
n1=pow(n1,n2);
break;
case LG:
if(n1<=0.0)
_ErrorNo=210;
else
n1=log10(n1);
break;
case LN:
if(n1<=0.0)
_ErrorNo=210;
else
n1=log(n1);
break;
case SIN:
n1=sin(n1);
break;
case COS:
n1=cos(n1);
break;
case TAN:
n1=tan(n1);
break;
case ATAN:
n1=atan2(n1,n2);
break;
case MAX:
n1=(n1>=n2?n1:n2);
break;
case MIN:
n1=(n1<=n2?n1:n2);
break;
case INT:
{
long tmp=n1;
n1=tmp;
}
break;
case ROUND:
{
int i=n2;
n1*=pow(10.0,i);
n2=floor(n1);
if(n1-n2>=0.5)
n2+=1.0;
else if(n1-n2<=-0.5)
n2-=1.0;
n1=n2/pow(10.0,i);
}
break;
case MOD:
n1=fmod(n1,n2);
break;
case HEX:
sprintf(_ResultString,"%lXH",(long)(n1));
_ResultType='C';
break;
default:
_ErrorNo=211;
}
return n1;
}
/*-----------------------------------------------------------
内部函数 func_code : 函数名转换为代码
-----------------------------------------------------------*/
static int _Cdecl func_code(char *fun_name)
{
int code=0,i,len=strlen(fun_name);
for(i=0;i<4;i++)
{
code<<=4;
if(i='A' && *s<='F')
v=v*16-'A'+10+(*s);
else
break;
s++;
}
return v*=sign;
}