现在的位置: 首页 > 综合 > 正文

反向工程之四则混合运算优先级判断–加括号问题

2017年12月08日 ⁄ 综合 ⁄ 共 8402字 ⁄ 字号 评论关闭

我们在栈内已经取得两个数或者表达式,已经以字符串的形式存放了:

asStackArray[iStackPoint] :         1+2+3+4

asStackArray[iStackPoint -1] :     1-2-3-4*5

 

如果将要进行的操作是除法。那优先级比他低的是:1. 乘法,2.加法,3.减法 4.自己(我的程序代码有这个bug,需要连自己也检测,但是仅仅限与上栈操作。也就是 - -, / /碰到一起时,后面要加括号的。)

我们就在上栈和下栈寻找这三个符号(括号内不寻找,比如:"(1+2+3)/4 ",在下栈可以直接除,上栈必须加括号 )

是不是在括号内的话,用一个计数器来标示。

 

另外,同级的操作符,+ ,- 如果是+,他对任何表达式都不加括号,因为它是数值类运算的最低级别。而减法对下栈数没影响,但是对上栈操作数有影响,同样,除号也只对同级的上栈操作数有影响。所以只需要判断一个栈。通常,因为除对加减都有管制,所以我们一般只对最低级的减号做单栈判断。等,不等,大于等于,小于等于,大于,小于等返回逻辑值,它的表达式如(a and b or c)=true,其级别比and,not,or都要高,所以要加括号。而 a +b = c+d,就不需要。

 

最后,bool类型的变量在赋值时,如果写: boolean lbn = 1=2 and 2=3;这样的话看起来比较费解,所以对除单值(true,false)以外的逻辑赋值,我们在右表达式都加上括号,成:boolean lbn = (1=2 and 2=3); 这样看起来舒服明白一点。

 

经过这样的处理后,表达式的括号就比较合理了。等下我在后面补一个效果图。

//----------------------------------------------------------------------------------

ll_aaa = ((1 + 2 + 3 - 6) * 2) ^ 2 / 3 ^ 3 - (20 - 30 + 30)
ll_aaa = 1 + 2 + 3 + 4 - 9 - (20 - 30 + 30)
ll_aaa = (-(10 - (-100))) * 100
ll_aaa = (10 - (-100)) * 100
ll_aaa = 100 - (-100)
lb = ( not (1 = 20 or 2 = 3) or 2 = 3 and (1 = 20 or 2 = 3))

------------------------------------------------------------------------------------//

 

bool __fastcall TForm1::PriorityCheck(const unsigned char asPcode,astring &asExpression)
{
    //四则混合运算优先级判断
    const astring asBracketLEFT = "(",asBracketRIGHT=")";
    char HasBracketcount = 0;
    char *pExpression,*pTemp;
    char ach,ach2,ach3;
   
    pExpression = asExpression.c_str();
    pTemp = pExpression;

    //取数时检测,如果是带符号就加上括号
    switch (asPcode)
    {
        case 'g':                  //get 数值时用,凡是带符号的数,都加上括号,以免影响阅读,比如 a - -b,这样写可以,但不好看。
            if (*pTemp == '-'){
                asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                return true;
            }
            return false;
            break;

   
        case '-':
            for(int i= asExpression.Length();i>=0;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }
                if (HasBracketcount !=0) continue;

                //减号遇到减号会变换符号,所以要在后面一个括起来,也就是说前操作数不用检查。
                if (ach  == '-' ){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;

                    return true;
                }
            }
            break;

   
    ///////////////////////////
        case '*':      //乘法
            for(int i= asExpression.Length();i>=0;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                     HasBracketcount ++;
                     continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;
           
                if (ach  == '+' ||
                    ach == '-' ){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }
            break;

   
    //////////////////////////
        case '/':          //除法
            for(int i= asExpression.Length();i>=0;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;
           
                if (ach  == '+' ||               //这里需要加上除号。。!!
                    ach == '-' ||
                    ach == '*'){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }
            break;

        ///////////////////////
        case '^':             //N次方
            for(int i= asExpression.Length();i>=0;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;
           
                if (ach  == '+' ||
                    ach == '-' ||
                    ach == '*' ||
                    ach == '/' ){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }
            break;

        //////////////////////////////////
        case '>':                // 大于,小于,等于 和 不等于。
            for(int i= asExpression.Length();i>=3;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;

                if ((ach  == 'n' && *(pTemp)== 'o' && *(pTemp + 1)== 't' && *(pTemp + 2)== '/x20' ) ||  //++操作后自动增加了1
                    (ach  == 'a' && *(pTemp)== 'n' && *(pTemp + 1)== 'd' && *(pTemp + 2)== '/x20') ||
                    (ach  == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '/x20')){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }

            break;

        ///////////////////////////////////////////
        case  '!':                 //logic Not
            for(int i= asExpression.Length();i>=3;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;
           
                if ((ach  == 'a' && *(pTemp)== 'n' && *(pTemp +1)== 'd' && *(pTemp + 2)== '/x20') ||   //++操作后自动增加了1
                    (ach  == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '/x20')){

                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }

            break;

        ///////////////////////////////////////////
        case  '&':                           //logic and
            for(int i= asExpression.Length();i>=3;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;
           
                if (ach  == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '/x20'){          //++操作后自动增加了1
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }
            break;

 

        ///////////////////////////////////
        case  '@':                       //数值的负号操作。大于一切。只比括号的级别小。如  -(li_1+li_2) ,这个符号如果跟数字接壤,比较混淆。       
            for(int i= asExpression.Length();i>=0;i--){
                ach = *(pTemp ++);
                if (ach == '/"' || ach == '/'') return false;  //字符串内不判断

                //括号已经存在的检测。
                if (ach == '('){
                    HasBracketcount ++;
                    continue;
                }
                if (ach == ')'){
                    HasBracketcount -- ;
                }

                if (HasBracketcount !=0) continue;
           
                if (ach  == '+' ||
                    ach == '-' ||
                    ach == '*' ||
                    ach == '/' ||
                    ach  == '^'){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
              
                    return true;
                }
            }
            break;

        //////////对逻辑表达式赋值时,加上括号,以免误解。/////////////
        case  'T':             //lbn= a and b and c or d时,把后面表达式括起来,只用于对左值赋值时。
            for(int i= asExpression.Length();i>=3;i--){
                ach = *(pTemp ++);
           
                if ((ach  == 'n' && *(pTemp)== 'o' && *(pTemp + 1)== 't' && *(pTemp + 2)== '/x20' ) ||  //++操作后自动增加了1
                    (ach  == 'a' && *(pTemp)== 'n' && *(pTemp + 1)== 'd' && *(pTemp + 2)== '/x20') ||
                    (ach  == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '/x20')){
                    asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
                    return true;
                }
            }
            break;
    }
   
    return false;
}

抱歉!评论已关闭.