元始天尊 发表于 2014-3-7 13:59:02

数学表达式解析器-(一)初期体验

学了堆栈以后,书上说可以用后缀表达式计算复杂数学表达式,因此想试试,既然开始探索,自然难度不能太低。这次选择表达式支持这些:
目的是可以计算sin(tan(x)*x)这种复杂表达式,给定定义域并画出图形
考虑到重用,因此先生成后缀表达式,因为后缀表达式是随着输入表达式固定的,而计算的时候只需要把x换成相应的值即可。
下面这些代码还处于理论阶段,因此现在称为初期体验,相信做出来以后还是蛮有用的

enum type
{
        //LEVEL0        0 1 2 3 4 5 6 7 8 9 . PI E
        LEVEL0,
        TYPE_INVALID=LEVEL0,//无效数
        TYPE_UNKNOWN,                //未知数
        TYPE_INTEGER,                //整数
        TYPE_DECIMAL,                //小数

        //LEVEL1        ()+() ()-()
        LEVEL1,
        TYPE_ADD=LEVEL1,        //和
        TYPE_SUB,                        //差

        //LEVEL2                        ()*() ()/()
        LEVEL2,
        TYPE_MUL=LEVEL2,        //积
        TYPE_DIV,                        //商

        //LEVEL3                        ()^()
        LEVEL3,
        TYPE_POW=LEVEL3,        //乘方

        //LEVEL4                        MOD() SIN() COS() TAN() ASIN() ACOS() ATAN() SINH() COSH() TANH() SQRT() LN() LOG10() EXP() CEIL() FLOOR() SGN()
        //                                        () [] {} ||
        //                                        ()!   (-())取反
        LEVEL4,
        //括号模式
        TYPE_MOD=LEVEL4,//取模
        TYPE_SIN,                //正弦
        TYPE_COS,                //余弦
        TYPE_TAN,                //正切
        TYPE_ASIN,                //反正弦
        TYPE_ACOS,                //反余弦
        TYPE_ATAN,                //反正切
        TYPE_SINH,                //双曲正弦
        TYPE_COSH,                //双曲余弦
        TYPE_TANH,                //双曲正切
        TYPE_SQRT,                //开平方
        TYPE_LN,                //自然对数
        TYPE_LOG10,                //以10为底的对数
        TYPE_EXP,                //自然指数
        TYPE_CEIL,                //向上取整
        TYPE_FLOOR,                //向下取整
        TYPE_SGN,                //符号函数
        TYPE_BRACKET,        //括号

        TYPE_ABS,                //绝对值
        TYPE_FACTORIAL,        //阶乘
        TYPE_NEG,                //取反

        LEVEL5,
};


现在仅写了如下代码,还在完善

struct numberstackdata
{
        type type;
        union
        {
                int                integer;//TYPE_INTEGER
                double        decimal;//TYPE_DECIMAL
        }data;
};

struct point
{
        int x;
        int y;
};

list<point> globalPTs;

int resolvenum(char* pos,double& data)
{//由字符串解析出小数
        bool negative=false;
        char* origin=pos;
        if(*pos == '-' || * pos == '+')
        {
                pos++;
                if(*pos == '-')
                        negative=true;
        }
        int integer=0;
        double decimal=0;
        while(*pos >= '0' && *pos <= '9')
        {
                integer=integer*10 + *pos - '0';
                pos++;
        }
        if(*pos == '.')
        {
                pos++;
                while(*pos >= '0' && *pos <= '9')
                {
                        decimal=decimal*10 + *pos - '0';
                        pos++;
                }
        }
        while(decimal >= 1.0)
        {
                decimal /= 10;
        }

        data=integer+decimal;
        if(pos-origin > 1)
                return pos-origin;
        else
                return 1;
}


bool compare(char A,char B)
{//优先级A<=B true   A>B false
        switch(A)
        {
                case '+':
                case '-':
                        switch(B)
                        {
                                case '+':
                                case '-':
                                        return true;
                                case '*':
                                case '/':
                                        return true;
                        }
                case '*':
                case '/':
                        switch(B)
                        {
                                case '+':
                                case '-':
                                        return false;
                                case '*':
                                case '/':
                                        return true;
                        }
                case '(':
                        return true;
        }
}
//MOD()    SIN()    COS()    TAN()    ACOS()    ASIN()    ATAN()    COSH()    SINH()    TANH()    SQRT()   
//()^()             ()!      LN()      EXP()   ()+()            ()-()         ()*()         ()/()      {}[]().    PI    E       |()| (-())
void main()
{//由普通表达式生成后缀表达式
        stack<char> sigstack;
        list<string> output;
        char str[]="9+(3-1)*3+10/2";//9 3 1 - 3 * + 10 2 / +
       
        int pos1=0,pos2=0;
        while(pos1<sizeof(str)-1)
        {
                if(str >= '0' && str <= '9')
                {
                        int endp=pos1;
                        while(str >= '0' && str <= '9')
                        {
                                endp++;
                        }
                        if(str == '.')
                        {
                                endp++;
                                while(str >= '0' && str <= '9')
                                {
                                        endp++;
                                }
                        }
                        string temp;
                        temp.append(str+pos1,endp-pos1);
                        output.push_back(temp);
                        pos1=endp;
                }
                else if(str == '+' || str == '-' || str == '*' || str == '/')
                {
                        if(sigstack.empty())
                        {
                                sigstack.push(str);
                        }
                        else
                        {
                                if(!compare(sigstack.top(),str))//若优先级A<B 则push
                                {
                                        while(!sigstack.empty() && !compare(sigstack.top(),str))
                                        {
                                                output.push_back(string(1,sigstack.top()));
                                                sigstack.pop();
                                        }
                                        output.push_back(string(1,str));
                                }
                                else
                                {
                                        sigstack.push(str);
                                }
                        }
                        pos1++;
                }
                else if(str == '(' || str == ')')
                {
                        if(str == '(')
                        {
                                sigstack.push('(');
                        }
                        else
                        {
                                while(sigstack.top() != '(')
                                {
                                        output.push_back(string(1,sigstack.top()));
                                        sigstack.pop();
                                }
                                sigstack.pop();
                        }
                        pos1++;
                }
        }
}


int func(list<string>& str)//由后缀表达式计算结果
{
        stack<double> numstack;
//        char str[]="9 3.1 1.2 - 3.3 * + 10.4 2.5 / +";
        int len=str.size();
        for(int pos=0;pos<len;)
        {
                if(str >= '0' && str <= '9')
                {
                        double data=0;
                        pos += resolvenum(str+pos,data);
                        numstack.push(data);
                }
                else if(str == '+' || str == '-' || str == '*' || str== '/')
                {
                        double num=numstack.top();
                        numstack.pop();
                        if(str == '+')
                                numstack.top() += num;
                        else if(str == '-')
                                numstack.top() -= num;
                        else if(str == '*')
                                numstack.top() *= num;
                        else
                                numstack.top() /= num;
                        pos++;
                }
                else
                        pos++;
        }
        cout<<numstack.top()<<endl;
}


