#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace ovdl { struct AbstractSyntaxTree : SymbolIntern { AbstractSyntaxTree() = default; explicit AbstractSyntaxTree(std::size_t max_elements) : _symbol_interner(max_elements) {} symbol_type intern(const char* str, std::size_t length); symbol_type intern(std::string_view str); const char* intern_cstr(const char* str, std::size_t length); const char* intern_cstr(std::string_view str); symbol_interner_type& symbol_interner(); const symbol_interner_type& symbol_interner() const; template symbol_type intern(lexy::lexeme lexeme) { return intern(lexeme.begin(), lexeme.size()); } template const char* intern_cstr(lexy::lexeme lexeme) { return intern_cstr(lexeme.begin(), lexeme.size()); } protected: symbol_interner_type _symbol_interner; }; template RootNodeT> struct BasicAbstractSyntaxTree : AbstractSyntaxTree { using file_type = FileT; using root_node_type = RootNodeT; using node_type = typename file_type::node_type; BasicAbstractSyntaxTree() = default; explicit BasicAbstractSyntaxTree(file_type&& file) : AbstractSyntaxTree(file.size() * file.visit_buffer([](auto&& buffer) -> size_t { return sizeof(typename std::decay_t::char_type); })), _file { std::move(file) } {} template explicit BasicAbstractSyntaxTree(lexy::buffer&& buffer) : AbstractSyntaxTree(buffer.size() * sizeof(Encoding::char_type)), _file { std::move(buffer) } {} void set_location(const node_type* n, NodeLocation loc) { _file.set_location(n, loc); } NodeLocation location_of(const node_type* n) const { return _file.location_of(n); } root_node_type* root() { return _tree.root(); } const root_node_type* root() const { return _tree.root(); } file_type& file() { return _file; } const file_type& file() const { return _file; } template T* create(NodeLocation loc, Args&&... args) { auto node = _tree.template create(DRYAD_FWD(args)...); set_location(node, loc); return node; } template T* create(const char* begin, const char* end, Args&&... args) { return create(NodeLocation::make_from(begin, end), DRYAD_FWD(args)...); } void set_root(root_node_type* node) { _tree.set_root(node); } protected: dryad::tree _tree; file_type _file; }; }