Конференция "FreePascal" » Infix to postfix [Win32]
 
  • yozhik89 (13.10.09 13:49) [0]
    Здраствуйте!! Помогите разобратся с кодом на паскале, он по идеи конвертирует из инфиксной в постфиксную форму:

    Type
    Datatype=string[4];
    Expr=array [1..255] of Datatype;
    Var
    infix, postfix, operator:string;
    Ainfix, Apostfix:Expr;
    V:real;
    k:byte;

    Function IsFunc(a:string):boolean;
    Begin
      IsFunc:=(a='I') or (a='sin') or (a='cos') or (a='ln') or (a='exp') or (a='sqr') or (a='sqrt');
    End;
    Function IsSign(a:string):boolean;
    Begin
     IsSign:=(a='+') or  (a='-') or (a='*') or (a='/');
    End;
    Function IsDelim(s:string):boolean;
    Begin
     IsDelim:=IsSign(s) or
              (s=' ') or (s='(') or (s=')') or
              IsFunc(s);
    End;

    {********* Процедура перетворення виразу з інфіксної форми на постфіксну *********}
    Procedure Translate(infix:string; var Apostfix:Expr);
    Type
     PEL=^EL;
     EL=record              {Визначення структури елемента стека знаків операцій}
              Dat:Datatype;
              Next:PEL;
             end;
    Var
     P:pointer;
     TOP, ANYEL : PEL;
     I,j:byte;
     C:Datatype;
     Flag:boolean;

    Procedure InitSteck(X:Datatype);
     Begin
      new(ANYEL);
      ANYEL^.Next:=nil;
      ANYEL^.Dat:=X;
      TOP:=ANYEL;
     End;

    Procedure InSteck(X:Datatype);
     Begin
      new(ANYEL);
      ANYEL^.Next:=TOP;
      ANYEL^.Dat:=X;
      TOP:=ANYEL;
     End;

    Function IfEmpty:boolean;
     Begin
      IfEmpty:=TOP=nil
     End;

    Function FromSteck:Datatype;
     Begin
      if not IfEmpty then
       begin
        ANYEL:=TOP;
        FromSteck:=ANYEL^.Dat;
        TOP:=TOP^.Next;
        dispose(ANYEL)
       end;
     End;

    Procedure CorInfix;
     Var buf:string;
         i,j:byte;
         c:Datatype;
         Binfix:Expr;
     Begin
      j:=0;
      i:=1;
      k:=0;
      while i<=length(infix) do
       begin
        if IsSign(infix[i]) or (infix[i]='(') or (infix[i]=')')
          then begin inc(j); Ainfix[j]:=infix[i]; inc(i) end
          else if infix[i]=' '
                 then inc(i)
                 else begin
                       inc(j); buf:='';
                       repeat
                        buf:=buf+infix[i]; inc(i)
                       until IsDelim(infix[i]) or (i>length(infix));
                       Ainfix[j]:=buf
                      end;
        if not IsFunc(Ainfix[j])
           then begin
                 inc(k); Binfix[k]:=Ainfix[j];
                 if Ainfix[j]='(' then InSteck('(');
                 if Ainfix[j]=')' then begin
                                       c:=FromSteck;
                                       if TOP^.Dat='[' then begin inc(k); Binfix[k]:=')'; c:=FromSteck end
                                      end;
                end
           else begin
                 if (j=1) or ((j>1) and (Ainfix[j-1]<>'('))
                    then begin
                          inc(k); Binfix[k]:='('; inc(k); Binfix[k]:=Ainfix[j];
                          if IfEmpty then InitSteck('[') else InSteck('[');
                         end
                    else begin inc(k); Binfix[k]:=Ainfix[j] end
                end
       end;
       Ainfix:=Binfix
     End;

    { Основна частина процедури перетворення }
    Begin
     mark(P);
     TOP:=nil;
     CorInfix;
     InitSteck('(');
     j:=0;
     for I:=1 to k do
      begin
       if not (IsDelim(Ainfix[I])) then begin inc(j); Apostfix[j]:=Ainfix[I]; end;
       if Ainfix[I]='(' then  InSteck('(');
       if Ainfix[I]=')' then
         begin
          repeat
           C:=FromSteck;
           if C<>'(' then begin inc(j); Apostfix[j]:=C; end;
          until C='(';
         end;
       if IsSign(Ainfix[I]) then
         begin
          repeat
           C:=FromSteck;
           Flag:=((C='+') or (C='-')) and ((Ainfix[I]='*') or (Ainfix[I]='/')) or (C='(') or (C=')');
           if not Flag then begin inc(j); Apostfix[j]:=C; end;
          until Flag;
          InSteck(C);
          InSteck(Ainfix[I]);
         end;
       if IsFunc(Ainfix[I]) then
         begin
          InSteck(Ainfix[I]);
         end;
      end;
     repeat
       C:=FromSteck;
       if C<>'(' then begin inc(j); Apostfix[j]:=C; end;
     until C='(';
     release(P);
     k:=j
    End;

    {******** Процедура перетворення виразу з постфіксної форми на операторну *******}
    Procedure Convert(S1:Expr; var S2:string);
    Type
     PTS=^TS;
     TS=record
         S:string;
         next,prev:PTS;
        end;
    var
     B,E,T:PTS;
     P1:pointer;
     i:byte;
     FlagInt:boolean;
     x,y:string;
    Begin
     mark(P1);
     new(T);
     T^.S:='b('+ S1[1] + ')'; T^.prev:=nil; T^.next:=nil;
     B:=T; E:=T;
     for i:=2 to k do
      begin
       new(T);
       if not (IsSign(S1[i]) or IsFunc(S1[i])) then T^.S:='b('+ S1[i] + ')' else T^.S:=S1[i];
       T^.prev:=E; T^.next:=nil;
       E^.next:=T; E:=T;
      end;
     T:=B;
     repeat
      if IsSign(T^.S) then begin
                             T^.S:='F(2,' + T^.S + ')[' + T^.prev^.prev^.S + ',' + T^.prev^.S + ']';
                             if T^.prev^.prev^.prev<>nil then T^.prev^.prev^.prev^.next:=T;
                             T^.prev:=T^.prev^.prev^.prev
                           end
                      else begin
                            if IsFunc(T^.S) then
                              begin
                               if not (T^.S='I')
                                then begin
                                      T^.S:='F(1,' + T^.S + ')[' + T^.prev^.S + ']';
                                      if T^.prev^.prev<>nil then T^.prev^.prev^.next:=T;
                                      T^.prev:=T^.prev^.prev;
                                     end
                                else begin
                                      x:= copy(T^.prev^.S,8,length(T^.prev^.S)-7);
                                      y:= copy(x,1,pos(',',x)-1);
                                      x:= copy(x,pos(',',x)+3,length(x)-2-pos(',',x)-2);
                                      T^.S:='F(n,'+x+')['+y+']';
                                      if T^.prev^.prev<>nil then T^.prev^.prev^.next:=T;
                                      T^.prev:=T^.prev^.prev;
                                     end
                              end
                           end;
      T:=T^.next
     until T=nil;
     S2:=E^.S;
     release(P1);
    End;

    BEGIN
     write('Infix expression: '); readln(infix);
     Translate(infix, Apostfix);
     Convert(Apostfix, operator);
     write('Operator expression: '); writeln(operator);
     readln;
    END.
  • Сергей М. © (21.10.09 14:31) [1]

    > Помогите разобратся с кодом


    Он что, обидел тебя ?
  • имя (15.11.09 03:01) [2]
    Удалено модератором
 
Конференция "FreePascal" » Infix to postfix [Win32]
Есть новые Нет новых   [134427   +38][b:0][p:0]