cyycoish 发表于 2014-11-18 22:43:08

基于栈的表达式计算,弄了好几个月,现在分享一下
/*
Calculation Engine Kernel v1.0
Created By CYY 20140201
Copyright (C) 2014 Ctechnology Corporation
All Rights Resaved.
cyycoish@hotmail.com
201402042139
201402241352
201403061734--func
201403140144--x1
201403202105--no add end
201404091752SAT--ALL END
注意:AddConstants必须在AddFunc前使用
*/
//包含部分
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <Windows.h>
#include <math.h>
#include <time.h>
//#include <iostream>
//宏定义部分
#define N 4096//输入总长
#define M 1024//输入总长
#define S_NUM_MAX 4096//单个数字大小
#define S_OPR_MAX 4096//单个运算符大小
#define OFUN_NUM63//运算符数量
#define CST_CTR   5   //常数个数

#define FUN_MAX   1024//运算符数量
#define PAR_MAX   1024//函数参数数量
#define UFN_MAX   1024//自定义函数数量

#define MPI 3.1415926535897932384626433832795028841971693993751058
#define MEE 2.7182818284590452353602874713526624977572470936999595
//#define SFUN_NUM10//自定义运算符数量
//声明部分
double CALC_main(char *exp);
char *InputScanner(char *exp);
void Debug_Print_Para(void);
//
int intFunParCount = 0;//函数参数个数
double Answ = 0;//保存前一个运算结果
double pa = { 0 };//函数参数
int ix = 0;//位置标记

int iUserFun = 0;//自定义函数数量
int iParCtr = 0;//函数参数数量
int iUserCnt = 0;//自定义常量数量

