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

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
  */
};



你可能感兴趣的:(list,null,Class,reference,output)