zoukankan      html  css  js  c++  java
  • 表达式的解析

      1 #pragma once
      2 #include <string>
      3 #include <functional>
      4 #include <type_traits>
      5 #include <stack>
      6 struct OpratorObject
      7 {
      8     OpratorObject(int a)
      9     {
     10 
     11     }
     12     OpratorObject(double a)
     13     {
     14 
     15     }
     16     OpratorObject()
     17     {
     18 
     19     }
     20 };
     21 enum ExpType {
     22     ADD,    //
     23     SUB,    //
     24     MULT,        //
     25     DIV,        //
     26     VALUE,        //直接取值
     27     FUNC
     28 };
     29 struct ExpNode
     30 {
     31     //每一个表达式都有值
     32     virtual    std::string GetValue() = 0;
     33 };
     34 struct ExpNodeString : public ExpNode
     35 {
     36 public:
     37     ExpType t;
     38     ExpNodeString* left;
     39     ExpNodeString* right;
     40     std::string val;
     41     std::string GetValue()
     42     {
     43         if (t == VALUE)
     44         {
     45             return val;
     46         }
     47         std::string lval = left->t == VALUE ? left->val : left->GetValue();
     48         std::string rval = right->t == VALUE ? right->val : right->GetValue();
     49         if (t == ADD)
     50         {
     51             return std::to_string(std::stof(lval) + std::stof(rval));
     52         }
     53         if (t == SUB)
     54         {
     55             return std::to_string(std::stof(lval) - std::stof(rval));
     56         }
     57         if (t == MULT)
     58         {
     59             return std::to_string(std::stof(lval) * std::stof(rval));
     60         }
     61         if (t == DIV)
     62         {
     63             return std::to_string(std::stof(lval) / std::stof(rval));
     64         }
     65 
     66         return "";
     67     }
     68 };
     69 struct ExpNodeStringValFunc : public ExpNodeString
     70 {
     71 public:
     72     std::string result;    //结果
     73     std::function<std::string(void)> func;
     74     std::string exp;
     75 };
     76 
     77 std::string right;    //
     78 struct Exp
     79 {
     80     //我目前先声明了一个node然后先放入左操作数,遇到(才创建新的子node
     81     //这里应该是遇到操作符 也要创建新的node
     82 
     83 
     84     static bool Parse(std::string s, ExpNodeString*& root)
     85     {
     86         root = new ExpNodeString();
     87         ExpNodeString* pCur = root;
     88         std::stack<ExpNodeString*> pCurStack;
     89         pCurStack.push(root);
     90         bool bLeft = true;    //先从左操作数开始
     91         for (int i = 0; i < s.size(); i++)
     92         {
     93             pCur = pCurStack.top();
     94             char ch = s[i];
     95             if (ch != ' ')
     96             {
     97                 if (isdigit(ch))
     98                 {
     99                     if (bLeft)
    100                     {
    101                         if (pCur->left == nullptr)
    102                         {
    103                             pCur->left = new ExpNodeString();
    104                         }
    105                         pCur->left->t = VALUE;
    106                         pCur->left->val.push_back(ch);
    107                     }
    108                     else {
    109                         if (pCur->right == nullptr)
    110                         {
    111                             pCur->right = new ExpNodeString();
    112                         }
    113                         pCur->right->t = VALUE;
    114                         pCur->right->val.push_back(ch);
    115                     }
    116                 }
    117                 else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
    118                 {
    119                     if (bLeft)
    120                     {
    121                         bLeft = false;
    122                     }
    123                     if (pCur->left != nullptr && pCur->right != nullptr)
    124                     {
    125                         ExpNodeString* pTemp = new ExpNodeString();
    126                         //pCur->right = new ExpNodeString();
    127                         pTemp->left = pCur;
    128                         pCurStack.pop();
    129                         pCurStack.push(pTemp);
    130                         pCur = pCurStack.top();
    131                     }
    132                     //左子节点如果为空就不需要创建新的node了实际情况:(5+2)/3
    133                     //if (pCur->left != nullptr)
    134                     //{
    135                     //    ExpNodeString* pTemp = new ExpNodeString();
    136                     //    pTemp->left = pCur;
    137                     //    pCurStack.pop();
    138                     //    pCurStack.push(pTemp);
    139                     //    //pCurStack.push(pTemp->left);
    140                     //    if (pCur == root)
    141                     //    {
    142                     //        root = pTemp;
    143                     //    }
    144                     //    pCur = pTemp;
    145                     //    pCur = pCurStack.top();
    146                     //}
    147                     //bLeft = false;
    148 
    149                     if (ch == '+')
    150                     {
    151                         pCur->t = ADD;
    152                     }
    153                     else    if (ch == '-')
    154                     {
    155                         pCur->t = SUB;
    156                     }
    157                     else    if (ch == '*')
    158                     {
    159                         pCur->t = MULT;
    160                     }
    161                     else    if (ch == '/')
    162                     {
    163                         pCur->t = DIV;
    164                     }
    165                 }
    166                 else if (ch == '(')
    167                 {
    168                     //if (root == pCur) continue;
    169                     if (bLeft)
    170                     {
    171                         pCur->left = new ExpNodeString();
    172                         pCurStack.push(pCur->left);
    173                         pCur = pCur->left;
    174                     }
    175                     else
    176                     {
    177                         pCur->right = new ExpNodeString();
    178                         pCurStack.push(pCur->right);
    179                     }
    180                     bLeft = true;
    181                 }
    182                 else if (ch == ')')
    183                 {
    184                     pCur = pCurStack.top();
    185                     //这里要一直弹出
    186                     while (pCur->left != nullptr && pCur->right != nullptr)
    187                     {
    188                         pCurStack.pop();
    189                         if (pCurStack.size() == 0)
    190                         {
    191                             ExpNodeString* pTemp = new ExpNodeString();
    192                             pTemp->left = pCur;
    193                             pCurStack.push(pTemp);
    194                             root = pTemp;
    195                         }
    196                         pCur = pCurStack.top();
    197                     }
    198                     pCur = pCurStack.top();
    199                     //}
    200 
    201                     //if (root == pCur)
    202                     //{
    203                     //    //小括号开头的
    204                     //    ExpNodeString* pTemp = new ExpNodeString();
    205                     //    pTemp->left = pCur;
    206                     //    pCurStack.pop();
    207                     //    pCurStack.push(pTemp);
    208 
    209                     //    //pCur = pCur->left;
    210                     //    root = pTemp;
    211                     //}
    212                     bLeft = !bLeft;
    213                 }
    214             }
    215         }
    216         if (pCurStack.size() == 0 || pCurStack.size() == 1)
    217         {
    218             if (pCurStack.size() == 1)
    219             {
    220                 root = pCurStack.top();
    221                 if (root->t != VALUE && root->left != nullptr && root->right != nullptr)
    222                 {
    223 
    224                 }
    225                 else {
    226                     root = root->left;
    227                 }
    228             }
    229             return true;
    230         }
    231         return false;
    232     }
    233     static bool Parse2(std::string s, ExpNodeString*& root)
    234     {
    235         //这里的思路是先组装一个left操作数,然后遇到operator然后在组装一个父节点
    236         //中间遇到小括号出问题了
    237         root = new ExpNodeString();
    238         ExpNodeString* pCur = root;
    239         std::stack<ExpNodeString*> pCurStack;
    240         pCurStack.push(root);
    241         bool bLeft = true;    //先从左操作数开始
    242         for (int i = 0; i < s.size(); i++)
    243         {
    244             pCur = pCurStack.top();
    245             char ch = s[i];
    246             if (ch != ' ')
    247             {
    248                 if (isdigit(ch))
    249                 {
    250                     if (pCur->left == nullptr && pCur->right == nullptr)
    251                     {
    252                         pCur->t = VALUE;
    253                         pCur->val.push_back(ch);
    254                     }
    255                     else
    256                         if (bLeft == true)
    257                         {
    258                             pCur->left->t = VALUE;
    259                             pCur->left->val.push_back(ch);
    260                         }
    261                         else
    262                         {
    263                             pCur->right->t = VALUE;
    264                             pCur->right->val.push_back(ch);
    265                         }
    266                     /*if (pCur->left == nullptr)
    267                     {
    268                         pCur->left = new ExpNodeString();
    269                     }
    270 
    271                     /*}
    272                     else {
    273                         if (pCur->right == nullptr)
    274                         {
    275                             pCur->right = new ExpNodeString();
    276                         }
    277                         pCur->right->t = VALUE;
    278                         pCur->right->val.push_back(ch);
    279                     }*/
    280                 }
    281                 else if (ch == '+' || ch == '-' || ch == '*' || ch == '/')
    282                 {
    283 
    284                     //if (bLeft)
    285                     //{
    286                     //    bLeft = false;
    287                     //}
    288                     //else {
    289                     //    //左子节点如果为空就不需要创建新的node了实际情况:(5+2)/3
    290                     //    if (pCur->left != nullptr)
    291                     //    {
    292 
    293                     ExpNodeString* pTemp = new ExpNodeString();
    294                     ExpNodeString* pTempRight = new ExpNodeString();
    295                     /*    if (root == pCur)
    296                         {
    297                             pTemp->left = pCur;
    298                             pCurStack.pop();
    299                             pCurStack.push(pTemp);
    300                             pCurStack.push(pTemp->right);
    301                         }
    302                         else {*/
    303                     pCurStack.pop();
    304                     if (pCurStack.size() == 0)
    305                     {
    306                         pTemp->left = pCur;
    307                         root = pTemp;
    308                     }
    309                     else
    310                         pTemp->left = pCurStack.top();
    311                     pTemp->right = pTempRight;
    312                     pCurStack.push(pTemp);
    313                     bLeft = false;
    314                     //pCurStack.push(pTemp->left);
    315                 /*    if (pCur == root)
    316                     {*/
    317 
    318                     //}
    319                     pCur = pTemp;
    320                     //    }
    321                     //    bLeft = false;
    322                     if (ch == '+')
    323                     {
    324                         pCur->t = ADD;
    325                     }
    326                     else    if (ch == '-')
    327                     {
    328                         pCur->t = SUB;
    329                     }
    330                     else    if (ch == '*')
    331                     {
    332                         pCur->t = MULT;
    333                     }
    334                     else    if (ch == '/')
    335                     {
    336                         pCur->t = DIV;
    337                     }
    338                 }
    339                 if (ch == '(')
    340                 {
    341                     if (!bLeft)
    342                     {
    343                         //if (root != pCur)
    344                         {
    345                             //pCur->right = new ExpNodeString();
    346                             pCurStack.push(pCur->right);
    347                             pCur = pCur->right;
    348                             /*pCur->right = new ExpNodeString();
    349                             pCur->left = new ExpNodeString();*/
    350                             bLeft = true;
    351                         }
    352                     }
    353                 }
    354                 if (ch == ')')
    355                 {
    356                     pCurStack.pop();
    357                     //同时意味着这个exp结束
    358                 }
    359             }
    360         }
    361         if (pCurStack.size() == 0 || pCurStack.size() == 1)
    362         {
    363             return true;
    364         }
    365         return false;
    366     }
    367     static bool Parse3(std::string s, ExpNodeString* pRoot)
    368     {
    369         // value operator
    370         // func
    371         // val
    372         //
    373     }
    374 
    375 };

    以上是自己的思路,但是作用有限,有括号这一块,优先级不能有限判定,其次只支持最基本的+ - * /。

    其中linq 有用到类似的思想。 所以这里对其做了简单的实现,有现成的开源第三方库:Muparser.使用c++实现的,更完美的异常捕获,以及更强大的表达式解析。

  • 相关阅读:
    笨办法学习python之hashmap
    python实现三级菜单源代码
    ql的python学习之路-day3
    ql的python学习之路-day2
    Spring的数据库开发
    Spring学习之Aspectj开发实现AOP
    spring学习之依赖注入DI与控制反转IOC
    spring学习之第一个spring程序
    spring学习之spring入门
    Java线程(一)——创建线程的两种方法
  • 原文地址:https://www.cnblogs.com/yang131/p/13857703.html
Copyright © 2011-2022 走看看