enum DEGSCALE{//角度度量
        S_Rad,//弧度制
        S_Deg,//角度制
        S_Gra //梯度制
};
DEGSCALE degScale = S_Rad;//角度度量默认弧度
//错误代码
int ERR_NUM = 0;
enum ERRORNUM{
        NoError,
        MathError,
        StackError,
        SyntaxError,
        UnknownError,
};
typedef struct{
        ERRORNUM num;
        int pos;
}ERRSTRU;
ERRSTRU Error(ERRORNUM E){
        ERRSTRU ERRNUMr;
        ERRNUMr.num = E;
        ERRNUMr.pos = ix;
        return ERRNUMr;
}
//常数
typedef struct{
        char *name;
        double value;
        int number;
}CONSTANT;
//运算符结合性
enum OPRCAL{
        DoubleCalOpr,//双目运算符
        FrontCalOpr, //前缀运算符
        RearCalOpr,//后缀运算符
        IsBracket,   //是括号
        Specific,    //特殊 ,
        Functio,   //函数
        UserFun,   //自定义函数
        //VarCon       //变量/常数
};
//运算符类型
typedef struct{
        char *name;//运算符名称
        int level;//优先级
        OPRCAL ctype;//运算符结合性
        /*
        ctype取值:
        0:双目运算符
        1.前缀运算符
        2.后缀运算符
        3.括号
        */
        int number;//标识符
        char *expr;//函数表达式
        //double value;
}OTYPE;
//数栈
typedef struct{
        double stack;
        int top;
}NumSTACK;
//二级数栈存放函数参数[操作对象函数CALC_fun]
typedef struct{
        double stack;
        int top;
}NumSTACK_fun;
//符栈
typedef struct{
        OTYPE stack;
        int top;
}OprSTACK;
//初始化数栈
void InitNumSTACK(NumSTACK* s){
        (*s).top = 0;
}
//进数栈
bool NPush(NumSTACK* s, double n)
{
        //如果栈满则报错退出程序
        if ((*s).top == N - 1){
                Error(StackError);
                return false;
        }
        (*s).stack[(*s).top] = n;
        (*s).top++;
        return true;
}
//出数栈
double NPop(NumSTACK* s)
{
        //如果栈空则报错退出程序
        if ((*s).top == 0){
                Error(StackError);
                return 0;
        }
        else{
                (*s).top--;
                return (*s).stack[(*s).top];
        }
}
//初始化符栈
void InitOprSTACK(OprSTACK* s){
        (*s).top = 0;
}
//进符栈
bool OPush(OprSTACK* s, OTYPE* sign)
{
        //如果栈满则报错退出程序
        if ((*s).top == M - 1){
                Error(SyntaxError);
                return false;
        }
        (*s).stack[(*s).top] = *sign;
        (*s).top++;
        return true;
}
//出符栈
OTYPE OPop(OprSTACK *s)
{
        //栈空则报错退出程序
        if ((*s).top == 0){
                Error(SyntaxError);
        }
        else{
                (*s).top--;
                //return (*s).stack;
                return (*s).stack[(*s).top];
        }
}
//运算符表
OTYPE oper;
bool InitOperTable(void){
        /*
        oper.name="#";   oper.level=1;oper.ctype=DoubleCalOpr; oper.number=1;
        oper.name="NOT";   oper.level=2;oper.ctype=FrontCalOpr;oper.number=2;
        oper.name="~NOT";oper.level=7;oper.ctype=FrontCalOpr;oper.number=3;
        oper.name="^";   oper.level=14; oper.ctype=DoubleCalOpr; oper.number=4;
        oper.name="!";   oper.level=15; oper.ctype=RearCalOpr;   oper.number=5;
        oper.name="*";   oper.level=13; oper.ctype=DoubleCalOpr; oper.number=6;
        oper.name="/";   oper.level=13; oper.ctype=DoubleCalOpr; oper.number=7;
        oper.name="MOD";   oper.level=13; oper.ctype=DoubleCalOpr; oper.number=8;
        oper.name="AND";   oper.level=8;oper.ctype=DoubleCalOpr; oper.number=9;
        oper.name="~AND";oper.level=3;oper.ctype=DoubleCalOpr; oper.number=10;
        oper.name="+";    oper.level=12;oper.ctype=DoubleCalOpr;oper.number=11;
        //oper.name="-";    oper.level=4;oper.ctype=DoubleCalOpr;oper.number=12;
        oper.name="OR";   oper.level=9; oper.ctype=DoubleCalOpr;oper.number=12;
        oper.name="~OR";oper.level=4; oper.ctype=DoubleCalOpr;oper.number=13;
        oper.name="XOR";oper.level=10;oper.ctype=DoubleCalOpr;oper.number=14;
        oper.name="~XOR"; oper.level=5; oper.ctype=DoubleCalOpr;oper.number=15;
        oper.name="XNOR"; oper.level=11;oper.ctype=DoubleCalOpr;oper.number=16;
        oper.name="~XNOR";oper.level=6; oper.ctype=DoubleCalOpr;oper.number=17;
        oper.name="=";    oper.level=16;oper.ctype=DoubleCalOpr;oper.number=18;
        oper.name=";";    oper.level=17;oper.ctype=RearCalOpr;oper.number=19;
        oper.name="(";    oper.level=-1;oper.ctype=IsBracket;   oper.number=20;
        oper.name=")";    oper.level=0; oper.ctype=IsBracket;   oper.number=21;
        oper.name=",";    oper.level=0; oper.ctype=IsBracket;   oper.number=22;
        */
        oper.name = "NAN";   oper.level = 100; oper.ctype = Specific;   oper.number = -1;
        oper.name = "NOT";   oper.level = 25;oper.ctype = FrontCalOpr;oper.number = 2;
        oper.name = "~NOT";oper.level = 24;oper.ctype = FrontCalOpr;oper.number = 3;
        oper.name = "^";   oper.level = 14;oper.ctype = DoubleCalOpr; oper.number = 4;
        oper.name = "!";   oper.level = 15;oper.ctype = RearCalOpr;   oper.number = 5;
        oper.name = "*";   oper.level = 13;oper.ctype = DoubleCalOpr; oper.number = 6;
        oper.name = "/";   oper.level = 13;oper.ctype = DoubleCalOpr; oper.number = 7;
        oper.name = "MOD";   oper.level = 13;oper.ctype = DoubleCalOpr; oper.number = 8;
        oper.name = "AND";   oper.level = 23;oper.ctype = DoubleCalOpr; oper.number = 9;
        oper.name = "~AND";oper.level = 22;oper.ctype = DoubleCalOpr; oper.number = 10;
        oper.name = "+";    oper.level = 12; oper.ctype = DoubleCalOpr; oper.number = 11;
        oper.name = "OR";   oper.level = 21; oper.ctype = DoubleCalOpr; oper.number = 12;
        oper.name = "~OR";oper.level = 20; oper.ctype = DoubleCalOpr; oper.number = 13;
        oper.name = "XOR";oper.level = 19; oper.ctype = DoubleCalOpr; oper.number = 14;
        oper.name = "~XOR"; oper.level = 18; oper.ctype = DoubleCalOpr; oper.number = 15;
        oper.name = "XNOR"; oper.level = 17; oper.ctype = DoubleCalOpr; oper.number = 16;
        oper.name = "~XNOR"; oper.level = 16; oper.ctype = DoubleCalOpr; oper.number = 17;
        oper.name = ">>";   oper.level = 9;oper.ctype = DoubleCalOpr; oper.number = 18;
        oper.name = ";";    oper.level = 17; oper.ctype = RearCalOpr;   oper.number = 19;
        oper.name = "(";    oper.level = -1; oper.ctype = IsBracket;    oper.number = 20;
        oper.name = ")";    oper.level = 0;oper.ctype = IsBracket;    oper.number = 21;
        oper.name = ",";    oper.level = 0;oper.ctype = IsBracket;    oper.number = 22;

        oper.name = "ADD";oper.level = 99; oper.ctype = Functio;      oper.number = 23;
        oper.name = "SIN";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 24;
        oper.name = "%";    oper.level = 26; oper.ctype = RearCalOpr;   oper.number = 1;
        oper.name = "COS";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 25;
        oper.name = "TAN";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 26;

        oper.name = "~>";   oper.level = 11; oper.ctype = DoubleCalOpr; oper.number = 27;
        oper.name = "~<";   oper.level = 11; oper.ctype = DoubleCalOpr; oper.number = 28;
        oper.name = ">=";   oper.level = 11; oper.ctype = DoubleCalOpr; oper.number = 27;
        oper.name = "<=";   oper.level = 11; oper.ctype = DoubleCalOpr; oper.number = 30;
        oper.name = "==";   oper.level = 10; oper.ctype = DoubleCalOpr; oper.number = 31;
        oper.name = "<>";   oper.level = 10; oper.ctype = DoubleCalOpr; oper.number = 32;

        oper.name = "ARCSIN";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 33;
        oper.name = "ARCCOS";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 34;
        oper.name = "ARCTAN";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 35;
        oper.name = "ABS";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 36;

        oper.name = "SINH";    oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 37;
        oper.name = "COSH";    oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 38;
        oper.name = "TANH";    oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 39;

        oper.name = "ARCSINH"; oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 40;
        oper.name = "ARCCOSH"; oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 41;
        oper.name = "ARCTANH"; oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 42;

        oper.name = "LG";      oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 43;
        oper.name = "LN";      oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 44;
        oper.name = "LOG";   oper.level = 99; oper.ctype = Functio;      oper.number = 45;
        oper.name = "SGN";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 46;

        oper.name = "SQR";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 47;
        oper.name = "INT";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 48;

        oper.name = "SEC";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 49;
        oper.name = "CSC";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 50;
        oper.name = "COT";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 51;
        oper.name = "ARCSEC";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 52;
        oper.name = "ARCCSC";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 53;
        oper.name = "ARCCOT";oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 54;
        oper.name = "SECH";    oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 55;
        oper.name = "CSCH";    oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 56;
        oper.name = "COTH";    oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 57;
        oper.name = "ARCSECH"; oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 58;
        oper.name = "ARCCSCH"; oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 59;
        oper.name = "ARCCOTH"; oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 60;
        oper.name = "ROOT";    oper.level = 99; oper.ctype = Functio;      oper.number = 61;

        oper.name = "AVG";   oper.level = 99; oper.ctype = Functio;      oper.number = 62;
        oper.name = "INT";   oper.level = 99; oper.ctype = FrontCalOpr;oper.number = 63;
        //oper.name = "PI";   oper.level = 100; oper.ctype = VarCon;   oper.number = 25; oper.value = 3.14;
        return true;
}
//常数表
CONSTANT constants;//常数变量
CONSTANT functpara;//函数参数
void InitParaTable(void){
        register int i = 0;
        for (i = 0; i < PAR_MAX; i++){
                functpara.name = "";
                functpara.number = 0;
                functpara.value = 0;
        }
}
bool InitConstTable(void){
        constants.name = "NULL"; constants.value = 0;   constants.number = 1;
        constants.name = "PI";   constants.value = MPI; constants.number = 2;
        constants.name = "E";    constants.value = MEE; constants.number = 3;
        constants.name = "ANS";constants.value = 0;   constants.number = 4;
        constants.name = "RND";constants.value = 0;   constants.number = 5;
        return true;
}
/////////////////
double Sgn(double x){
        if (x > 0)
                return 1.0;
        else if (x == 0)
                return 0.0;
        else
                return -1.0;
}
//运算符运算过程表
double DOprCal(double b, double a, int number){//双目运算符运算
        switch (number){
        case 4://^
                //printf("%s\n","hello^");////////////////////
                return powf(a, b);
        case 6://*
                //printf("%s\n","hello*");////////////////////
                return a*b;
        case 7:///
                if (b != 0)
                        return a / b;
                else{
                        Error(MathError);
                        return 0;
                }
        case 8://MOD
                return (int)a % (int)b;
        case 9://AND
                return a&&b;
        case 10://~AND
                return (int)a&(int)b;
        case 11://+
                //printf("%s\n","hello+");////////////////////
                return a + b;
                //case 12://-
                //return a-b;
        case 12://OR
                //printf("%s\n","hello or");////////////////////
                return a || b;
        case 13://~OR
                return (int)a | (int)b;
        case 14://XOR
                if (a == b)
                        return 0;
                else
                        return 1;
        case 15://~XOR
                return (int)a ^ (int)b;
        case 16://XNOR
                if (a == b)
                        return 1;
                else
                        return 0;
        case 17://~XNOR
                return ~((int)a ^ (int)b);
        case 18://=
                if (a == b)
                        return 1;
                else
                        return 0;
        case 27:
                if (a > b)
                        return 1;
                else
                        return 0;
        case 28:
                if (a < b)
                        return 1;
                else
                        return 0;
        case 29:
                if (a >= b)
                        return 1;
                else
                        return 0;
        case 30:
                if (a <= b)
                        return 1;
                else
                        return 0;
        case 31:
                if (a == b)
                        return 1;
                else
                        return 0;
        case 32:
                if (a != b)
                        return 1;
                else
                        return 0;
        }
}
double FOprCal(int number, double a = 0){//单目前缀运算符运算
        int j = 0; double x = 0; char tStr = { '\0' };
        //printf("入FO的数字代码:%s\n",number);/////////////////////////
        switch (number){
        case 2://NOT
                if (a != 0)
                        return 0;
                else
                        return 1;
        case 3://~NOT
                return ~((int)a);
        case 23://add
                for (j = 0; j <= intFunParCount; j++)
                        x += pa;
                return x;
        case 24://sin
                switch (degScale){
                case S_Rad:
                        return sin(a);
                case S_Deg:
                        return sin(MPI / 180 * a);
                case S_Gra:
                        return sin(MPI / 200 * a);
                }
        case 25://cos
                switch (degScale){
                case S_Rad:
                        return cos(a);
                case S_Deg:
                        return cos(MPI / 180 * a);
                case S_Gra:
                        return cos(MPI / 200 * a);
                }
        case 26:
                switch (degScale){
                case S_Rad:
                        return tan(a);
                case S_Deg:
                        return tan(MPI / 180 * a);
                case S_Gra:
                        return tan(MPI / 200 * a);
                }
        case 33:
                x = asin(a);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 34:
                x = acos(a);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 35:
                x = atan(a);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 36:
                return fabs(a);
        case 37://sinh
                return (exp(a) - exp(-a)) / 2;
        case 38://cosh
                return (exp(a) + exp(-a)) / 2;
        case 39://tanh
                return(exp(a) - exp(-a)) / (exp(a) + exp(-a));
        case 40://arcsinh
                return log(a + sqrt(a * a + 1));
        case 41://arccosh
                return log(a + sqrt(a * a - 1));
        case 42://arctanh
                return log((1 + a) / (1 - a)) / 2;
        case 43://lg
                return log(a) / log(10.0);
        case 44://ln
                return log(a) / log(MEE);
        case 45://log
                return log(pa) / log(pa);
        case 46://sgn
                return Sgn(a);
        case 47://sqr
                return sqrt(a);
        case 48://int
                return (double)int(a);
        case 49://sec
                if (a == 0)
                        return 1.0;
                else
                        x = 1 / cos(a);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 50://csc
                x = 1 / sin(a);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 51://cot
                x = 1 / tan(a);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 52://arc sec
                if (a == 1)
                        return 0.0;
                else
                        x = atan(a / sqrt(a * a - 1)) + Sgn((a)-1) * (2 * atan(1.0));
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 53://arc csc
                x = atan(a / sqrt(a * a - 1)) + (Sgn(a) - 1) * (2 * atan(1.0));
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 54://arc cot
                x = atan(a) + 2 * atan(1.0);
                switch (degScale){
                case S_Rad:
                        return x;
                case S_Deg:
                        return MPI / 180 * x;
                case S_Gra:
                        return MPI / 200 * x;
                }
        case 55://sech
                if (a == 0)
                        return 1;
                else
                        x = 2 / (exp(a) + exp(-a));
        case 56://scsh
                x = 2 / (exp(a) - exp(-a));
        case 57://coth
                x = (exp(a) + exp(-a)) / (exp(a) - exp(-a));
        case 58://arc sech
                x = log((sqrt(-a * a + 1) + 1) / a);
        case 59://arc scsh
                x = log((Sgn(a) * sqrt(a * a + 1) + 1) / a);
        case 60://arc coth
                x = log((a + 1) / (a - 1)) / 2;
        case 61:
                return powf(pa, 1 / pa);
        case 62:
                for (j = 0; j <= intFunParCount; j++)
                        x += pa;
                return x / (intFunParCount + 1);
        case 63:
                return (double)int(a);
        default:
                //Debug_Print_Para();
                //double xxxz = 0;
                //char *cah;
                strcpy(tStr, InputScanner(oper.expr));
                //printf("\tA1st::\'%s\'\n", tStr);/////////////////////////////////////////InputScanner(oper.expr)
                return CALC_main(tStr);
        }
}
double ROprCal(double a, int number){//单目后缀运算符运算
        int k;
        double r = 1.0;
        switch (number){
        case 1:
                return (a / 100);
                //printf("hello");
        case 5://!

                for (k = 1; k <= (int)a; k++)
                        r = r*(double)k;
                return r;
        case 19://;
                ;
        }
}
//查找运算符
int IsOper(char *s){
        register int i = 0;
        //printf("iUserFun:%d\n", iUserFun);////////////////////
        for (i = 0; i <= (OFUN_NUM + iUserFun); i++){
                //printf("比较前:%s\n", oper.name);
                //if (i == 63) printf("hello\n");//////////////////////////////////
                if ((s != '\0') && (strcmp(s, oper.name) == 0)){
                        //printf("找到的:%d\n",i);/////////////////////////////////////////
                        return i;
                }
        }
        //printf("LAST:%d\n", i);/////////////////////////////////////////
        return 0;
}
//查找函数参数变量
int IsPara(char *s){
        register int i = 1;
        for (i = 1; i <= iParCtr; i++){
                if ((s != '\0'))
                        if ((strcmp(s, functpara.name) == 0))
                                return i;
        }
        return 0;
}
//查找常数
int IsConst(char *s){
        register int i = 1;
        for (i = 1; i < CST_CTR + iUserCnt; i++){
                if ((s != '\0') && (strcmp(s, constants.name) == 0)){
                        return i;
                }
        }
        return 0;
}
//符栈看栈顶
OTYPE OPeek(OprSTACK *s){
        OTYPE r;
        if ((*s).top == 0){//判栈空,空则赋等级0值
                r.level = 0;
                return r;
        }
        else
                return(*s).stack[(*s).top - 1];
}
///////////////////////////////
//字符串函数
char *Mid(char *String, long Start, long Length = -1){
        long i = 0, j = 0;
        char string = { '\0' }; strcpy(string, String);
        if (Length == -1)
                Length = strlen(string) - Start + 1;
        string = '\0';
        for (i = 0, j = Start - 1; i <= strlen(string); i++, j++)
                string = string;
        return string;
}
///////////////////////////////
bool AddFunc(char *name, char para[], char *expr){
        int i = 0;
        if (IsOper(name) != 0)
                return false;
        ++iUserFun;

        //printf("\t\\%s\\\n", oper.name);///////////////////////////////////
        oper.ctype = UserFun;
        oper.level = 99;
        oper.name = name;
        oper.number = OFUN_NUM + iUserFun;
        oper.expr = expr;
        //printf("自定义函数:\"%s\"\n", oper.name);////////////////////
        //oper
        for (i = 0; i < PAR_MAX; i++){
                //printf("参数:\"%s\"\n", para);////////////////////////////////////////
                if ((IsConst(para) == 0) && (IsPara(para) == 0) && (para != '\0')){
                        //printf("参数:\"%s\"\n", para);////////////////////////////////////////
                        functpara.name = para;
                        //iParCtr++;
                }
                else{
                        break;
                }
        }
        return true;
        //printf("自定义函数:%s\n", oper.name);////////////////////
}
void SetPara(double value){
        ++iParCtr;
        functpara.number = iParCtr;
        functpara.value = value;
}
bool ClearAllFunc(void){
        int i = 0;
        for (i = 0; i <= iUserFun; i++){
                oper.name = "";
                oper.number = 0;
        }
        iUserFun = 0;
        iParCtr = 0;
        return true;
}
//////
bool AddConstant(char *cname, double value){
        int i = 0;
        if (IsConst(cname) != 0)
                return false;
        if (IsPara(cname) != 0)
                return false;
        if (IsOper(cname) != 0)
                return false;
        ++iUserCnt;
        //printf("CST HELLO!\t%d\n", CST_CTR + iUserCnt);///////////////////////////////
        constants.name = cname;
        constants.value = value;
        constants.number = CST_CTR + iUserCnt;
        return true;
}
bool ClearAllConst(void){
        int i = 0;
        for (i = 0; i <= iUserCnt; i++){
                constants.name = "";
                constants.number = 0;
        }
        iUserCnt = 0;
        return true;
}
///////////////////////////////
void CALC_simple(OTYPE OTOpr, NumSTACK* dblStack, bool isFun = false){
        double tmpNumA = 0.0, tmpNumB = 0.0, tmpNumR = 0.0;
        int j = 0;
        //printf("CALC_simple hello\n");///////////////////////////////
        //printf("\t运算符出栈:%s\n",OTOpr.name);/////////////////////////////////
        switch (OTOpr.ctype){//检测运算符类型
        case DoubleCalOpr:
                tmpNumA = NPop(dblStack);//取出一个操作数
                //printf("\t数栈出栈A:%f\n",tmpNumA);////////////////////////////
                tmpNumB = NPop(dblStack);//取出一个操作数
                //printf("\t数栈出栈B:%f\n",tmpNumB);////////////////////////////
                tmpNumR = DOprCal(tmpNumA, tmpNumB, OTOpr.number);//双目运算符运算
                break;
        case FrontCalOpr:
                tmpNumA = NPop(dblStack);//取出一个操作数1
                //printf("\t数栈出栈A2:%f\n",tmpNumA);////////////////////////////
                tmpNumB = NPop(dblStack);//取出一个操作数2
                //printf("\t数栈出栈B2:%f\n",tmpNumB);////////////////////////////
                tmpNumR = FOprCal(OTOpr.number, tmpNumA);
                NPush(dblStack, tmpNumB);//操作数1进栈
                //printf("\t内进栈:%f\n",tmpNumB);////////////////////////////
                break;
        case RearCalOpr:
                tmpNumA = NPop(dblStack);//取出一个操作数1
                tmpNumR = ROprCal(tmpNumA, OTOpr.number);
                break;
        case Functio:
                for (j = 0; j <= intFunParCount; j++){
                        pa = NPop(dblStack);//取出一个操作数1
                        //printf("\t数栈出栈AF:%f\n", tmpNumA);////////////////////////////
                }
                tmpNumR = FOprCal(OTOpr.number);
                break;
        case UserFun:
                for (j = 0; j <= intFunParCount; j++)
                        SetPara(NPop(dblStack));//取出一个操作数
                tmpNumR = FOprCal(OTOpr.number);
                break;
        }
        NPush(dblStack, tmpNumR);//运算结果进栈
        //printf("数栈进栈 内:%f\n",tmpNumR);////////////////////////////
}
double CALC_main(char *exp){//计算
        //初始化
        //InitOperTable();
        //定义栈
        NumSTACK nStack;
        OprSTACK oStack;
        //初始化栈
        InitNumSTACK(&nStack);
        InitOprSTACK(&oStack);
        char sTmpNum = { 0 };//用于[数字整合]的临时变量
        char sTmpOpr = { 0 };//用于[运算符整合]临时变量
        char cTmpDblChar = { 0, 0 };//临时存放单个字符
        OTYPE y, w;//
        int iWhichOpr = 0;//记录运算符返回值
        //主循环
        //ix = 0;//位置标记
        if (exp == "")return 0;//空串返零
        //exp = strupr(exp);//全转为大写
        for (ix = 0; ix <= strlen(exp); ix++){
                if ((exp >= '0'&&exp <= '9') || exp == '-' || exp == '.'){//区分操作数和运算符及其进栈
                        //数字整合
                        cTmpDblChar = exp;
                        strcat(sTmpNum, cTmpDblChar);
                        if ((exp >= '0'&&exp <= '9') || exp == '-' || exp == '.'){
                                continue;
                        }
                        else{//数字进栈
                                double x = atof(sTmpNum);//转换
                                NPush(&nStack, x);//数字进栈
                                //printf("数字进栈A:%f\n",x);/////////////////////////////////
                                sTmpNum = '\0';//进栈后的临时数串清零
                        }
                }
                else{//运算符整合及运算
                        //运算符整合
                        cTmpDblChar = exp;
                        strcat(sTmpOpr, cTmpDblChar);
                        //printf("符号:%s\n", sTmpOpr);////////////////////////////////////////////////////////
                        //printf("yname==%d\n", IsOper(sTmpOpr));/////////////////////////////////////////////////////
                        if (iWhichOpr = IsOper(sTmpOpr)){
                                y = oper;
                                //printf("yname==%s\n",y.name);/////////////////////////////////////////////////////
                                sTmpOpr = '\0';
                                if (y.ctype != IsBracket){
                                        //////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                        while (OPeek(&oStack).level >= y.level&&oStack.top > 0 && OPeek(&oStack).level > 0){//当栈中符的等级大于当前等级时则取出符进行运算
                                                w = OPop(&oStack);//出栈一个运算符
                                                //printf("\t运算符出栈1:%s\n",w.name);/////////////////////////////////
                                                CALC_simple(w, &nStack);
                                                intFunParCount = 0;
                                        }
                                        OPush(&oStack, &y);//直到无法运算将当前符放入栈中
                                        //printf("运算符进栈1:%s\n",y.name);/////////////////////////////////
                                        //////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                }
                                else{
                                        if (y.number == 20){//如果是左括号则无条件进栈
                                                OPush(&oStack, &y);//进栈后等级为-1,以便遇到右括号出栈
                                                //printf("运算符进栈2:%s\n",y.name);/////////////////////////////////
                                        }
                                        else if (y.number == 21){//右括号计算
                                                while (OPeek(&oStack).level != -1){//遇到右括号则计算直到左括号
                                                        w = OPop(&oStack);//出栈一个运算符
                                                        //printf("\t运算符出栈2:%s\n", w.name);/////////////////////////////////
                                                        CALC_simple(w, &nStack);
                                                }
                                                OPop(&oStack);//直到遇到左括号将左括号出栈
                                        }
                                        else if (y.number == 22){
                                                intFunParCount++;
                                        }
                                }
                        }
                        else{
                                continue;
                        }
                }
        }
        while (OPeek(&oStack).level != 0){//表达式结束后对栈进行操作直到栈空
                if (OPeek(&oStack).level == -1){//如果有为用掉的左括号则报错退出程序
                        Error(SyntaxError);
                        return 0;
                }
                //printf("\t\t运算符1:%s\n",OPeek(&oStack).name);/////////////////////////////////
                w = OPop(&oStack);//取出两个数和一个符进行计算
                //printf("\t运算符出栈3:%s\n",w.name);/////////////////////////////////
                CALC_simple(w, &nStack);
                intFunParCount = 0;
        }
        Answ = NPop(&nStack);
        //constants.value = Answ;
        return Answ;
}
///////////////////////////////
//功能
//角度弧度梯度制转换
inline void ChangeScaleEnv(int x){
        if (x == 0)
                degScale = S_Rad;
        else if (x == 2)
                degScale = S_Deg;
        else
                degScale = S_Gra;
}
//Preprocesser Debugger
char *InputScanner(char *exp){
        srand((int)time(NULL));
        register int i = 0, j = 0, z = 0, h = 0;//循环计数器
        //初始化
        //InitOperTable();
        //InitConstTable();
        constants.value = rand();
        if (InitConstTable) constants.value = Answ;

        char sTmpOpr = { 0 };//用于[运算符整合]临时变量
        char cTmpDblChar = { 0, 0 };//临时存放单个字符
        register int iWhichOpr = 0;//记录运算符返回值
        //int iWhichCst = 0;//记录常数
        OTYPE y; bool bEnvIsTrue = false; CONSTANT c;
        int absCtrAll = 0;//记录"|"的总数

        char tStr = { '\0' }, ttStr = { '\0' }, ttStrB = { '\0' };
        for (i = 0; i <= strlen(exp); i++){
                if (exp == ' ')//跳过空格
                        continue;
                if (exp >= 'a'&&exp <= 'z'){
                        tStr = exp - 32;
                }
                else{
                        tStr = exp;
                }
                if (exp == '|')
                        absCtrAll++;
                j++;
        }
        tStr = '\0';
        strcpy(ttStr, tStr);
        //处理绝对值 将|-1|转换为ABS(-1)
        if (absCtrAll % 2 != 0){
                Error(SyntaxError);
                return "";
        }
        for (i = 0; i <= strlen(tStr); i++){
                if (tStr == '|'){
                        if (h < absCtrAll / 2){
                                z = 0;
                                strcpy(ttStr, Mid(tStr, 1, i));
                                strcpy(ttStrB, Mid(tStr, i + 2));
                                tStr = '\0';
                                strcat(tStr, ttStr);
                                strcat(tStr, "ABS(");
                                strcat(tStr, ttStrB);
                                //printf("\t%s\n", tStr);//////////////////
                                h++;
                        }
                        else
                                tStr = ')';
                }
        }
        /*
        for (i = 0; i <= strlen(tStr); i++)
        if (tStr == '|')
        tStr = ')';
        */
        //
        i = 0; j = 0; z = 0; h = 0;
        ttStr = '\0'; ttStrB = '\0';
        //将减法转换为加法 a-b == a+-b
        for (i = 0; i <= strlen(tStr); i++){
                if ((tStr != NULL) && (i >= 1) && ((tStr >= '0'&&tStr <= '9' || tStr == ')') && (tStr == '-') && ((tStr >= '0'&&tStr <= '9') || tStr == '.' || tStr == '('))){
                        z = 0;
                        ttStr = '+';
                        for (z = i; z <= strlen(tStr); z++)
                                ttStr = tStr;
                        ttStr = '\0';
                        for (z = 0; z <= strlen(ttStr); z++)
                                tStr = ttStr;
                        i++;
                }
        }
        //将+-()转换为+-1*()
        for (i = 0; i <= strlen(tStr); i++){
                if ((tStr != NULL) && (tStr == '-' && (tStr == '(' || (tStr >= 'a'&&tStr <= 'z' || tStr >= 'A'&&tStr <= 'Z')))){
                        z = 0;
                        for (z = 0; z < i; z++)
                                ttStr = tStr;
                        ttStr = '1';
                        ttStr[++z] = '*';
                        for (z = i + 2; tStr != NULL; z++)
                                ttStr = tStr;
                        strcpy(tStr, ttStr);
                        i += 2;
                }
        }
        //printf("1 hello!!\n");//////////////////////////////////////
        //将:2sin变成2*sin
        for (i = 0; i <= strlen(tStr); i++){
                if ((tStr >= '0'&&tStr <= '9') || tStr == '-' || tStr == '.'){//区分操作数和运算符
                        bEnvIsTrue = true;
                        sTmpOpr = '\0';///////////////////////////WARNING!!!
                }
                else{
                        cTmpDblChar = tStr;
                        strcat(sTmpOpr, cTmpDblChar);
                        if (iWhichOpr = IsOper(sTmpOpr)){
                                y = oper;
                                sTmpOpr = '\0';
                                if ((y.ctype == FrontCalOpr || y.ctype == Functio) && bEnvIsTrue){
                                        z = 0;
                                        ttStr = '*';
                                        for (z = i - strlen(y.name) + 1; z <= strlen(tStr); z++)
                                                ttStr = tStr;
                                        ttStr = '\0';
                                        for (z = 0; z <= strlen(ttStr); z++)
                                                tStr = ttStr;
                                        i++;
                                }
                                bEnvIsTrue = false;
                        }
                }
        }
        //printf("2 hello!!\n");//////////////////////////////////////

        //printf("3 hello!!\n");//////////////////////////////////////
        //将2pi转换成2*pi
        bEnvIsTrue = false; sTmpOpr = '\0';
        for (i = 0; i <= strlen(tStr); i++){
                if ((tStr >= '0'&&tStr <= '9') || tStr == '-' || tStr == '.'){//区分操作数和运算符
                        bEnvIsTrue = true;
                        sTmpOpr = '\0';
                }
                else{
                        //printf("hello\n");///////////////////////////
                        cTmpDblChar = tStr;
                        strcat(sTmpOpr, cTmpDblChar);
                        //printf("%s\n",sTmpOpr);////////////////////////////
                        if (iWhichOpr = IsConst(sTmpOpr)){
                                //printf("hello\n");///////////////////////////
                                c = constants;
                                sTmpOpr = '\0';
                                if (bEnvIsTrue){
                                        /*
                                        z = 0;
                                        ttStr = '*';
                                        for (z = i - strlen(c.name) + 1; z <= strlen(tStr); z++)
                                        ttStr = tStr;
                                        ttStr = '\0';
                                        for (z = 0; z <= strlen(ttStr); z++)
                                        tStr = ttStr;
                                        i++;
                                        */
                                        strcpy(ttStr, Mid(tStr, 1, i - strlen(c.name) + 1));
                                        //printf("A\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                        strcat(ttStr, "*");
                                        //printf("B\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                        //printf("BA\tttStr %s\n", Mid(tStr, i)); system("pause");////////////////////////////////////
                                        strcat(ttStr, Mid(tStr, i));
                                        //printf("C\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                        i = i - strlen(c.name) + 1;
                                        strcpy(tStr, ttStr);
                                }
                                bEnvIsTrue = false;
                        }
                }
        }
        //printf("\t\"%s\"\n", tStr);/////////////////////////////////////////////////////////
        //

        //printf("::::%s\n", tStr);/////////////////////////////////////////////////////i <= strlen(tStr)
        //将函数参数替换成数值
        sTmpOpr = '\0'; bEnvIsTrue = true;
        for (i = 0; i <= strlen(tStr); i++){
                if ((tStr >= '0'&&tStr <= '9') || tStr == '-' || tStr == '.'){//区分操作数和运算符
                        //bEnvIsTrue = true;
                        sTmpOpr = '\0';
                }
                else{
                        //printf("tstr %s\n", tStr);
                        //printf("i==%d\n", i);///////////////////////////////////////////////////////////////////////
                        //printf("\t%c\n",tStr);////////////////////////////////////////////
                        //if ((tStr >= 'A') && (tStr <= 'Z')){//区分操作数和运算符
                        //printf("1A,%d====%s\n", i, sTmpOpr);///////////////////////////////////////////
                        cTmpDblChar = tStr;
                        //if (cTmpDblChar >= '0' || cTmpDblChar <= '9')sTmpOpr = '\0';///////////////////////////////////////////
                        strcat(sTmpOpr, cTmpDblChar);
                        //printf("XX %s\n",sTmpOpr);///////////////////////////////////////////////////////////
                        //printf("IsPara %d\n", IsPara(sTmpOpr));////////////////////////////////////////////////
                        //printf("\t\tEnv %d\n", bEnvIsTrue);/////////////////////////////////////////////////////
                        //if (strcmp(sTmpOpr, "PI") == 0) printf("ok\n");
                        if (IsOper(sTmpOpr)){
                                sTmpOpr = '\0';
                                bEnvIsTrue = true;
                        }
                        else if ((iWhichOpr = IsConst(sTmpOpr)) && bEnvIsTrue){
                                //printf("sTmpOpr \'%s\'\n", sTmpOpr);//////////////////////////////////////////////////显示字符串
                                sTmpOpr = '\0';
                                bEnvIsTrue = false;
                                c = constants;
                                //printf("替换hello\n");
                                printf("替换 %s\n",c.name);
                                strcpy(ttStr, Mid(tStr, 1, i - strlen(c.name) + 1));
                                //printf("A\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                j = sprintf(ttStrB, "%.16f", c.value);
                                strcat(ttStr, ttStrB);
                                //printf("B\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                strcat(ttStr, Mid(tStr, i + strlen(c.name)));
                                //printf("C\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                i = i - strlen(c.name) + j;
                                strcpy(tStr, ttStr);

                                //printf("tStr %s\n", tStr);
                                //printf("i %d\n", i + strlen(c.name)+j);
                                //i += (j + (i - (strlen(c.name) + 1)));
                                //i += strlen(c.name) + j;
                        }
                }
        }
        //将函数参数替换成数值B
        sTmpOpr = '\0'; bEnvIsTrue = true;
        for (i = 0; i <= strlen(tStr); i++){
                if ((tStr >= '0'&&tStr <= '9') || tStr == '-' || tStr == '.'){//区分操作数和运算符
                        sTmpOpr = '\0';
                }
                else{
                        cTmpDblChar = tStr;
                        strcat(sTmpOpr, cTmpDblChar);

                        if (IsOper(sTmpOpr)){
                                sTmpOpr = '\0';
                                bEnvIsTrue = true;
                        }
                        else if ((iWhichOpr = IsPara(sTmpOpr)) && bEnvIsTrue){
                                sTmpOpr = '\0';
                                bEnvIsTrue = false;
                                c = functpara;

                                strcpy(ttStr, Mid(tStr, 1, i - strlen(c.name) + 1));
                                //printf("A\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                j = sprintf(ttStrB, "%.16f", c.value);
                                strcat(ttStr, ttStrB);
                                //printf("B\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                strcat(ttStr, Mid(tStr, i + strlen(c.name)));
                                //printf("C\tttStr %s\n", ttStr); system("pause");////////////////////////////////////
                                i = i - strlen(c.name) + j;
                                strcpy(tStr, ttStr);
                        }
                }
        }
        return tStr;
}
///////////////////////////////
void Debug_Print_Para(void){
        int i = 0;
        for (i = 0; i <= CST_CTR + iUserCnt; i++){
                //printf("参数:\"%s\"\n", para);////////////////////////////////////////
                //printf("参数:\"%s\"\n", para);////////////////////////////////////////
                //printf("\t%s %f\n", functpara.name, functpara.value);
                printf("\t%s\n", constants.name);
                //iParCtr++;
        }
}
//主函数
void PrintTitle(void){
        printf("Calculation Engine Kernel Alpha\n");
        printf("Copyright (C) 2014 Ctechnology Corporation & TZR Lab.\n");
        printf("All Rights Resaved.\n");
}
int main(){
        //////freopen("C:\\Users\\Cosh Cage\\Desktop\\t.txt","r",stdin);
        //////char* a="16.714+56";
        InitOperTable();
        InitConstTable();
        InitParaTable();

        char a = { 0 };
        //Debug_Print_Para();
        AddConstant("ZZZ", 3.0);
        //Debug_Print_Para();
        char par = { '\0' };
        strcat(par, "AA");
        strcat(par, "BB");
        strcat(par, "CC");

        AddFunc("SSUM", par, "AA+BB+CC");

        //printf("??%d\n", IsConst("ZZ"));//////////////////////////////////
        //printf("!! %s\n", constants.name);/////////////////////////////////////////////
        //ClearAllFunc();
        //printf("Calculation Engine Kernel Alpha\n");
        //printf("Copyright (C) 2014 Ctechnology Corporation & TZR Lab.\n");
        //printf("All Rights Resaved.\n");
        /*
        do{
        printf("?"); gets(a);
        //////////std::cin >> a;
        strcpy(a, InputScanner(a));
        printf("%s\n", a);
        printf("ANS=%f\n", CALC_main(a));
        } while (a != NULL);
        */
        //15+6-8/2*5\n3+8*6-13\n9-2*3*3+8-6+5
        //printf("2*(1+2)\n");
        //printf("9-2-6\n");
        //8+2-(7-4)*2//3+2*(5-2)-4//3+4-(6+2)*2
        /////////////////////InitConstTable();
        //////////////////////printf("%d\n", IsConst("PIP\0"));//////////////////

        //strcpy(a, InputScanner("zz+1"));
        //printf("\"%s\"\n", a);
        //printf("ANS=%f\n", CALC_main(a));

        //Debug_Print_Para();
        //printf("IsPara %d\n", IsPara("AA"));////////////////////////////////////////////////
        //printf("\n");
        //printf("End:%s\n", InputScanner("AA+BB+CC"));

        //system("Pause");

        int i = 0; double localAns;
        char *fn; char str;
        PrintTitle();
        do{
                printf("?"); gets(a);
                if (strcmp(strupr(a), "ADDFUN") == 0){
                        do{
                                printf("\tFunction Name?"); gets(a);
                                fn = a;
                                for (i = 0; i < 10; i++){
                                        printf("\tFunction Parament?"); gets(a);
                                        if (a == '\0'){
                                                break;
                                        }
                                        else{
                                                strcat(par, a);
                                        }
                                }
                                printf("\tFunction Expression?"); gets(a);
                                AddFunc(fn, par, a); printf("\tAdded OK!\n");
                                printf("\tFunction Name?"); gets(a);
                        } while (a != NULL);
                        printf("?"); gets(a);
                }
                else if (strcmp(strupr(a), "ADDVAR") == 0){
                        do{
                                printf("\tVar Name?"); gets(a);
                                fn = a;
                                printf("\tVar Value?"); gets(a);
                                AddConstant(fn, atof(a)); printf("\tAdded OK!\n");
                                printf("\tVar Name?"); gets(a);
                        } while (a != NULL);
                        printf("?"); gets(a);
                }
                else if (strcmp(strupr(a), "DELALLFUN") == 0){
                        ClearAllFunc(); printf("Done!\n");
                        printf("?"); gets(a);
                }
                else if (strcmp(strupr(a), "DELALLVAR") == 0){
                        ClearAllConst(); printf("Done!\n");
                        printf("?"); gets(a);
                }
                else if (strcmp(strupr(a), "SCALE") == 0){
                        do{
                                printf("\t\t0:Rad\n\t\t2:Deg\n\t\tAny:Gra\n\tScale?"); gets(a);
                                ChangeScaleEnv(atoi(a));
                        } while (a != NULL);
                        printf("?"); gets(a);
                }
                else if (strcmp(strupr(a), "CLS") == 0){
                        system("cls");
                        PrintTitle();
                }
                else{
                        //////////std::cin >> a;
                        strcpy(a, InputScanner(a));
                        localAns = CALC_main(a);
                        //printf("%s\n", a);
                        str = '\0';
                        if (ERR_NUM != NoError){
                                for (i = 1; i <= ix - 2; i++){
                                        strcat(str, " ");
                                }
                                strcat(str, "^\n");
                                if (ERR_NUM == MathError){
                                        strcat(str, "MathError!");
                                }
                                else if (ERR_NUM == StackError){
                                        strcat(str, "StackError!");
                                }
                                else if (ERR_NUM == SyntaxError){
                                        strcat(str, "SyntaxError!");
                                }
                                else if (ERR_NUM == UnknownError){
                                        strcat(str, "UnknownError!");
                                }
                                printf("%s\n", a);
                                printf("%s\n", str);
                        }
                        printf("ANS=%f\n", localAns);
                }
        } while (a != NULL);

        return 0;
}
//////////END///////////////////

cyycoish 发表于 2014-11-18 22:51:35

天哪,上边怎么回事?我的代码呢!?

cyycoish 发表于 2014-11-18 22:55:20

0xAA55 发表于 2014-12-30 17:16:12

哈哈 这个好
页: [1]
查看完整版本: 数学表达式解析器-(一)初期体验