中缀表达式转后缀表达式(部分代码)

来源:互联网 发布:手机投影仪软件下载 编辑:程序博客网 时间:2024/06/05 10:12
class Parser{  /* reference: http://totty.iteye.com/blog/123252    * infix expression => postfix expression   */  class PostExpStack  {private:    #define  STACK_SIZE   100    Symbol *sym[STACK_SIZE];    int index;public:    PostExpStack()    {      index = 0;    }    int push(Symbol *s)    {      int err = OB_SUCCESS;      if (NULL == s)      {        TBSYS_LOG(WARN, "unexpected NULL. wtfQ");      }      TBSYS_LOG(DEBUG, "push an element into stack");      if (index < STACK_SIZE)      {        sym[index] = s;        index++;     }      else      {        err = OB_ERROR;      }      return err;    }    Symbol *pop()    {      Symbol *s;      TBSYS_LOG(DEBUG, "pop an element from stack");      if(!is_empty())      {        index--;        s = sym[index];        if (NULL == s)        {          TBSYS_LOG(WARN, "unexpected NULLi. index = %d", index);        }      }      else      {        s = NULL;      }      return s;    }    inline bool is_empty()    {      return (0 == index);    }  };  public:    Parser(Symbol *sym_list, int size):sym_list(sym_list),len(size)    {      TBSYS_LOG(DEBUG, "init Parser");      idx = 0;      if (NULL == sym_list)      {        TBSYS_LOG(WARN, "invalid sym list");      }      TBSYS_LOG(DEBUG, "init Parser succ. sys_list=%p, size=%d", sym_list, len);    }    ~Parser(){}  public:    int parse()    {      int err = 0;      int i = 0;      err = parse_Expression();      return err;    }  private:    PostExpStack stack;    Symbol *sym_list;    int len;    int idx;  private:    int parse_Expression()    {      int err = OB_SUCCESS;      int i = 0;      int code = 0;      Symbol *sym = NULL;      for (i = 0; i < len; i++)      {        sym = &sym_list[i];        code = sym->code;        TBSYS_LOG(DEBUG, "code = %d", code);        switch(code)        {          case peCodeLeftBracket:            err = stack.push(sym);            break;          case peCodeRightBracket:            err = do_oper2();            break;          case peCodeMul:          case peCodeDiv:            //break;          case peCodeAdd:          case peCodeSub:           // break;          case peCodeLessThan:          case peCodeLessOrEqual:          case peCodeEqual:          case peCodeNotEqual:          case peCodeGreaterThan:          case peCodeGreaterOrEqual:          case peCodeIs:          case peCodeLike:           // break;          case peCodeAnd:           // break;          case peCodeOr:            err = do_oper1(sym);            break;          case peCodeString:          case peCodeInt:          case peCodeFloat:          case peCodeDateTime:          case peCodeNull:          case peCodeTrue:          case peCodeFalse:            err = output(sym);            break;          default:            err = output(sym);            /*            err = OB_ERR_UNEXPECTED;            TBSYS_LOG(WARN, "unexpected symbol found");            */            break;        }        if (OB_SUCCESS != err)        {          break;        }      }      while((OB_SUCCESS == err) && !stack.is_empty())      {        err = output(stack.pop());      }      return err;    }    int do_oper1(Symbol *new_sym)    {      int err = OB_SUCCESS;      Symbol *old_sym;      int code = 0;      int new_prio = 0;      int old_prio = 0;      if (NULL != new_sym)      {        while((OB_SUCCESS == err) && (!stack.is_empty()))        {          old_sym = stack.pop();          if (NULL  == old_sym)          {            TBSYS_LOG(WARN, "unexpect null pointer");            err = OB_ERROR;            break;          }          code = old_sym->code;          if (peCodeLeftBracket == code)          {            err = stack.push(old_sym);            if (OB_SUCCESS != err)            {              TBSYS_LOG(WARN, "fail to push symbol into stack. stack is full!");            }            break;          }          else          {            new_prio = new_sym->prio;            old_prio = old_sym->prio;            if (new_prio > old_prio)            {              err = stack.push(old_sym);              if (OB_SUCCESS != err)              {                TBSYS_LOG(WARN, "fail to push symbol into stack. stack is full!");              }              break;            }            else            {              err = output(old_sym);            }          }        } /* while */        TBSYS_LOG(DEBUG, "push new sym");                if (OB_SUCCESS == err)        {          err = stack.push(new_sym);        }      }      else      {        TBSYS_LOG(WARN, "symbol pointer is null");        err = OB_ERROR;      }      return err;    }    int do_oper2()    {      int err = OB_SUCCESS;      Symbol *sym;      int code = 0;      while(!stack.is_empty())      {        sym = stack.pop();        if (NULL == sym)              {          TBSYS_LOG(WARN, "fail to pop symbol from stack. stack is empty!");          err = OB_ERROR;        }        code = sym->code;        if (peCodeLeftBracket == code)        {          break;        }        else        {          err = output(sym);          if (OB_SUCCESS != err)          {            TBSYS_LOG(WARN, "unexpected error");            break;          }        }      }      return err;    }    int output(Symbol *s)    {      TBSYS_LOG(INFO, ">>>>>>>>output===>>>>: [code:%d, value:%.*s]",           s->code,          s->length,          s->value);      s->encode.dump();      return OB_SUCCESS;    }};int infix2postfix(Symbol *sym_list, int size, ObObj *arr){  int err;  Parser *p  = new Parser(sym_list, size);  err = p->parse();  if (OB_ITER_END != err)  {    err = OB_ERROR;  }  else  {    err = OB_SUCCESS;  }  return err;}



支持多种运算:

enum peCode{  peCodeLeftBracket = 1,  peCodeRightBracket = 2,  peCodeMul = 3,  peCodeDiv = 4,  peCodeAdd = 5,  peCodeSub = 6,  peCodeLessThan = 7,  peCodeLessOrEqual = 8,  peCodeEqual = 9,  peCodeNotEqual = 10,  peCodeGreaterThan = 11,  peCodeGreaterOrEqual = 12,  peCodeIs = 13,  peCodeLike = 14,  peCodeAnd = 15,  peCodeOr = 16,  peCodeColumnName = 50,  peCodeString = 51,  peCodeInt = 52,  peCodeFloat = 53,  peCodeDateTime = 54,  peCodeNull = 55,  peCodeTrue = 56,  peCodeFalse = 57};enum pePriority{  pePrioLeftBracket = 100,  /* highest */  pePrioRightBracket = 0,   /* lowest */  pePrioMul = 9,  pePrioDiv = 9,  pePrioAdd = 8,  pePrioSub = 8,  pePrioLessThan = 7,  pePrioLessOrEqual = 7,  pePrioEqual = 7,  pePrioNotEqual = 7,  pePrioGreaterThan = 7,  pePrioGreaterOrEqual = 7,  pePrioIs = 7,  pePrioLike = 7,  pePrioAnd = 6,  pePrioOr = 5 /*,  pePrioString = -1,  pePrioInt = -1,  pePrioFloat = -1,  pePrioDateTime = -1,  pePrioNull = -1,  pePrioTrue = -1,  pePrioFalse = -1  */};



原创粉丝点击