2023-03-26 15:20:53 +03:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
// for clangd
|
|
|
|
|
#include "tree_sitter/api.h"
|
|
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
extern "C" const TSLanguage* tree_sitter_LANG();
|
2023-03-26 15:20:53 +03:00
|
|
|
|
|
|
|
|
namespace parser {
|
|
|
|
|
|
|
|
|
|
class ParseTree {
|
|
|
|
|
public:
|
|
|
|
|
class Node {
|
|
|
|
|
public:
|
2023-04-02 15:10:32 +03:00
|
|
|
Node() : uninitialized_(true) {
|
|
|
|
|
for (unsigned int& i : node_.context) {
|
|
|
|
|
i = 0;
|
|
|
|
|
}
|
|
|
|
|
node_.id = nullptr;
|
|
|
|
|
node_.tree = nullptr;
|
|
|
|
|
|
|
|
|
|
source_ = nullptr;
|
|
|
|
|
};
|
|
|
|
|
Node(const TSNode& node, const std::string* source) : uninitialized_(false), node_(node), source_(source) {}
|
2023-03-31 12:10:12 +03:00
|
|
|
|
|
|
|
|
std::string GetType() {
|
|
|
|
|
return ts_node_type(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<size_t, size_t> GetStartPoint() {
|
|
|
|
|
TSPoint point = ts_node_start_point(node_);
|
|
|
|
|
return {point.row, point.column};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<size_t, size_t> GetEndPoint() {
|
|
|
|
|
TSPoint point = ts_node_end_point(node_);
|
|
|
|
|
return {point.row, point.column};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string GetAsSExpression() {
|
|
|
|
|
return ts_node_string(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string GetValue() { // from source
|
|
|
|
|
size_t start = ts_node_start_byte(node_);
|
|
|
|
|
size_t end = ts_node_end_byte(node_);
|
2023-04-11 13:49:22 +03:00
|
|
|
return source_->substr(start, end - start);
|
2023-03-31 12:10:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsNull() {
|
|
|
|
|
return ts_node_is_null(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsNamed() {
|
|
|
|
|
return ts_node_is_named(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsMissing() {
|
|
|
|
|
return ts_node_is_missing(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsExtra() { // comments, etc.
|
|
|
|
|
return ts_node_is_extra(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HasError() {
|
|
|
|
|
return ts_node_has_error(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node NthChild(size_t n) {
|
|
|
|
|
return Node(ts_node_child(node_, n), source_);
|
|
|
|
|
}
|
2023-05-13 16:14:02 +03:00
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
size_t ChildCount() {
|
|
|
|
|
return ts_node_child_count(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node NthNamedChild(size_t n) {
|
|
|
|
|
return Node(ts_node_named_child(node_, n), source_);
|
|
|
|
|
}
|
|
|
|
|
size_t NamedChildCount() {
|
|
|
|
|
return ts_node_named_child_count(node_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node ChildByFieldName(const std::string& name) {
|
|
|
|
|
return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()), source_);
|
2023-05-13 16:14:02 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node PreviousSibling() {
|
|
|
|
|
return Node(ts_node_prev_sibling(node_), source_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node PreviousNamedSibling() {
|
|
|
|
|
return Node(ts_node_prev_named_sibling(node_), source_);
|
2023-03-31 12:10:12 +03:00
|
|
|
}
|
2023-03-26 15:20:53 +03:00
|
|
|
|
2023-04-11 13:49:22 +03:00
|
|
|
Node NextSibling() {
|
|
|
|
|
return Node(ts_node_next_sibling(node_), source_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Node NextNamedSibling() {
|
|
|
|
|
return Node(ts_node_next_named_sibling(node_), source_);
|
|
|
|
|
}
|
2023-03-26 15:20:53 +03:00
|
|
|
private:
|
2023-04-02 15:10:32 +03:00
|
|
|
bool uninitialized_;
|
2023-03-26 15:20:53 +03:00
|
|
|
TSNode node_;
|
2023-04-02 15:10:32 +03:00
|
|
|
const std::string* source_;
|
2023-03-26 15:20:53 +03:00
|
|
|
};
|
|
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
ParseTree(const std::string& source) : source_(source) {
|
|
|
|
|
TSParser* parser = ts_parser_new();
|
|
|
|
|
ts_parser_set_language(parser, tree_sitter_LANG());
|
|
|
|
|
|
|
|
|
|
tree_ = ts_parser_parse_string(
|
|
|
|
|
parser,
|
2023-04-02 15:10:32 +03:00
|
|
|
nullptr,
|
2023-03-31 12:10:12 +03:00
|
|
|
source_.c_str(),
|
|
|
|
|
source_.size());
|
2023-04-02 15:10:32 +03:00
|
|
|
|
|
|
|
|
ts_parser_delete(parser);
|
2023-03-31 12:10:12 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-02 15:10:32 +03:00
|
|
|
ParseTree(const ParseTree& parse_tree) : tree_(ts_tree_copy(parse_tree.tree_)), source_(parse_tree.source_) {}
|
|
|
|
|
|
2023-03-31 12:10:12 +03:00
|
|
|
Node GetRoot() const {
|
|
|
|
|
return Node(ts_tree_root_node(tree_), &source_);
|
|
|
|
|
}
|
2023-03-26 15:20:53 +03:00
|
|
|
|
2023-04-02 15:10:32 +03:00
|
|
|
~ParseTree() {
|
|
|
|
|
ts_tree_delete(tree_);
|
|
|
|
|
}
|
2023-05-05 11:59:02 +03:00
|
|
|
|
|
|
|
|
bool IsProperlyParsed() { // TODO: check
|
|
|
|
|
return !GetRoot().HasError();
|
|
|
|
|
}
|
2023-03-26 15:20:53 +03:00
|
|
|
private:
|
|
|
|
|
TSTree* tree_;
|
2023-03-31 12:10:12 +03:00
|
|
|
std::string source_; // for token value extraction
|
2023-03-26 15:20:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace parser
|