#include #include #include using namespace std; #define STRINGIFY(msg) dynamic_cast(&(std::stringstream() << msg))->str() typedef vector OpStack; typedef vector 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; }