procedure ProcA(vcExpress:string);
var                          
  AStackSrc,AStackDst:TStack;
  i,iCount:integer;          
  AChar:Char;                
  pAChar:^Char;              
  pAItem:pChar;              
  AString,AStringRet:String; 
  pAString:^String;        
begin
  Try                                          
    AStackSrc:=TStack.Create;                  
    AStackDst:=TStack.Create;                  
//================================             
    for iCount:=0 to Length(vcExpress) do      
    begin                                      
      pAChar:=@vcExpress[iCount];              
      AStackSrc.Push(pAChar);                  
    end;                                       
//================================             
    iCount:=AStackSrc.Count;                   
    for i:=0 to iCount-1 do                    
    begin                                      
      pAChar:=AStackSrc.Pop;                   
      AChar:=pAChar^;                          
      AStackDst.Push(pAChar);                  
      if AChar=LBracket then                   
      Begin                                    
//        new(pAString);                       
        Repeat                                 
//          new(pAItem);                       
          pAItem:=AStackDst.Pop;               
          AString:=AString+pAItem^;            
        Until (pAItem^=RBracket);              
        AStringRet:=AString;                   
//        pAString:=AllocMem(Length(AStringRet));
//        strCopy(pAString,pChar(AStringRet));   
        pAString:=@AStringRet;               
        AStackDst.Push(pAString);              
        AString:='';                           
        memo1.Lines.Add(pAString);             
      End;                                     
    end;                                       
  Finally                                      
    AStackSrc.Free;                            
    AStackDst.Free;                            
  End;                                         
End;
  
  
一个简单的解析表达式的过程
用表达式  vcExpress:='(((A+B)/(C+D+E)>15)and((D+E/(F+B))<16))'测试的结果:
(F+B)
(D+E/()
(<<16)
(C+D+E)
(A+B)
(??15)
(豠nd?
如果正确的话应该是如下的结果:
(F+B)
(D+E/(F+B))
((D+E/(F+B))<16)
(C+D+E)
(A+B)
((A+B)/(C+D+E)>15)
(((D+E/(F+B))<16)and((A+B)/(C+D+E)>15))
我估计问题出在
          pAItem:=AStackDst.Pop;               
          AString:=AString+pAItem^;
而在AString入栈之后,再pop的时候,取得的不是当初入栈的字符串了;

解决方案 »

  1.   

    for iCount:=0 to Length(vcExpress) do      
    应该是
      for iCount:=0 to Length(vcExpress)-1 do
      

  2.   

    不好意思,忘了贴了:
      LBracket='(';
      RBracket=')';
      

  3.   

    感觉怎么写这么乱啊?是不是自己拍脑袋出来的一个算法?
    我贴个算法给你吧,大学编译课有讲过这个算法,没好好上课吧?代码就不能贴了,因为实现了比这个复杂的功能,而且属于公司财产,有算法不会写代码就是你的不对了。1.把中缀表达式换成后缀表达式(逆波兰式)
      从左到右扫描中缀表达式(就是输入字符串inExpr),重复下述两步操作,直到表达式尾。
      (1)从inExpr中取出下个sToken(数字、运算符、小括号)
      (2)case sToken of
           '(':将sToken压入栈;
           操作数:将操作数加入outExpr; 如9,
           操作符:如栈空或sToken比栈顶元素优先级高,将sToken进栈;
                   否则,出栈并将出栈元素加入outExpr,然后再将sToken与新栈顶元素比较;
           ')':出栈并将出栈元素加入outExpr,直到碰到'(','('出栈不加入outExpr。
      (3)当inExpr扫描完毕,连续出栈并将出栈元素加到outExpr,直至栈空。2.对后缀表达式进行计算
      栈stk初始化,用于存放计算结果
      从左到右扫描outExpr,重复下述两步操作,直到表达式尾。
      (1)从outExpr中取出下个sToken(数字、运算符)
      (2)case sToken of
           操作数:将操作数转换为double并入栈。
           操作符:出栈两个操作数,对其进行运算符计算,结果入栈。
      (3)当outExpr扫描完毕,栈顶的值就是计算结果。
      

  4.   

    To chuchu(维他命C):
    在此感谢chuchu(维他命C)大侠的指点,你说得算法固然不错,但是我这里用不着这么复杂;可能算法没有注释,你看起来会比较乱!
    其实我的设计思想很简单,当然表达式要按照如下的规则写:
    1)凡运算关系式一定要用括号"()"括起来;如((A+B)>10)
    2)凡表达式一定要用括号“()”括起来;如((A+B))
    3) 最终的关系式要用括号“()”括起来;如(((A+B)>10)and((A+B)<20))
    算法描述就是:
    1,先将表达式入栈AStackSrc;
    2,从AStackSrc出栈,入栈AStackDst;
    3,当出栈字符是“(”时候,将AStackDst入栈的字符出栈,并组成字符串,直到遇到“)”为止;
    4,将3)组成的字符串,入栈AStackSrc;然后继续1),直到AStackSrc为空;
    从我测试的结果看,估计算法是没有问题的,问题出在
    步骤4,入栈的字符串,取出来的好像不对;估计是字符串指针运用的不当!