#include <iostream>
#include <string>
#include <stack>
using namespace std;
const int MAX_ROW = 100;
class CRational
{
int up, down;
void Reduce();
public:
CRational(int _up = 0, int _down = 0)
{
up = _up;
down = _down;
if(up*down!=0) Reduce();
}
void Set(int _up, int _down)
{
up = _up;
down = _down;
Reduce();
}
CRational operator + (int num)
{
this->up += this->down*num;
Reduce();
return *this;
}
CRational operator + (CRational r)
{
this->up *= r.down;
r.up *= this->down;
this->up += r.up;
this->down *= r.down;
Reduce();
return *this;
}
CRational operator * (int num)
{
this->up *= num;
Reduce();
return *this;
}
CRational operator * (CRational r)
{
this->up *= r.up;
this->down *= r.down;
Reduce();
return *this;
}
friend CRational operator + (int num, CRational r)
{
return (r.operator +(num));
}
friend CRational operator * (int num, CRational r)
{
return (r.operator *(num));
}
friend ostream &operator<<(ostream &out, CRational r)
{
out<<r.up<<"/"<<r.down;
return
}
};
void CRational::Reduce()
{
int a, b, temp = 1;
int m = up>0?up:-up;
int n = down>0?down:-down;
while (temp)
{
a=m>n?m:n;
b=m<=n?m:n;
temp=a%b;
m=temp;
n=b;
}
up = up/n;
down = down/n;
}
class CElement
{
CRational r;
int n;
bool bInt;
public:
CElement(int up=0, int down=0, int _n=0): r(up,down)
{
n = _n;
bInt = false;
}
void Set(int up, int down, int _n, bool _bInt)
{
bInt = _bInt;
if(!bInt)
r.Set(up,down);
else
n = _n;
}
void Set(CRational inR)
{
bInt = false;
r = inR;
n = 0;
}
CRational GetRational()
{
return r;
}
friend CRational operator + (CElement valueL, CElement valueR)
{
if(valueL.bInt && valueR.bInt)
return CRational(valueL.n+valueR.n, 1);
else if (valueL.bInt)
return (valueL.n+valueR.r);
else if (valueR.bInt)
return (valueL.r+valueR.n);
else
return (valueL.r+valueR.r);
}
friend CRational operator * (CElement valueL, CElement valueR)
{
if(valueL.bInt && valueR.bInt)
return CRational(valueL.n*valueR.n, 1);
else if (valueL.bInt)
return (valueL.n*valueR.r);
else if (valueR.bInt)
return (valueL.r*valueR.n);
else
return (valueL.r*valueR.r);
}
};
bool IsNumber(char c)
{
if(c=='+' || c=='*' || c=='\0')
return false;
else
return true;
}
char Precede(char optrLeft, char optrRight)
{
if(optrLeft=='#')
return '<';
if(optrLeft==optrRight)
return '>';
else if(optrLeft=='+' && optrRight=='*')
return '<';
else
return '>';
}
CElement StringToValue(string exp, int &i)
{
bool bPlus = true;
bool bInterrupt = false;
char token;
int up, down;
CElement elem;
up = 0;
token = exp[i];
if (token == '-') { bPlus = false; token = exp[++i];}
do
{
up = up*10+(token - '0');
i++;
if(i==exp.size()) break;
token = exp[i];
if(token == '/') bInterrupt = true;
}
while(!bInterrupt && IsNumber(token));
if(!bPlus) up = -up;
if(bInterrupt)
{
down = 0;
token = exp[++i];
do
{
down = down*10+(token - '0');
i++;
if(i==exp.size()) break;
token = exp[i];
}
while(IsNumber(token));
elem.Set(up, down, 0, false);
}
else
{
elem.Set(0, 0, up, true);
}
return elem;
}
int main()
{
int rowNum, i;
string exp;
char token;
char theta;
CElement value, valueLeft, valueRight;
stack <char> optr;
stack <CElement> opnd;
CRational result[MAX_ROW];
rowNum = 0;
cin >> exp;
while (exp != "exit" && rowNum < MAX_ROW)
{
optr.push('#');
i = 0;
while((i<exp.size()) || optr.top()!= '#')
{
token = exp[i];
if (IsNumber(token))
{
value = StringToValue(exp, i);
opnd.push(value);
}
else
{
if ((Precede(optr.top(),token)) == '<')
{
optr.push(token);
i++;
}
else
{
theta = optr.top();
optr.pop();
valueLeft = opnd.top();
opnd.pop();
valueRight = opnd.top();
opnd.pop();
if(theta == '+')
value.Set(valueLeft+valueRight);
else if (theta == '*')
value.Set(valueLeft*valueRight);
else
value.Set(0, 0, 0, false);
opnd.push(value);
}
}
}
value = opnd.top();
result[rowNum] = value.GetRational();
opnd.pop();
cin >> exp;
rowNum++;
}
for (i=0; i<rowNum; i++)
cout << result[i];
}