Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "knuth.h"
- #include <stack>
- #include <utility>
- template <int val>
- static bool tk(int code) {
- return code == val;
- }
- static bool defined(int code) {
- return code > 1000;
- }
- static bool integer(int code) {
- return (501 <= code) && (code <= 1000);
- }
- std::vector<state> analyzer::states = {
- { 0, "<signal-program>", 1, nullptr, 0, 0 },
- { 1, "<program>", 0, tk<401>, 0, 0 },
- { 2, "", 44, nullptr, -1, 0 },
- { 3, "", 18, nullptr, 0, -1 },
- { 4, "", 0, tk<';'>, -1, 0 },
- { 5, "", 7, nullptr, -1, 0 },
- { 6, "", 0, tk<';'>, 1, 0 },
- { 7, "<block>", 11, nullptr, 0, -1 },
- { 8, "", 0, tk<403>, -1, 0 },
- { 9, "", 24, nullptr, -1, -1 },
- { 10, "", 0, tk<404>, 1, 0 },
- { 11, "<declarations>", 12, nullptr, 0, 0 },
- { 12, "<procedure-declarations>", 14, nullptr, 0, 0 },
- { 13, "", 12, nullptr, 0, 0 },
- { 14, "<procedure>", 0, tk<401>, 0, 1 },
- { 15, "", 43, nullptr, 0, 0 },
- { 16, "", 18, nullptr, -1, -1 },
- { 17, "", 0, tk<';'>, 1, 0 },
- { 18, "<parameters-list>", 0, tk<'('>, 0, 1 },
- { 19, "", 21, nullptr, 0, 0 },
- { 20, "", 0, tk<')'>, 1, 0 },
- { 21, "<identifiers-list>", 43, nullptr, 0, 0 },
- { 22, "", 0, tk<','>, 0, 1 },
- { 23, "", 21, nullptr, 0, 0 },
- { 24, "<statements-list>", 25, nullptr, 0, 0 },
- { 25, "", 27, nullptr, -1, 0 },
- { 26, "", 25, nullptr, 0, 0 },
- { 27, "<statement>", 28, nullptr, 0, 0 },
- { 28, "", 33, nullptr, 0, -1 },
- { 29, "", 30, nullptr, 0, 0 },
- { 30, "", 44, nullptr, -1, 0 },
- { 31, "", 36, nullptr, -1, -1 },
- { 32, "", 0, tk<';'>, 1, 0 },
- { 33, "", 34, nullptr, 0, 0 },
- { 34, "", 0, tk<402>, -1, 1 },
- { 35, "", 0, tk<';'>, 1, 0 },
- { 36, "<actual-arguments>", 0, tk<'('>, 0, 1 },
- { 37, "", 39, nullptr, 0, -1 },
- { 38, "", 0, tk<')'>, 1, 0 },
- { 39, "<actual-arguments-list>", 40, nullptr, 0, 0 },
- { 40, "", 46, nullptr, -1, 0 },
- { 41, "", 0, tk<','>, 0, 1 },
- { 42, "", 40, nullptr, 0, 0 },
- { 43, "<variable-identifier>", 45, nullptr, 0, 0 },
- { 44, "<procedure-identifier>", 45, nullptr, 0, 0 },
- { 45, "<identifier>", 0, defined, 1, 1 },
- { 46, "<unsigned-integer>", 0, integer, 1, 1 }
- };
- struct tree {
- tree* root;
- std::string name;
- std::vector<tree*> nodes;
- tree(tree* root, std::string name) : root(root), name(std::move(name)) {}
- };
- void print(tree* root, int prefix = 0) {
- printf("%*c%s\n", prefix, '\0', root->name.c_str());
- for (auto node : root->nodes) {
- print(node, prefix + 4);
- }
- }
- void analyzer::run(tstream tokens) {
- tokens.reset();
- std::stack<state> sp;
- size_t ip = 0;
- auto root = new tree(nullptr, "<root>");
- do {
- sp.push(states[ip]);
- if (!sp.top().buffer.empty()) {
- auto node = new tree(root, sp.top().buffer);
- root->nodes.push_back(node);
- root = node;
- }
- if (sp.top().code == 0) {
- bool accept = sp.top().accept(tokens.peek().type);
- if (!accept && (sp.top().af != 1)) {
- printf("error: %zu -> %s\n", sp.top().ip, tokens.peek().buffer.c_str());
- break;
- }
- if (accept) {
- root->nodes.push_back(new tree(root, tokens.get().buffer));
- }
- if ((accept ? sp.top().at : sp.top().af) == 1) {
- while (!sp.empty() && (accept ? sp.top().at : sp.top().af) != -1) {
- if (!sp.top().buffer.empty()) {
- root = root->root;
- if (root->nodes.back()->nodes.empty()) {
- delete root->nodes.back();
- root->nodes.pop_back();
- }
- }
- sp.pop();
- }
- }
- if (!sp.empty()) {
- ip = sp.top().ip + 1;
- if (sp.top().buffer.empty()) {
- sp.pop();
- }
- }
- } else {
- ip = sp.top().code;
- }
- } while (!sp.empty());
- print (root);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement