106 lines
2.1 KiB
C++
106 lines
2.1 KiB
C++
#include <stdio.h>
|
|
#include <string.h>
|
|
extern "C" {
|
|
#include <tree_sitter/api.h>
|
|
extern const TSLanguage * tree_sitter_c(void);
|
|
}
|
|
|
|
int tbtraverse(const char * const code) {
|
|
// init
|
|
TSParser * parser;
|
|
TSTree * tree;
|
|
TSTreeCursor cursor;
|
|
TSNode current_node;
|
|
TSNode previous_node;
|
|
|
|
parser = ts_parser_new();
|
|
|
|
ts_parser_set_language(parser, tree_sitter_c());
|
|
|
|
tree = ts_parser_parse_string(parser, NULL, code, strlen(code));
|
|
cursor = ts_tree_cursor_new(ts_tree_root_node(tree));
|
|
current_node = ts_tree_root_node(tree);
|
|
|
|
// meat
|
|
do {
|
|
current_node = ts_tree_cursor_current_node(&cursor);
|
|
|
|
const char * previous_node_type = NULL;
|
|
|
|
int tblen = ts_node_end_byte(current_node) - ts_node_start_byte(current_node);
|
|
char * tbtext = (char *)malloc(sizeof(char) * (tblen + 1));
|
|
memcpy(tbtext, code + ts_node_start_byte(current_node), tblen);
|
|
tbtext[tblen] = '\0';
|
|
|
|
// XXX INJECTION
|
|
|
|
if (!strcmp("function_definition", ts_node_type(current_node))) {
|
|
|
|
puts("ack");
|
|
puts(tbtext);
|
|
|
|
goto end;
|
|
}
|
|
|
|
|
|
if (!strcmp("number_literal", ts_node_type(current_node))) {
|
|
|
|
puts("++");
|
|
|
|
goto end;
|
|
}
|
|
|
|
|
|
|
|
end:
|
|
free(tbtext);
|
|
} while ([&] {
|
|
bool r = false;
|
|
previous_node = current_node;
|
|
|
|
if (ts_tree_cursor_goto_first_child(&cursor)
|
|
|| ts_tree_cursor_goto_next_sibling(&cursor)) {
|
|
r = true;
|
|
goto eval;
|
|
}
|
|
|
|
while (ts_tree_cursor_goto_parent(&cursor)) {
|
|
if (!strcmp(ts_node_type(current_node), "translation_unit")) {
|
|
r = false;
|
|
break;
|
|
}
|
|
|
|
if (ts_tree_cursor_goto_next_sibling(&cursor)) {
|
|
r = true;
|
|
}
|
|
|
|
eval:
|
|
if (!strcmp("function_definition", ts_node_type(previous_node))) {
|
|
puts("^^df");
|
|
|
|
goto end;
|
|
}
|
|
|
|
end:
|
|
if (r) { break; }
|
|
}
|
|
|
|
return r;
|
|
}());
|
|
|
|
// deinit
|
|
ts_tree_delete(tree);
|
|
ts_parser_delete(parser);
|
|
ts_tree_cursor_delete(&cursor);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// @BAKE g++ $@ $(pkg-config --cflags --libs tree-sitter tree-sitter-c) -ggdb
|
|
|
|
signed main() {
|
|
tbtraverse("int main() { return 0; }");
|
|
}
|
|
|