需要该这段程序,但其中有些地方不知该怎么改 ,请教各位了。
double Calc::Run(char* buffer)
{  TStringList* tokens = new TStringList();      
char buf[CALC_MAXBUFFER];
AnsiString nowT;
int pos;     //标记链表中的位置
int r;
TStringList *opnd = new TStringList();
        TStringList *oper = new TStringList();
AnsiString a,b,x,y,z;
bool operLevel3 = true;                 //以上一段TstringList部分不知该如何改 isError=false;
strcpy(buf,buffer);
r = getToken(buf,tokens);
if(r != -1)
        {
   SetError("Expression syntax error.");
   return 0.0;
}
tokens->Add("$");
pos = 0; opnd->Add("0");
oper->Add("$"); while(pos<(tokens->Count))
        {
nowT=tokens->Strings[pos];
                pos++;
nowT.TrimLeft();
nowT.TrimRight();
nowT = nowT.LowerCase(); if(nowT == "e")         nowT="2.718281828";
if(nowT == "pi") nowT="3.1415926535897932384";
if(nowT == "ans") nowT =AnsiString(m_Ans);
if(nowT == "mr") nowT =AnsiString(m_Memory);
if((nowT.SubString(1,1) == "#")&&(nowT.SubString(nowT.Length(),1) == "#"))
if(!ProcVariable(nowT))
                        {
SetError("System variable not defined.");
return 0.0;
}

if(nowT.Pos('.')!=0)
                { // It's a number.
opnd->Add(nowT);
operLevel3 = false;
}
else{ // Now we get a operator.
//a = oper.GetTail();
if(nowT == "("){
oper->Add(nowT);
}
else{
if(nowT == ")")
                                { // So we just push the stacks until we encountered "("
                                        a = oper->Strings[oper->Count-1];
                                        oper->Delete(oper->Count-1);
while(a != "(")
                                        {
if(!operate(opnd,a))
                                                        {
SetError("Math operation error, perhaps the expression syntax.");
return 0.0;
}
                                                        a = oper->Strings[oper->Count-1];
                                                        oper->Delete(oper->Count-1);
                                        }
}
else{
a = oper->Strings[oper->Count-1]; // Not push, just look at it.
if(getPrior(a.c_str()) < getPrior(nowT.c_str())){
if((operLevel3)&&(nowT == '-')) nowT = "minus"; // special treat to the prefix '-'
if((operLevel3)&&(nowT == '+')) nowT = "positive"; // special treat to the prefix '+'
oper->Add(nowT);
}
else{ // We can calculate it until the prior return to be >
                                                a = oper->Strings[oper->Count-1];
                                                oper->Delete(oper->Count-1);
while((getPrior(a.c_str()) >= getPrior(nowT.c_str())) && (!((a == "$")&&(nowT == "$"))))
                                                {
if(!operate(opnd,a))
                                                        {
SetError("Math operation error, perhaps the expression syntax.");
return 0.0;
}
                                                        a = oper->Strings[oper->Count-1];
                                                        oper->Delete(oper->Count-1);
                                                }
if((a == "$")&&(nowT == "$")) break;
else{
oper->Add(a);
oper->Add(nowT);
}
}
}
}
operLevel3 = true; // we are encountering a symbol, so if we goon getting this, it'll be treated especially.
}
} m_Ans=atof((LPCTSTR)((opnd->Strings[opnd->Count-1]).c_str()));
opnd->Clear();
oper->Clear();
tokens->Clear();
return m_Ans;
}int Calc::getToken(char *buffer,TStringList *result){
int lastToken = CALC_NUM;
bool haveDot = false, isVar = false;
unsigned int nowP=0,nowNum=0,nowSym=0;
char numBuf[CALC_MAXBUFFER]="",symBuf[CALC_MAXBUFFER]=""; while(nowP<strlen(buffer)){
if(buffer[nowP] != ' '){
if(((buffer[nowP]>='0'&&buffer[nowP]<='9')||(buffer[nowP]=='.'))&&(!isVar)){
if(buffer[nowP]=='.')
if(haveDot==true) return(nowP);
else haveDot=true;
numBuf[nowNum]=buffer[nowP];
nowNum++;
if(lastToken!=CALC_NUM&&nowSym!=0){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
}
lastToken=CALC_NUM;
}
else{
if(lastToken==CALC_NUM&&nowNum!=0){
if(!haveDot){ numBuf[nowNum]='.';numBuf[nowNum+1]='\0';}
else numBuf[nowNum]='\0';
result->Add(numBuf);
strcpy(numBuf,"");nowNum=0;haveDot=false;
}
symBuf[nowSym]=buffer[nowP];
nowSym++;
if(buffer[nowP] == '#') isVar = true;
if(checkSym(symBuf,nowSym)){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
if(isVar) isVar = false;
}
lastToken=CALC_SYM;
}
}
nowP++;
} if(lastToken==CALC_NUM&&nowNum!=0){
if(!haveDot){ numBuf[nowNum]='.';numBuf[nowNum+1]='\0';}
else numBuf[nowNum]='\0';
result->Add(numBuf);
strcpy(numBuf,"");nowNum=0;haveDot=false;
}
if(lastToken==CALC_SYM&&nowSym!=0){
symBuf[nowSym]='\0';
result->Add(symBuf);
strcpy(symBuf,"");nowSym=0;
}
return(-1);
}

