Program calculator;

type
  kindtype = (num, sym, opp);
  str10 = string[10];
  str5 = string[5];
  list = array [1..255] of str10;
  node = ^Pnode;
  Pnode = record
    nam:str5;
    case kind:kindtype of
      num:(val:real);
{           neg:boolean}
{      sym:(nam:str5);}
      opp:({nam:str5;}
           lt,rt:node);
    end;
  Stable = array [1..100,1..2] of node;

var
  show,emul,ediv:boolean;
  max,max2:integer;
  table:Stable;

  function valu(str:str10):real;
  var
    i:integer;
    a:real;
  begin
    val(str,a,i);
    valu:=a;
  end;

  procedure kil(var n:node);
  begin
    if n<>nil then
    begin
     if n^.kind=opp then
     begin
       kil(n^.lt);
       kil(n^.rt);
     end;
     dispose(n);
    end;
  end;

  procedure disp(n:node);
  begin
    if n=nil then write('_');
    if n<>nil then
    begin
{      if (n^.kind=sym) and n^.neg then write('-');}
      if n^.kind = num then write(n^.val:0:10)
      else if n^.kind = sym then write(n^.nam)
      else begin
        write('(');
        disp(n^.lt);
        write(n^.nam);
        disp(n^.rt);
        write(')');
      end;
    end;
  end;

  procedure new_node(var n:node;k:kindtype);
  begin
    new(n);
    n^.kind:=k;
    if k=num then
    begin
      n^.val:=0;
{      n^.neg:=false;}
    end else if k=sym then
      n^.nam:=''
    else begin
      n^.nam:='';
      n^.lt:=nil;
      n^.rt:=nil;
    end;
  end;

  procedure factor(a:node);
  var
    i,m:integer;
    n:real;
    temp:node;
  begin
    if a^.kind = num then
    begin
      temp:=a;
      if a^.val = trunc(a^.val) then
      begin
        n:=a^.val;
        m:=trunc(n/2);
        for i:=2 to trunc(n-1) do
        begin
          disp(temp);
          a^.kind:=opp;
          a^.nam:='*';
          new_node(a^.lt,num);
          new_node(a^.rt,num);
          a^.lt^.val:=i;
          a^.rt^.val:=n;
          a:=a^.rt;
          i:=1;
          writeln;
          disp(temp);
          writeln;
        end;
      end;
    end;
    a:=temp;
  end;

  function equal(n,m:node):boolean;
  var
    e:boolean;
  begin
    e:=(n=nil) and (m=nil);
    if (n<>nil) and (m<>nil) then
    begin
      if n^.kind = m^.kind then
      begin
        if n^.kind = opp then
        begin
          if n^.nam='/' then
            e:=equal(n^.lt,m^.lt) and equal(n^.rt,m^.rt)
            else e:= (equal(n^.lt,m^.lt) and equal(n^.rt,m^.rt))
              or (equal(n^.lt,m^.rt) and equal(n^.rt,m^.lt));
        end;
        case n^.kind of
          sym,opp:e:=e and (m^.nam = n^.nam);
          num:e:=m^.val=n^.val;
        end;
      end;
    end;
    equal:=e;
  end;

  procedure inpu(var n:node); forward;

  procedure lis(s:string;var ar:list);
  var
    i,c,l:integer;
  begin
    c:=1;
    l:=1;
    for i:=1 to 255 do ar[i]:= '';
    while l<length(s)+1 do
    begin
      case s[l] of
      'a'..'z','0'..'9':begin
        while ((s[l] in ['a'..'z']) or (s[l] in ['0'..'9'])) and (l<length(s)+1) do
        begin
          ar[c]:= ar[c]+s[l];
          l:=l+1;
        end;
        c:=c+1;
        l:=l-1;
      end;
      ' ',')':c:=c+1;
      else
        ar[c]:=s[l];
        c:=c+1;
      end;
      l:=l+1;
    end;
  end;

  function right(s:string):string;
  var
    i:integer;
    sb:string;
  begin
    sb:='';
    for i:=2 to length(s) do sb:=sb+s[i];
    right:=sb;
  end;

  procedure parse(var li:list;var l:integer;var n:node);
  var z,jj:integer;
  begin
    z:=1;
    l:=l+1;
    case li[l][z] of
      'a'..'z':begin
        new_node(n,sym);
        n^.nam:=li[l];
      end;
      '0'..'9':begin
        new_node(n,num);
        n^.val:=valu(li[l]);
      end;
      '(':begin
        new_node(n,opp);
        parse(li,l,n^.lt);
        parse(li,l,n);
        parse(li,l,n^.rt);
      end;
      '_':n:=nil;
     else n^.nam:=li[l];
  end;
  end;

  procedure addeq;
  var
    a,b:node;
  begin
    write('a-');
    inpu(a);
    write('b-');
    inpu(b);
    max:=max+1;
    table[max,1]:= a;
    table[max,2]:= b;
  end;

  procedure showeq;
  var i:integer;
  begin
    for i:=1 to max do
    begin
      write(i,'A- ');disp(table[i,1]);writeln;
      write(i,'B- ');disp(table[i,2]);writeln;
    end;
  end;

  procedure inpu(var n:node);
  var
    s:string;
    l:list;
    a:integer;
  begin
    a:=0;
    write(':');
    readln(s);
    if s='quit' then halt;
    if s='showeq' then
    begin
      showeq;
      inpu(n);
    end else
      if s='addeq' then
      begin
        addeq;
        inpu(n);
      end else begin
        lis(s,l);
        parse(l,a,n);
      end;
  end;

  procedure init;
  var i:integer;
  begin
    for i:=1 to 100 do
    begin
      table[i,1]:=nil;
      table[i,2]:=nil;
    end;
  end;

  procedure main;
  var
    a,b:node;
    Ne,i:integer;
  begin
    max:=0;
    for i:=1 to 1000 do
    begin
      inpu(a);
      disp(a);
      writeln;
    end;
  end;

begin
  main;
end.
