Advertisement
dark-s0ul

knuth

May 22nd, 2018
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.10 KB | None | 0 0
  1. #include "knuth.h"
  2. #include <stack>
  3. #include <utility>
  4.  
  5. template <int val>
  6. static bool tk(int code) {
  7.     return code == val;
  8. }
  9.  
  10. static bool defined(int code)  {
  11.     return code > 1000;
  12. }
  13.  
  14. static bool integer(int code)  {
  15.     return (501 <= code) && (code <= 1000);
  16. }
  17.  
  18. std::vector<state> analyzer::states = {
  19.     {  0,         "<signal-program>",  1, nullptr,  0,  0 },
  20.     {  1,                "<program>",  0, tk<401>,  0,  0 },
  21.     {  2,                         "", 44, nullptr, -1,  0 },
  22.     {  3,                         "", 18, nullptr,  0, -1 },
  23.     {  4,                         "",  0, tk<';'>, -1,  0 },
  24.     {  5,                         "",  7, nullptr, -1,  0 },
  25.     {  6,                         "",  0, tk<';'>,  1,  0 },
  26.     {  7,                  "<block>", 11, nullptr,  0, -1 },
  27.     {  8,                         "",  0, tk<403>, -1,  0 },
  28.     {  9,                         "", 24, nullptr, -1, -1 },
  29.     { 10,                         "",  0, tk<404>,  1,  0 },
  30.     { 11,           "<declarations>", 12, nullptr,  0,  0 },
  31.     { 12, "<procedure-declarations>", 14, nullptr,  0,  0 },
  32.     { 13,                         "", 12, nullptr,  0,  0 },
  33.     { 14,              "<procedure>",  0, tk<401>,  0,  1 },
  34.     { 15,                         "", 43, nullptr,  0,  0 },
  35.     { 16,                         "", 18, nullptr, -1, -1 },
  36.     { 17,                         "",  0, tk<';'>,  1,  0 },
  37.     { 18,        "<parameters-list>",  0, tk<'('>,  0,  1 },
  38.     { 19,                         "", 21, nullptr,  0,  0 },
  39.     { 20,                         "",  0, tk<')'>,  1,  0 },
  40.     { 21,       "<identifiers-list>", 43, nullptr,  0,  0 },
  41.     { 22,                         "",  0, tk<','>,  0,  1 },
  42.     { 23,                         "", 21, nullptr,  0,  0 },
  43.     { 24,        "<statements-list>", 25, nullptr,  0,  0 },
  44.     { 25,                         "", 27, nullptr, -1,  0 },
  45.     { 26,                         "", 25, nullptr,  0,  0 },
  46.     { 27,              "<statement>", 28, nullptr,  0,  0 },
  47.     { 28,                         "", 33, nullptr,  0, -1 },
  48.     { 29,                         "", 30, nullptr,  0,  0 },
  49.     { 30,                         "", 44, nullptr, -1,  0 },
  50.     { 31,                         "", 36, nullptr, -1, -1 },
  51.     { 32,                         "",  0, tk<';'>,  1,  0 },
  52.     { 33,                         "", 34, nullptr,  0,  0 },
  53.     { 34,                         "",  0, tk<402>, -1,  1 },
  54.     { 35,                         "",  0, tk<';'>,  1,  0 },
  55.     { 36,       "<actual-arguments>",  0, tk<'('>,  0,  1 },
  56.     { 37,                         "", 39, nullptr,  0, -1 },
  57.     { 38,                         "",  0, tk<')'>,  1,  0 },
  58.     { 39,  "<actual-arguments-list>", 40, nullptr,  0,  0 },
  59.     { 40,                         "", 46, nullptr, -1,  0 },
  60.     { 41,                         "",  0, tk<','>,  0,  1 },
  61.     { 42,                         "", 40, nullptr,  0,  0 },
  62.     { 43,    "<variable-identifier>", 45, nullptr,  0,  0 },
  63.     { 44,   "<procedure-identifier>", 45, nullptr,  0,  0 },
  64.     { 45,             "<identifier>",  0, defined,  1,  1 },
  65.     { 46,       "<unsigned-integer>",  0, integer,  1,  1 }
  66. };
  67.  
  68. struct tree {
  69.     tree* root;
  70.     std::string name;
  71.     std::vector<tree*> nodes;
  72.  
  73.     tree(tree* root, std::string name) : root(root), name(std::move(name)) {}
  74. };
  75.  
  76. void print(tree* root, int prefix = 0) {
  77.     printf("%*c%s\n", prefix, '\0', root->name.c_str());
  78.  
  79.     for (auto node : root->nodes) {
  80.         print(node, prefix + 4);
  81.     }
  82. }
  83.  
  84. void analyzer::run(tstream tokens) {
  85.     tokens.reset();
  86.  
  87.     std::stack<state> sp;
  88.  
  89.     size_t ip = 0;
  90.  
  91.     auto root = new tree(nullptr, "<root>");
  92.  
  93.     do {
  94.         sp.push(states[ip]);
  95.  
  96.         if (!sp.top().buffer.empty()) {
  97.             auto node = new tree(root, sp.top().buffer);
  98.             root->nodes.push_back(node);
  99.             root = node;
  100.         }
  101.  
  102.         if (sp.top().code == 0) {
  103.             bool accept = sp.top().accept(tokens.peek().type);
  104.  
  105.             if (!accept && (sp.top().af != 1)) {
  106.                 printf("error: %zu -> %s\n", sp.top().ip, tokens.peek().buffer.c_str());
  107.                 break;
  108.             }
  109.  
  110.             if (accept) {
  111.                 root->nodes.push_back(new tree(root, tokens.get().buffer));
  112.             }
  113.  
  114.             if ((accept ? sp.top().at : sp.top().af) == 1) {
  115.                 while (!sp.empty() && (accept ? sp.top().at : sp.top().af) != -1) {
  116.                     if (!sp.top().buffer.empty()) {
  117.                         root = root->root;
  118.  
  119.                         if (root->nodes.back()->nodes.empty()) {
  120.                             delete root->nodes.back();
  121.                             root->nodes.pop_back();
  122.                         }
  123.                     }
  124.                     sp.pop();
  125.                 }
  126.             }
  127.  
  128.             if (!sp.empty()) {
  129.                 ip = sp.top().ip + 1;
  130.                 if (sp.top().buffer.empty()) {
  131.                     sp.pop();
  132.                 }
  133.             }
  134.         } else {
  135.             ip = sp.top().code;
  136.         }
  137.     } while (!sp.empty());
  138.  
  139.     print (root);
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement