Want more features on Pastebin? Sign Up, it's FREE!
Guest

Daily Programmer 105 Intermediate

By: a guest on Oct 21st, 2012  |  syntax: C++  |  size: 3.27 KB  |  views: 65  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <vector>
  2. #include <iostream>
  3. #include <sstream>
  4.  
  5. using namespace std;
  6.  
  7. #define STRINGIFY(msg) dynamic_cast<std::stringstream *>(&(std::stringstream() << msg))->str()
  8.  
  9. typedef vector<char> OpStack;
  10. typedef vector<bool> ValStack;
  11.  
  12. OpStack ops;
  13. ValStack vals;
  14.  
  15. enum Operation : char
  16. {
  17.         NOT,
  18.         AND,
  19.         OR,
  20.         XOR,
  21.         R_PAR,
  22.         L_PAR,
  23.         END,
  24. };
  25.  
  26. bool opNot();
  27. bool opAnd();
  28. bool opOr();
  29. bool opXor();
  30. bool opRPar();
  31. bool opLPar();
  32. bool opEnd();
  33.  
  34. bool (*functions[])() = {opNot, opAnd, opOr, opXor, opRPar, opLPar, opEnd};
  35.  
  36. bool parseSymbol(char c);
  37. bool translate(char & c);
  38. bool addOp(char c);
  39. bool execute();
  40.  
  41. bool error(string error);
  42.  
  43. struct ValReturn{bool error; bool data;};
  44. ValReturn valsPop();
  45.  
  46. int main()
  47. {
  48.         while(cin.peek() != 'e')
  49.         {
  50.                 parseSymbol(cin.get());
  51.         }
  52.         cin.ignore();
  53. }
  54.  
  55. bool parseSymbol(char c)
  56. {
  57.         if (c == 'T' || c == '1')
  58.                 vals.push_back(true);
  59.         else if (c == 'F' || c == '0')
  60.                 vals.push_back(false);
  61.         else if (translate(c))
  62.         {
  63.                 if (!addOp(c))
  64.                 {
  65.                         ops.clear();
  66.                         vals.clear();
  67.                 }
  68.         }
  69.         else
  70.                 return error(STRINGIFY("ERROR: Unknown symbol: '" << c << "'"));
  71.         return true;
  72. }
  73.  
  74. bool addOp(char c)
  75. {
  76.         while (!ops.empty() && ops.back() < c && c != L_PAR)
  77.         {
  78.                 if (!execute())
  79.                         return false;
  80.         }
  81.         ops.push_back(c);
  82.         if (c == END)
  83.         {
  84.                 if (!execute())
  85.                         return false;
  86.                 if (!ops.empty())
  87.                 {
  88.                         return error("ERROR: Operator stack not empty at end of line!");
  89.                 }
  90.         }
  91.         return true;
  92. }
  93.  
  94. bool execute()
  95. {
  96.         if (ops.empty())
  97.         {
  98.                 return error("ERROR: Empty op stack!");
  99.         }
  100.         char op = ops.back();
  101.         ops.pop_back();
  102.         return functions[op]();
  103. }
  104.  
  105. bool translate(char & c)
  106. {
  107.         if (c == '!')
  108.                 c = NOT;
  109.         else if (c == '*')
  110.                 c = AND;
  111.         else if (c == '|')
  112.                 c = OR;
  113.         else if (c == '^')
  114.                 c = XOR;
  115.         else if (c == '(')
  116.                 c = L_PAR;
  117.         else if (c == ')')
  118.                 c = R_PAR;
  119.         else if (c == '\n')
  120.                 c = END;
  121.         else
  122.                 return false;
  123.         return true;
  124. }
  125.  
  126. ValReturn valsPop()
  127. {
  128.         if (vals.empty())
  129.         {
  130.                 ValReturn rtn = {true, false};
  131.                 error("ERROR: Empty value stack!");
  132.                 return rtn;
  133.         }
  134.         ValReturn rtn = {false, vals.back()};
  135.         vals.pop_back();
  136.         return rtn;
  137. }
  138.  
  139. bool opNot()
  140. {
  141.         auto t = valsPop();
  142.         if (t.error)
  143.                 return false;
  144.         vals.push_back(!t.data);
  145.         return true;
  146. }
  147.  
  148. bool opAnd()
  149. {
  150.         auto r = valsPop();
  151.         auto l = valsPop();
  152.         if (r.error || l.error)
  153.                 return false;
  154.         vals.push_back(r.data & l.data);
  155.         return true;
  156. }
  157.  
  158. bool opOr()
  159. {
  160.         auto r = valsPop();
  161.         auto l = valsPop();
  162.         if (r.error || l.error)
  163.                 return false;
  164.         vals.push_back(r.data | l.data);
  165.         return true;
  166. }
  167.  
  168. bool opXor()
  169. {
  170.         auto r = valsPop();
  171.         auto l = valsPop();
  172.         if (r.error || l.error)
  173.                 return false;
  174.         vals.push_back(r.data ^ l.data);
  175.         return true;
  176. }
  177.  
  178. bool opEnd()
  179. {
  180.         auto t = valsPop();
  181.         if (t.error)
  182.                 return false;
  183.         cout<< t.data << "\n";
  184.         if (vals.empty())
  185.                 return true;
  186.         return error("ERROR: Value stack not empty at end of line!");
  187. }
  188.  
  189. bool opLPar()
  190. {
  191.         return error("ERROR: Unmatched left parenthesis!");
  192. }
  193.  
  194. bool opRPar()
  195. {
  196.         while(!ops.empty() && ops.back() != L_PAR)
  197.         {
  198.                 if (!execute())
  199.                         return false;
  200.         }
  201.         if (ops.empty())
  202.         {
  203.                 return error("ERROR: Unmatched right parenthesis!");
  204.         }
  205.         ops.pop_back();
  206.         return true;
  207. }
  208.  
  209. bool error(string error)
  210. {
  211.         cout<< error << "\n";
  212.         return false;
  213. }
clone this paste RAW Paste Data