Interpreter.cpp 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #include <stdio.h>
  2. /*
  3. * C++ Design Patterns: INTERPRETER
  4. * http://www.plantuml.com/plantuml/uml/XL7Dpjem4BpxALRg0IXre_OOHH6bui058SIzseHjiEgVQEqWKCi3zJdwOdK2-OBqWU93ifuPxux72n-GGsEqI2QmtknNk-rk5RymIKHSfKRluRjMPCFRpjb0vm2_1SGb8RXVPEzrpUg4WNuOh3ja3fx2LDcRw1F4gd1Ep-vazK3E8EquSHL2nGdy4qk2RuKFZ6LOdMicxvMpzxaVe1D5D4ndujgRsnCRPL6_qm_U1h_pnnwGzZSRkcqYCDxmmUENrzJNiP57TI0WKuSB6385iHUYppgJ_IFSVY1b_YGRyIIkx8-KGooZqlxEusefFxuG2-i20SRyRdbaHPwLJZjEsLrGBtL3-RgFWJXBEZBFaYBlzVjBJMaBm9AEU5AEKNVSDewZ036gmx-_9IicQ2n1nMWCjhlQDHoXJgpHLbWHj0Scolg0jbJ4u9qTte4Q_Yp87g1rBHQnQep-3m00
  5. *
  6. */
  7. #include <iostream>
  8. #include <unordered_map>
  9. /*
  10. * Simple Interpreter example:
  11. * (digit+digit) => digit
  12. * (|+|digit|) = terminal
  13. * exemple : (9 = non-terminal
  14. * context : 9 -> true, )->true, (->false, (digit->false, digit)->true, digit+->false, +digit->false
  15. *
  16. */
  17. class Context {
  18. public:
  19. typedef char token;
  20. enum class std_token:token{digit='9',open_bracket='(', close_bracket=')', plus_symbol='+'};
  21. void set(std_token var, bool value) {
  22. maps.insert(std::make_pair(var, value));
  23. }
  24. char get(std_token var) {
  25. return maps[var];
  26. }
  27. private:
  28. std::unordered_map<std_token, bool> maps;
  29. };
  30. class AbstractExpression {
  31. public:
  32. virtual ~AbstractExpression() {}
  33. virtual bool interpret(Context* const context) = 0;
  34. };
  35. class TerminalExpression : public AbstractExpression {
  36. public:
  37. TerminalExpression(Context::std_token token) : private_token(token) {}
  38. ~TerminalExpression() {}
  39. bool interpret(Context* const context) {
  40. return context->get(private_token);
  41. }
  42. private:
  43. Context::std_token private_token;
  44. };
  45. class NonTerminalExpression : public AbstractExpression {
  46. public:
  47. NonTerminalExpression(AbstractExpression* f, AbstractExpression* s)
  48. : first(f), second(s) {}
  49. ~NonTerminalExpression() {
  50. if (first) delete first;
  51. if (second) delete second;
  52. }
  53. bool interpret(Context* const context) {
  54. return first->interpret(context) && second->interpret(context);
  55. }
  56. private:
  57. AbstractExpression* first;
  58. AbstractExpression* second;
  59. };
  60. int main() {
  61. Context context;
  62. //define way "basic" token property
  63. context.set(Context::std_token::close_bracket, true);
  64. context.set(Context::std_token::digit, true);
  65. context.set(Context::std_token::open_bracket, false);
  66. context.set(Context::std_token::plus_symbol, false);
  67. AbstractExpression* expressionCloseBracket = new TerminalExpression(Context::std_token::close_bracket); // )
  68. AbstractExpression* expressionOpenBracket = new TerminalExpression(Context::std_token::open_bracket); // (
  69. AbstractExpression* expressionDigit = new TerminalExpression(Context::std_token::digit); // 9
  70. AbstractExpression* expressionPlus = new TerminalExpression(Context::std_token::plus_symbol); // +
  71. AbstractExpression* expressionOpenBracketDigit = new NonTerminalExpression(expressionOpenBracket, expressionDigit); // (9
  72. AbstractExpression* expressionDigitCloseBracket = new NonTerminalExpression(expressionDigit, expressionCloseBracket); // 9)
  73. AbstractExpression* expressionDigitPlus = new NonTerminalExpression(expressionDigit, expressionPlus); // 9+
  74. AbstractExpression* expressionPlusDigit = new NonTerminalExpression(expressionPlus, expressionDigit); // +9
  75. std::cout << "( -> " << expressionOpenBracket->interpret(&context) << std::endl;
  76. std::cout << "9 -> " << expressionDigit->interpret(&context) << std::endl;
  77. std::cout << "+ -> " << expressionPlus->interpret(&context) << std::endl;
  78. std::cout << "(9 -> " << expressionOpenBracketDigit->interpret(&context) << std::endl;
  79. std::cout << "9+ -> " << expressionDigitPlus->interpret(&context) << std::endl;
  80. std::cout << "+9 -> " << expressionPlusDigit->interpret(&context) << std::endl;
  81. std::cout << "9) -> " << expressionDigitCloseBracket->interpret(&context) << std::endl;
  82. }