C++11解释器模式展示

2021-07-12  本文已影响0人  FredricZhu

题目,


image.png

本例实现一个简单的+,-法解释器,不考虑括号的情况,也就是不考虑优先级。
需要支持嵌入变量的情况。
如果变量是单字母,并且在预定义集合中,则从集合中找出变量值,参与计算。
如果变量是双字母,出错,返回0。
如果集合中没有变量,也返回0。
需要支持多位数字的情况。
字符串转整型可以使用std::ostringstream和std::istringstream类实现。
代码如下,

#include <map>
#include <sstream>
#include <iostream>

using namespace std;

struct Cal {
    enum Op {Add, Sub} op;
    bool caled {false};
    int left_val{-1};
    int right_val{-1};
    int result = 0;
    Cal() {};
    Cal(int left, int right, Cal::Op op_): left_val{left}, right_val{right}, op{op_} {}
    
    int eval() {
        int result {0};
        switch(op) {
            case Cal::Op::Add:
                cout << "left_val: " << left_val << " ";
                cout << "right_val: " << right_val << " ";
                cout << "old result: " << result << endl;

                result = left_val + right_val;
                cout << "new result: " << result << endl;
                break;
            case Cal::Op::Sub:
                cout << "left_val: " << left_val << " ";
                cout << "right_val: " << right_val << " ";
                cout << "old result: " << result << endl;
                result = left_val - right_val;
                cout << "new result: " << result << endl;
                break;
        }
        return result;
    }
    
};

struct ExpressionProcessor
{
  map<char,int> variables;

  int calculate(const string& expression)
  {
      Cal cal{};
      for(int i=0; i<expression.size(); ++i) {
          if(expression[i]>='0' && expression[i]<='9') {
              ostringstream oss;
              oss << expression[i];
              int j = i+1;
              for(;j<expression.size(); ++j) {
                  if(expression[j]>='0' && expression[j]<='9') {
                      oss << expression[j];
                  }else {
                      break;
                  }
              }
              i = j-1;
              
              int val{};
              istringstream iss{oss.str()};
              iss >> val;
              
             
              if(!cal.caled) {
                  cal.left_val = val;
                  cal.result = val;
                  cal.caled = true;
              } else {
                  
                 cal.right_val = val;
                 cal.result = cal.eval();
                 cal.left_val = cal.result;
              }
              
              
          } else if(expression[i] == '+') {
              cal.op = Cal::Op::Add;
          } else if(expression[i] == '-') {
              cal.op = Cal::Op::Sub;
          } else {
              // 字母
              // 多一个字母
              if(i+1 < expression.size()) {
                if((expression[i+1] <'0' || expression[i+1] >'9') && (expression[i+1] != '+') && (expression[i+1] != '-') ) {
                      return 0;
                 }
              }
              
              if(variables.find(expression[i])!=variables.end()) {
                 if(!cal.caled) {
                    cal.left_val = variables.find(expression[i])->second;
                    cal.caled = true;
                 } else {
                    cal.right_val = variables.find(expression[i])->second;
                    cal.result = cal.eval();
                    cal.left_val = cal.result;
                 }
              }else {
                  return 0;
              }
              
          }
      }

      return cal.result;
  }
};
上一篇 下一篇

猜你喜欢

热点阅读