解决方案 »

  1.   

    var
      list : TStringList;
    begin
      list := TStringList.Create;
      

  2.   

    function Calc.Run(buffer: PAnsiChar): double;
    var
      tokens: TStringList;
      buf: Array[0..CALC_MAXBUFFER-1] of AnsiChar;
      nowT: AnsiString;
      pos: Integer;    //标记链表中的位置
      r: Integer;
      opnd: TStringList;
      oper: TStringList;
      a,b,x,y,z: AnsiString;
      operLevel3: Boolean;                //以上一段TstringList部分不知该如何改
    begin
      tokens := TStringList.Create();
      opnd := TStringList.Create();
      oper := TStringList.Create();
      operLevel3 := true;
      isError := false;
      StrPCopy(buf,buffer);
      Result := 0.0;
      r := getToken(buf,tokens);
      if(r <> -1) then
      begin
        SetError('Expression syntax error.');
        Exit;
      end;
      tokens.Add('$');
      pos := 0;  opnd.Add('0');
      oper.Add('$');  while(pos <(tokens.Count)) do
      begin
        nowT:=tokens.Strings[pos];
        Inc(pos);
        //nowT := TrimLeft(nowT);
        //nowT := TrimRight(nowT);
        nowT := Trim(nowT);
        nowT := LowerCase(nowT);    if(nowT = 'e') then nowT:='2.718281828';
        if(nowT = 'pi') then nowT:='3.1415926535897932384';
        if(nowT = 'ans') then nowT := AnsiString(m_Ans);
        if(nowT = 'mr')  then nowT :=AnsiString(m_Memory);
        if((Copy(nowT,1,1) = '#') and (Copy(nowT,Length(nowT),1) = '#')) then
          if Not (ProcVariable(nowT)) then begin
            SetError('System variable not defined.');
            Exit;
          end;
        if(AnsiPos('.', nowT)<>0) then
        begin// It's a number.
          opnd.Add(nowT);
          operLevel3 := false;
        end else begin // Now we get a operator.
          //a = oper.GetTail();
          if(nowT = '(') then begin
            oper.Add(nowT);
          end else begin
            if(nowT = ')') then
              begin // So we just push the stacks until we encountered "("
                a := oper.Strings[oper.Count-1];
                oper.Delete(oper.Count-1);
                while(a <> '(') do
                begin
                  if Not (operate(opnd,a)) then
                  begin
                    SetError('Math operation error, perhaps the expression syntax.');
                    Exit;
                  end;              a := oper.Strings[oper.Count-1];
                  oper.Delete(oper.Count-1);
                end;
              end else begin
                a := oper.Strings[oper.Count-1]; // Not push, just look at it.
                if(getPrior(PAnsiChar(a)) < getPrior(PAnsiChar(nowT))) then begin
                  if((operLevel3) and (nowT = '-')) then nowT := 'minus'; // special treat to the prefix '-'
                  if((operLevel3) and (nowT = '+')) then nowT := 'positive'; // special treat to the prefix '+'
                  oper.Add(nowT);
                end else begin // We can calculate it until the prior return to be >
                  a := oper.Strings[oper.Count-1];
                  oper.Delete(oper.Count-1);
                  while((getPrior(PAnsiChar(a)) >= getPrior(PAnsiChar(nowT))) and (not ((a = '$') and (nowT = '$')))) do
                  begin
                    if( not operate(opnd,a)) then
                    begin
                      SetError('Math operation error, perhaps the expression syntax.');
                      Exit;
                    end;
                    a := oper.Strings[oper.Count-1];
                    oper.Delete(oper.Count-1);
                  end;              if((a = '$') and (nowT = '$')) then break
                  else begin
                    oper.Add(a);
                    oper.Add(nowT);
                  end;
                end;
              end;
          end;
          operLevel3 := true; // we are encountering a symbol, so if we goon getting this, it'll be treated especially.
        end;
      end;  m_Ans:=strtofloat(opnd.Strings[opnd.Count-1]);
      opnd.Clear();
      oper.Clear();
      tokens.Clear();
      Result := m_Ans;
    end;function Calc.getToken(buffer: PAnsiChar; result: TStringList): Integer;
    var
      lastToken: Integer;
      haveDot, isVar: Boolean;
      nowP,nowNum, nowSym: LongWord;
      numBuf: Array[0..CALC_MAXBUFFER-1] of AnsiChar;
      symBuf: Array[0..CALC_MAXBUFFER-1] of AnsiChar;
    begin
      lastToken := CALC_NUM;
      haveDot := false;
      isVar := false;
      nowP:=0;
      nowNum:=0;
      nowSym:=0;
      fillchar( numBuf, sizeof(numBuf), 0);
      fillchar( symBuf, sizeof(symBuf), 0);  while(nowP <strlen(buffer)) do begin
        if(buffer[nowP] <> ' ') then begin
          if((((buffer[nowP]>='0') and (buffer[nowP] <='9')) or (buffer[nowP]='.')) and (Not isVar)) then begin
            if(buffer[nowP]='.') then
              if(haveDot=true) then begin
                Result := (nowP);
                Exit;
              end
              else haveDot:=true;
            numBuf[nowNum]:=buffer[nowP];
            Inc(nowNum);
            if(lastTokenM<>CALC_NUM) and (nowSym<>0) then begin
              symBuf[nowSym]:=#0;
              result.Add(symBuf);
              //strcpy(symBuf,"");
              fillchar(symBuf,sizeof(symBuf),0);
              nowSym:=0;
            end;
            lastToken:=CALC_NUM;
          end else begin
            if(lastToken=CALC_NUM) and (nowNum<>0) then Begin
              if(not haveDot) then begin
                numBuf[nowNum]:='.';
                numBuf[nowNum+1]:=#0;
              end else numBuf[nowNum]:=#0;
              result.Add(numBuf);
              fillchar(numBuf,sizeof(numBuf),0);
              nowNum:=0;
              haveDot:=false;
            End;
            symBuf[nowSym]:=buffer[nowP];
            Inc(nowSym);
            if(buffer[nowP] = '#') then isVar := true;
            if(checkSym(symBuf,nowSym)) then begin
              symBuf[nowSym]=#0;
              result.Add(symBuf);
              fillchar(symBuf,sizeof(symBuf),0);
              nowSym:=0;
              if(isVar)then isVar := false;
            end;
            lastToken:=CALC_SYM;
          end;
        end;
        Inc(nowP);
      end;  if(lastToken=CALC_NUM) and (nowNum<>0) then begin
        if(Not haveDot) then begin
          numBuf[nowNum]:='.';
          numBuf[nowNum+1]:=#0;
        end else numBuf[nowNum]:=#0;
        result.Add(numBuf);
        fillchar(numBuf,sizeof(numBuf),0);
        nowNum:=0;
        haveDot:=false;
      end;
      if(lastToken=CALC_SYM) and (nowSym<>0) then begin
        symBuf[nowSym]:=#0;
        result.Add(symBuf);
        fillchar(symBuf,sizeof(symBuf),0);
        nowSym:=0;
      end;
      Result :=(-1);
    end;