Advertisement
cxzuk

Concrete Syntax Tree node

Jul 3rd, 2020
1,221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.97 KB | None | 0 0
  1. #pragma once
  2. #include "node.hpp"
  3. #include "lexer.hpp"
  4. #include <map>
  5. #include <vector>
  6. #include <memory>
  7.  
  8. // TODO: If we didn't use token_type in the template, we could most likely remove the #include to the lexer.
  9.  
  10. class scope_t {
  11.     std::vector<std::map<std::string const, node* const>> scope;
  12. public:
  13.     std::map<std::string const, node* const>& add_scope() {
  14.         scope.emplace_back();
  15.         return scope.back();
  16.     }
  17.     inline void pop_scope() {
  18.         scope.pop_back();
  19.     }
  20.  
  21.     inline void add_symbol(node* const symbol) {
  22.         assert(scope.size() != 0);
  23.         //std::cout << "Adding variable: " << symbol->name() << "\n";
  24.         scope.back().emplace( std::make_pair(symbol->name(), symbol) );
  25.     }
  26.  
  27.     const std::optional<node * const> find(const std::string& symbol) {
  28.         for (auto i = scope.begin(); i != scope.end(); ++i) {
  29.             if (auto fres = i->find(symbol); fres != i->end()) {
  30.                 return fres->second;
  31.             }
  32.         }
  33.         return std::nullopt;
  34.     }
  35. };
  36.  
  37. class branch_node: public node {
  38. protected:
  39.     std::multimap< std::string, node* const> index; // Symbol Table!
  40.     std::vector<std::unique_ptr<node>> children;
  41.     std::vector<std::string> semantic_errors;
  42.     // --- Symbol Table Functions ---
  43.     inline void insert(std::vector<token> const& input);
  44.     inline node& insert(std::vector<token> const& input, std::string const& symbol_name);
  45.     inline void insert(std::unique_ptr<node>&& input);
  46.     inline node& insert(std::unique_ptr<node>&& input, std::string const& symbol_name);
  47.  
  48.     // --- Parsing DSL ---
  49.     template<token_type T> // From token_type
  50.     inline void match(lexer& tokens, std::string const& symbol_name) {
  51.         tokens.peek_for(T);
  52.         insert( tokens.advance(), symbol_name );
  53.     }/*
  54.     template<token_type T> // From token_type
  55.     void match(lexer& tokens, std::vector<token>& symbol_ref) {
  56.         tokens.peek_for(T);
  57.         symbol_ref = tokens.advance();
  58.         return;
  59.     }*/
  60.     template<token_type T> // From token_type
  61.     inline void match(lexer& input) {
  62.         input.peek_for(T);
  63.         insert( input.advance() );
  64.     }
  65.     template<typename T> // Consume node using class constructor
  66.     inline void match(lexer& input, std::string const& symbol_name = "") {
  67.         insert( std::make_unique<T>(input) , symbol_name );
  68.     }
  69.     using factory = std::unique_ptr<node>(*)(lexer&, int);
  70.     template<factory F> // TODO: THIS NEEDS VARGS.
  71.     inline void match(lexer& tokens, std::string const& rolename = "", int min_bp = 0) {
  72.         insert(F(tokens, min_bp), rolename);
  73.     }
  74.     // TODO: Create a "Create Error Node" function instead.
  75.     inline void reset() {
  76.         children.clear();
  77.         index.clear();
  78.     }
  79. public:
  80.     inline void add_error(const std::string& msg) final {
  81.         semantic_errors.push_back(msg);
  82.     }
  83.  
  84.     // TODO: Code smells?
  85.     std::string value() const override { throw std::runtime_error("Can't get value of a parse node!"); };
  86.  
  87.     // --- Symbol Table Lookup ---
  88.     std::vector<node*> operator[](std::string const& lookup) const final;
  89.  
  90.     void check_for_errors(scope_t&) override;
  91.  
  92.     std::string print() const override;
  93.     int line_number() const override;
  94.     int column() const override;
  95.     int length() const override;
  96.     std::string toTree() const override;
  97.     std::string asHTML() const override;
  98. };
  99.  
  100. class syntax_error_node: public branch_node {
  101.     std::string error_msg;
  102.     int error_offset;
  103. public:
  104.     syntax_error_node(lexer& input, token_type recovery, std::string const& msg, std::vector<token>::iterator const& saved_pos);
  105.     syntax_error_node(lexer& input, std::vector<token_type> const& recovery, std::string const& msg, std::vector<token>::iterator const& saved_pos);
  106.     std::string print() const final;
  107.  
  108.     void check_for_errors(scope_t&) final;
  109.  
  110.     std::string asHTML() const final {
  111.         std::string result = "<span class='syntax_error' title='" + error_msg + "'>";
  112.         for(const auto& c: children) {
  113.             result += c->asHTML();
  114.         }
  115.         result += "</span>";
  116.         return result;
  117.     }
  118. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement