#include <vector>
#include <iostream>
#include <sstream>
using namespace std;
#define STRINGIFY(msg) dynamic_cast<std::stringstream *>(&(std::stringstream() << msg))->str()
typedef vector<char> OpStack;
typedef vector<bool> ValStack;
OpStack ops;
ValStack vals;
enum Operation : char
{
NOT,
AND,
OR,
XOR,
R_PAR,
L_PAR,
END,
};
bool opNot();
bool opAnd();
bool opOr();
bool opXor();
bool opRPar();
bool opLPar();
bool opEnd();
bool (*functions[])() = {opNot, opAnd, opOr, opXor, opRPar, opLPar, opEnd};
bool parseSymbol(char c);
bool translate(char & c);
bool addOp(char c);
bool execute();
bool error(string error);
struct ValReturn{bool error; bool data;};
ValReturn valsPop();
int main()
{
while(cin.peek() != 'e')
{
parseSymbol(cin.get());
}
cin.ignore();
}
bool parseSymbol(char c)
{
if (c == 'T' || c == '1')
vals.push_back(true);
else if (c == 'F' || c == '0')
vals.push_back(false);
else if (translate(c))
{
if (!addOp(c))
{
ops.clear();
vals.clear();
}
}
else
return error(STRINGIFY("ERROR: Unknown symbol: '" << c << "'"));
return true;
}
bool addOp(char c)
{
while (!ops.empty() && ops.back() < c && c != L_PAR)
{
if (!execute())
return false;
}
ops.push_back(c);
if (c == END)
{
if (!execute())
return false;
if (!ops.empty())
{
return error("ERROR: Operator stack not empty at end of line!");
}
}
return true;
}
bool execute()
{
if (ops.empty())
{
return error("ERROR: Empty op stack!");
}
char op = ops.back();
ops.pop_back();
return functions[op]();
}
bool translate(char & c)
{
if (c == '!')
c = NOT;
else if (c == '*')
c = AND;
else if (c == '|')
c = OR;
else if (c == '^')
c = XOR;
else if (c == '(')
c = L_PAR;
else if (c == ')')
c = R_PAR;
else if (c == '\n')
c = END;
else
return false;
return true;
}
ValReturn valsPop()
{
if (vals.empty())
{
ValReturn rtn = {true, false};
error("ERROR: Empty value stack!");
return rtn;
}
ValReturn rtn = {false, vals.back()};
vals.pop_back();
return rtn;
}
bool opNot()
{
auto t = valsPop();
if (t.error)
return false;
vals.push_back(!t.data);
return true;
}
bool opAnd()
{
auto r = valsPop();
auto l = valsPop();
if (r.error || l.error)
return false;
vals.push_back(r.data & l.data);
return true;
}
bool opOr()
{
auto r = valsPop();
auto l = valsPop();
if (r.error || l.error)
return false;
vals.push_back(r.data | l.data);
return true;
}
bool opXor()
{
auto r = valsPop();
auto l = valsPop();
if (r.error || l.error)
return false;
vals.push_back(r.data ^ l.data);
return true;
}
bool opEnd()
{
auto t = valsPop();
if (t.error)
return false;
cout<< t.data << "\n";
if (vals.empty())
return true;
return error("ERROR: Value stack not empty at end of line!");
}
bool opLPar()
{
return error("ERROR: Unmatched left parenthesis!");
}
bool opRPar()
{
while(!ops.empty() && ops.back() != L_PAR)
{
if (!execute())
return false;
}
if (ops.empty())
{
return error("ERROR: Unmatched right parenthesis!");
}
ops.pop_back();
return true;
}
bool error(string error)
{
cout<< error << "\n";
return false;
}