免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1207 | 回复: 0

计算器(计算字符串表达式)(修改自lemon例子) [复制链接]

论坛徽章:
0
发表于 2009-12-21 21:32 |显示全部楼层
#include
#include
#include
#include
#include
using namespace std;
//== 字符串表达式======
string strExp="3*(x-5) +7";
enum Token_value {
  NAME, NUMBER, END, INC, DEC,
  PLUS='+', MINUS='-', MUL='*', DIV='/',
  PRINT=';', ASSIGN='=', LP='(', RP=')'
};
Token_value curr_tok = PRINT;
double number_value;
string string_value;
double expr(bool );
double term(bool );
double error(const string&);
double prim(bool );
Token_value get_token();
map table;
double expr(bool get)
{
  double left = term(get);
  for(;;)
    switch(curr_tok) {
    case PLUS:
      left += term(true);
      break;
    case MINUS:
      left -= term(true);
      break;
    default:
      return left;
    }
}
double term(bool get)
{
  double left = prim(get);
  for(;;)
    switch(curr_tok) {
    case MUL:
      left *= prim(true);
      break;
    case DIV:
      if (double d = prim(true)) {
    left /=d;
    break;
      }
      return error("divide by 0");
    default:
      return left;
    }
}
double prim(bool get)
{
  if(get) get_token();
  switch(curr_tok) {
  case NUMBER:
    {
      double v = number_value;
      get_token();
      return v;
    }
  case NAME:
    {
      double& v = table[string_value];
      get_token();
      if (curr_tok  == ASSIGN)
        v = expr(true);
      if (curr_tok == INC)  //r++;
    v = v+1;
      if (curr_tok == DEC)  //r++;
    v = v-1;
      return v;
    }
  case INC:
    return prim(true)+1;
  case DEC:
    return prim(true)-1;
  case MINUS:
    return -prim(true);
  case LP:
    {
      double e=expr(true);
      if(curr_tok != RP) return error(" ')' expected");
      get_token();
      return e;
    }
  default:
    return error("primary expected");
  }
}
Token_value get_token()
{
  char ch;
  string strTemp;
  
  do {
    //============changed=========================
    //if(!cin.get(ch)) return curr_tok = END;
    //=========  to ==============================
      if (strExp.empty()) {
        return curr_tok = END;
      }
    ch = strExp.at(0);
    strExp.erase(0,1);
    if(!ch) {
        return curr_tok = END;
    }
    //===========================================
  } while(ch!='\n' && isspace(ch));
  switch(ch) {
  case ';':
  case '\n':
    return curr_tok=PRINT;
  case 0:
    return curr_tok=END;
  case '+':    // added for ++name and name++
    {
          char c;
          //================ changed =========================
          //if ( cin.get(c) && c == '+' )
               //return curr_tok=INC;
          //=========  to ==============================
          c = strExp.at(0);
          if (c == '+') {
              strExp.erase(0,1);
              return curr_tok=INC;
          }
          //================================================
        
          return curr_tok=Token_value(ch);
    }
  case '-':
    {
      char c;
      //===============changed============================
      //if ( cin.get(c) && c == '-' ) {
            //return curr_tok=DEC;
      //}
     //cin.putback(c);
      //============= to ==================================
      c = strExp.at(0);
      if (c == '-') {
          strExp.erase(0,1);
          return curr_tok=DEC;
      }
      //======================================
      return curr_tok=Token_value(ch);
    }
  case '*':
  case '/':
  case '(':
  case ')':
  case '=':
    return curr_tok=Token_value(ch);
  case '0':case '1': case '2': case '3': case '4':
  case '5': case '6': case '7': case '8': case '9':
  case '.':
    //================= changed =================================
    //cin.putback(ch);
    //cin >> number_value;
    //================  to =====================================
      strTemp.clear();
      strTemp.assign(1,ch);
      number_value = atof(strTemp.c_str());
    //=======================================================
    return curr_tok=NUMBER;
  default:
    if (isalpha(ch)){
      string_value=ch;
      //========================changed=========================
      //while(cin.get(ch) && isalnum(ch)) string_value.push_back(ch);
      //cin.putback(ch);
      //==========================to ===========================
      ch = strExp.at(0);
      if (isalnum(ch)) {
          strExp.erase(0,1);
          string_value.push_back(ch);
      }
      //================================================================
        
      return curr_tok=NAME;
    }
    error("bad token");
    return curr_tok=PRINT;
  }
}
int no_of_errors;
double error(const string& s)
{
  no_of_errors++;
  cerr  1) {
    get_token();
   
    if( curr_tok == END) break;
    if( curr_tok == PRINT) continue;
    wumao = expr(false);
    wumao*=1.1;
   // cout
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/45407/showart_2127455.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

DTCC2020中国数据库技术大会 限时8.5折

【架构革新 高效可控】2020年8月17日~19日第十一届中国数据库技术大会将在北京隆重召开。

大会设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

http://dtcc.it168.com


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP