97 lines
2.1 KiB
C
97 lines
2.1 KiB
C
#include "../libs/tree-sitter-ruby/bindings/c/tree-sitter-ruby.h"
|
|
#include "../libs/tree-sitter/lib/include/tree_sitter/api.h"
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static void die(const char *msg) {
|
|
fprintf(stderr, "error: %s\n", msg);
|
|
exit(1);
|
|
}
|
|
|
|
static char *read_stdin(size_t *out_len) {
|
|
size_t cap = 4096, len = 0;
|
|
char *buf = (char *)malloc(cap);
|
|
if (!buf)
|
|
die("malloc failed");
|
|
size_t n;
|
|
while (!feof(stdin)) {
|
|
if (cap - len < 2048) {
|
|
cap *= 2;
|
|
char *tmp = (char *)realloc(buf, cap);
|
|
if (!tmp) {
|
|
free(buf);
|
|
die("realloc failed");
|
|
}
|
|
buf = tmp;
|
|
}
|
|
n = fread(buf + len, 1, cap - len, stdin);
|
|
len += n;
|
|
}
|
|
// ensure NUL-terminated for convenience
|
|
if (len == cap) {
|
|
char *tmp = (char *)realloc(buf, cap + 1);
|
|
if (!tmp) {
|
|
free(buf);
|
|
die("realloc term failed");
|
|
}
|
|
buf = tmp;
|
|
}
|
|
buf[len] = '\0';
|
|
if (out_len)
|
|
*out_len = len;
|
|
return buf;
|
|
}
|
|
|
|
static void walk(TSNode node, int depth) {
|
|
uint16_t sym = ts_node_symbol(node);
|
|
const char *type = ts_node_type(node);
|
|
for (int i = 0; i < depth; i++)
|
|
putchar(' ');
|
|
uint32_t n = ts_node_child_count(node);
|
|
printf("#define SYM_%s %u\n", type, sym);
|
|
for (uint32_t i = 0; i < n; i++) {
|
|
TSNode child = ts_node_child(node, i);
|
|
walk(child, depth + 2);
|
|
}
|
|
}
|
|
|
|
int main(void) {
|
|
size_t len = 0;
|
|
char *src = read_stdin(&len);
|
|
if (len == 0) {
|
|
fprintf(stderr,
|
|
"No input on stdin. Paste some Ruby code and press Ctrl-D.\n");
|
|
free(src);
|
|
return 1;
|
|
}
|
|
|
|
TSParser *parser = ts_parser_new();
|
|
if (!parser) {
|
|
free(src);
|
|
die("ts_parser_new failed");
|
|
}
|
|
|
|
if (!ts_parser_set_language(parser, tree_sitter_ruby())) {
|
|
ts_parser_delete(parser);
|
|
free(src);
|
|
die("ts_parser_set_language failed (is tree-sitter-ruby linked?)");
|
|
}
|
|
|
|
TSTree *tree = ts_parser_parse_string(parser, NULL, src, (uint32_t)len);
|
|
if (!tree) {
|
|
ts_parser_delete(parser);
|
|
free(src);
|
|
die("parse failed");
|
|
}
|
|
|
|
TSNode root = ts_tree_root_node(tree);
|
|
walk(root, 0);
|
|
|
|
ts_tree_delete(tree);
|
|
ts_parser_delete(parser);
|
|
free(src);
|
|
return 0;
|
|
}
|