⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse11.30.cpp

📁 Linux下编写的一个表达式解析器可以计算= - * / 与或非运算 经过测试并带有测试用例!供大家参考
💻 CPP
字号:
#include <math.h>#include <iostream>#include <stdio.h>#include <stdlib.h>#include <limits>#include "Parse.h"using namespace std;Parse::Parse (){    m_strErrorInfo = new char[50];}Parse::~Parse(){        delete [] m_strErrorInfo;        m_strErrorInfo = NULL;  }const char *Parse::FindLastOp(const char *str)		//find lastop{	int		len,i;    int   	n = 0;    char*   str_op = "+-&|*/";    char*	str_op_L = "+-&|";    char*	str_op_B = "*/";	char	str_left[5] = "(";	char	str_right[5] = ")";	char	str_begin[] = "-~";		int		len_i = 0, len_j = 0, k = 0;	char	str_les[256] = {0};	char	*ptr, *right_str;	int		len_op = strlen(str_op);        n = 0;	len = strlen(str);	len_i = strcspn(str, str_left);	len_j = strcspn(str, str_right);	int len_R_L,len_L_L;	char* right_P;			if(len_i != len && !strchr(str_begin, str[0]))		{		//	right_P = strrchr(str, str_right[0]);		//	len_R_L = right_P-str;			for(int nn = len-1; nn > 0; nn--)			{				if(strchr(str_right, str[nn]))					n++;				if(strchr(str_left, str[nn]))					n--;				if(strchr(str_op_L, str[nn]) && n == 0)					return str + nn;			}						n = 0;			for(int nn = len-1; nn > 0; nn--)			{									if(strchr(str_right, str[nn]))					n++;				if(strchr(str_left, str[nn]))					n--;				if(strchr(str_op_B, str[nn]) && n == 0)					return str + nn;			}			return NULL;		}		else		{    		for(i = 0; i < len_op; i++)   			{				if(strchr(str_begin, str[0]))   				{   					strcpy(str_les, str + 1);		   					int lenles = strlen(str_les);   					if(lenles == strcspn(str_les, str_op) || strchr(str_left, str_les[0]))        				return NULL;        			else        				return str + strcspn(str_les, str_op) + 1;     			}     					ptr = strrchr(str, str_op[i]);		//從右找運算符				if(ptr)					k = ptr-str;				if((k < len_i || k > len_j) && n == 0 && k != 0)					return str + k;  			}  		}    return NULL;}double Parse::CalculateExp(const char *str){    float 	result;    char * 	p = NULL;    char  	str_op_left[15] = "-~";    char	str_left_p[] = "(";	char	str_right_p[] = ")";        if (FindLastOp(str) == NULL && (isxdigit(str[0]) || strchr(str_op_left, str[0])))	    {           if(NULL != (p = (p = strstr(str, "0x")) ? p: strstr(str, "0X")))            return  StrHexToInt((LPSTR)(LPCTSTR)str); 		if(str[0] == '~')				//只有int和short類型的數據可以取反		{			int ii = atoi(&str[1]);			return ~ii;		}              return atof(str);    }    else     {        const char  *last_op = FindLastOp(str);         const char  *p = str;        int         n = 0;		char 		left_str[256] = {0};		char 		right_str[256] = {0};		        if (last_op != NULL)        {        	if(p == last_op && *last_op == '~')            {            	strcpy(left_str, "-1");            	strcpy(right_str, last_op + 1);            	last_op = "-";            	return  result = CalculateNum(CalculateExp(left_str), CalculateExp(right_str), *last_op);            }            while (p != last_op)             {                if (strchr(str_left_p, *p))                     n++;                else if (strchr(str_right_p, *p))                    n--;                p++;            }        }        if (n != 0 || last_op == NULL)        {               char tmp[256] = {0};            strncpy(tmp, str + 1, strlen(str) - 2);            return CalculateExp(tmp);        }		else		{			strncpy(left_str, str, last_op - str);			strcpy(right_str, last_op + 1);        }        return  result = CalculateNum(CalculateExp(left_str), CalculateExp(right_str), *last_op);    }}double Parse::CalculateNum(float num1, float num2, char op){    switch (op)     {        case '+':            return num1 + num2;        case '-':            return num1 - num2;        case '*':            return num1 * num2;        case '/':            return num1 / num2;            case '^':            return pow(num1, num2);                    case '&':            return (int)num1 & (int)num2;                    case '|':            return (int)num1 | (int)num2;        default:        return 0;    }}double Parse::StrHexToInt(char* strSource) {       double	nTemp = 0;    int   	nDecNum;        for(int i = 2;  i<(int)::strlen(strSource);  i++)       //此处i从2起    {        switch(strSource[i])        {            case 'a':            case 'A':   nDecNum = 10;   break;            case 'b':            case 'B':   nDecNum = 11;   break;            case 'c':            case 'C':   nDecNum = 12;   break;            case 'd':            case 'D':   nDecNum = 13;   break;            case 'e':            case 'E':   nDecNum = 14;   break;            case 'f':            case 'F':   nDecNum = 15;   break;            case '0':            case '1':            case '2':            case '3':            case '4':            case '5':            case '6':            case '7':            case '8':            case '9':    nDecNum = strSource[i] - '0';     break;            default:     return 0;                  }        nTemp += nDecNum * (double)::pow(16,::strlen(strSource)-i -1);    }    return nTemp;}bool Parse::DetectionStr(const char *str,int Type,void *p) 	//interface statement{       int  len1,lenth;    int  i,j;        if (str!=NULL)    {        strcpy(m_str,str);    }   	lenth = strlen(m_str);        if(m_str[0] != '\0')    {        m_nLen = strspn(m_str,"0123456789abcdefxABCDEFX()+-*/. ~&|");    	//检查出不在这些字符内的异常字符的位置        if(m_nLen < lenth)        {            m_nNO = 1;            return false;        }        for(i = j = 0; j < lenth; i++,j ++)        {            while(m_str[j] == ' ')            {                j++;            }            m_str1[i] = m_str[j];                           //去除空格        }        m_str1[i] = '\0';        if(CheckStr())        {            float result = CalculateExp(m_str1);            if(result !=INFINITY)            {                switch( Type )                {                    case _CHR_TYPE_DOUBLE_:                        *(double*)p = (double)result;                        return true;                    case _CHR_TYPE_FLOAT_:                        *(float*)p = result;                        return true;                                            case _CHR_TYPE_INT_:                        if(INT_MIN < result && result < INT_MAX)                        {                            *(int*)p = (int) result;                            return true;                        }                    case _CHR_TYPE_SHORT_:                        if(SHRT_MIN < result && result < SHRT_MAX)                        {                            *(short*)p = (short)result;                            return true;                        }                    default:                        break;                }                m_nNO = 5;            }                                                 else                m_nNO = 4;        }        else            m_nNO = 3;    }    else        m_nNO = 2;    if(m_nNO != 0)        return false;    else        return true;}int Parse::CheckStr(){    bool  	bisdigit ;    int   	n = 0;    int		len = strlen(m_str1);    char*	str_One_op = "~(-";    char*   str_End = "+-*/&|~(";    if (!isxdigit(m_str1[0]) && !strchr(str_One_op, m_str1[0]))        return 0;    if(strchr(str_End, m_str1[len-1]))    	return 0;     for(int i = 0 ; i < len; i++)    {    	char *p = NULL;    	p = strchr(str_One_op, m_str1[i+1]);        bisdigit= isxdigit(m_str1[i+1]);        switch(m_str1[i])        {            case '(':                if(bisdigit || strchr(str_One_op, m_str1[i+1]))                 {                     n++;                     break;                 }                 else                     return 0;            case ')':                n--;                if(n >= 0 && !bisdigit)                     break;                else                     return 0;            case '-':            	if(m_str1[i+1] == '-')            		return 0;            case '+':            case '*':            	if(bisdigit || p != NULL)                    break;                else                     return 0 ;            case '/':                if(bisdigit && (m_str1[i+1] != '0' || m_str1[i+2] == 'x' || m_str1[i+2] == 'X') || p != NULL)                    break;                else                     return 0 ;                            case 'x':            case 'X':                if(bisdigit && m_str1[i-1] == '0' && m_str1[i-1] != bisdigit)                    break;                else                    return 0;                               case '.':                  if(bisdigit && isxdigit(m_str1[i-1]))                    break;                else                    return 0;            case '~':                if(bisdigit || m_str1[i+1] == '(')                    break;                else                    return 0;            case '&':                if(bisdigit || m_str1[i+1] == '(')                    break;                else                    return 0;            case '|':                if(bisdigit || m_str1[i+1] == '(')                    break;                else                    return 0;            default:                break;        }    }    if(n!=0)        return 0;    else        return 1;}char* Parse::GetErrorCode(){    char    cStr[20] = "error!";    char  	cStrChar[42] = "Please input the correct characte!";    char    cSoverflow[20] = "result overflow!";    switch( m_nNO )    {        case 1:            m_nNO = 0;            sprintf(m_strErrorInfo,"%s %c %d\n",cStr, m_str[m_nLen], m_nLen + 1);             return m_strErrorInfo;        case 2:        case 3:            m_nNO = 0;            sprintf(m_strErrorInfo,"%s\n", cStrChar);            return m_strErrorInfo;        case 4:        case 5:            m_nNO = 0;            sprintf(m_strErrorInfo,"%s\n", cSoverflow);            return m_strErrorInfo;        default:                 return NULL;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -