Betreff: Re: Equation Parser
     Datum: Fri, 04 Sep 1998 02:11:55 -0700
       Von: Yuri Pilipishin 
     Firma: JCM Group
        An: newsserv@gu.kiev.ua
     Foren: comp.lang.pascal.delphi.misc


Ben Crain wrote:
> 
> I am new to Delphi, but with some experience in VB.  I want to develop
> an application (in both VB & Delphi, until I decide which is better) in
> which the user enters a mathematical equation, presumably as a string
> (any arbitrary equation, using any of the standard mathematical
> operators : +,*,^, etc, and any of the standard functions: sin, exp,
> etc.).  I need to take that string, convert it to a real function, and
> evaluate it.

Simple, but still useful solution, written originally in Turbo Pascal 3.0 (and
working with any version of Delphi as well). Examples of usage:

 x := ExeFn('2+(x5*y)^2', 1, 4, 0,0);
 ..........

 if not BadFn(Str, ['x', 'y', 't'])
 then s := ExeFn(Str, 3, 7.777, 0, 0)
 else WriteLn('Error in expression');

Please, write me if you need more explanation.

Sincerely,
Yuri Pilipishin



----------------------------------------------------

unit calcfn;
                       { (c) 1991  Yuri Pilipisin }
interface
uses mathfns;

  type charset=set of char;

  function exefn(var f:string; x,y,z,t:real):real;
  function badfn(var f:string; arguments:charset):boolean;

implementation

  type tab=array[1..255]of byte;
  var  stack,stb:tab; oldfn:string; c:real; sp,i:integer;

  procedure set_stb(var f:string);
  begin
    sp:=1;
    for i:=1 to length(f) do
    case f[i] of
     '(': begin stack[sp]:=i;inc(sp)       end;
     ')': begin dec(sp);stb[i]:=stack[sp]  end
    end;
    oldfn:=f
  end;

  function exefn(var f:string; x,y,z,t:real):real;
    
     function calc(p1,p2:byte):real;
       var p:byte;
       function found(ch:char):boolean;
       begin
        p:=p2;
        while not((f[p]=ch)or(poldfn then set_stb(f);
     exefn:=calc(1,length(f))
  end;

  const
    operators=['+','-','*','/','^'];
    func_num=17;
    func:array [1..func_num] of string[6] =
    ('sin','cos','tg','ctg','sh','ch','th','cth','sgn','abs','-','ln','exp',
     'arcsin','arccos','arcctg','arctg');

  function badfn(var f:string; arguments:charset):boolean;

      function fnok(p1,p2:byte):boolean;
         var p:byte; ok:boolean;
         function operator:boolean;
         begin
          p:=p2;
          while not((f[p] in operators)or(pp2        then fnok:=false
        else if p1=p2        then fnok:=f[p1] in (arguments+['0'..'9'])

        else if (stb[p2]=p1)
            and (f[p2]=')' ) then fnok:=fnok(p1+1,p2-1)
        else if f[p1]=' '    then fnok:=fnok(p1+1,p2)
        else if f[p2]=' '    then fnok:=fnok(p1,p2-1)

        else if operator     then fnok:=fnok(p1,p-1) and fnok(p+1,p2)
        else if f[p1] in ['0'..'9']
             then begin  val(copy(f,p1,p2-p1+1),c,i);fnok:=(i=0) end
        else if copy(f,p1,p2-p1+1)='pi' then fnok:=true

        else begin
          i:=0; ok:=false;
          repeat
           inc(i);
           ok:=func[i]=copy(f,p1,length(func[i]))
          until ok or (i=func_num);
          fnok:=ok and fnok(p1+length(func[i]),p2)
        end

      end;

  begin
    set_stb(f);
    badfn:=(sp<>1)or not fnok(1,length(f))
  end;

end.

-------------------------------------------------------------------

unit mathfns;

interface

  function power(a,b:real):real;
  function tg     (x:real):real;
  function ctg    (x:real):real;
  function sc     (x:real):real;
  function csc    (x:real):real;
  function sh     (x:real):real;
  function ch     (x:real):real;
  function th     (x:real):real;
  function cth    (x:real):real;
  function sch    (x:real):real;
  function csch   (x:real):real;
  function arcsin (x:real):real;
  function arccos (x:real):real;
  function arctg  (x:real):real;
  function arcctg (x:real):real;
  function sgn    (x:real):real;

implementation

  function power(a,b:real):real;
  begin
    if (a>0) and (b>=0) then power:=exp(a*ln(a))
    else if b<0 then power:=1/power(a,-b)
    else if a<0 then
      begin
        if frac(b/2)=0
        then power:= power(-a,b)
        else power:=-power(-a,b)
      end
    else power:=0; {a=0}
  end;

  function arcsin(x:real):real;
  begin
    arcsin:=arctan(x/sqrt(1-sqr(x)))
  end;

  function sgn(x:real):real;
  begin
    if      x>0 then sgn:=1
    else if x<0 then sgn:=-1
    else sgn:=0
  end;

  function tg    (x:real):real; begin  tg:=sin(x)/cos(x)       end;
  function ctg   (x:real):real; begin  ctg:=1/tg(x)            end;
  function sc    (x:real):real; begin  sc:=1/cos(x)            end;
  function csc   (x:real):real; begin  csc:=1/sin(x)           end;
  function sh    (x:real):real; begin  sh:=(exp(x)-exp(-x))/2  end;
  function ch    (x:real):real; begin  ch:=(exp(x)+exp(-x))/2  end;
  function th    (x:real):real; begin  th:=sh(x)/ch(x)         end;
  function cth   (x:real):real; begin  cth:=1/th(x);           end;
  function sch   (x:real):real; begin  sch:=1/ch(x)            end;
  function csch  (x:real):real; begin  csch:=1/sh(x)           end;
  function arctg (x:real):real; begin  arctg:=arctan(x)        end;
  function arcctg(x:real):real; begin  arcctg:=pi/2-arctg(x)   end;
  function arccos(x:real):real; begin  arccos:=pi/2-arcsin(x)  end;

end.


    Source: geocities.com/SiliconValley/2926/tpsrc

               ( geocities.com/SiliconValley/2926)                   ( geocities.com/SiliconValley)