150 lines
3.1 KiB
Plaintext
150 lines
3.1 KiB
Plaintext
%top{
|
|
#define _GNU_SOURCE
|
|
}
|
|
%{
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include <kvec.h>
|
|
#include <sds.h>
|
|
|
|
kvec_t(char *) query;
|
|
static sds buffer;
|
|
static sds query_string_buffer;
|
|
|
|
#define ECHOC(x) do { buffer = sdscatlen(buffer, &x, 1); } while(0)
|
|
#define ECHOS(x) do { buffer = sdscat(buffer, x); } while(0)
|
|
|
|
extern char * expand_c_query(void);
|
|
%}
|
|
identifier [a-zA-z][a-zA-z0-9_]*
|
|
|
|
%x IN_COMMENT IN_MULTILINE_COMMENT IN_STRING
|
|
%x IN_QUERY IN_QUERY_STRING
|
|
|
|
%option nodefault
|
|
%option noyywrap
|
|
%option nounput noinput
|
|
|
|
%option prefix="tbsp_c_"
|
|
%%
|
|
\/\/ {
|
|
ECHOS(yytext);
|
|
BEGIN IN_COMMENT;
|
|
}
|
|
\/\* {
|
|
ECHOS(yytext);
|
|
BEGIN IN_COMMENT;
|
|
}
|
|
\" {
|
|
BEGIN IN_STRING;
|
|
}
|
|
\$\$ {
|
|
BEGIN IN_QUERY;
|
|
}
|
|
.|\n {
|
|
ECHOS(yytext);
|
|
}
|
|
|
|
<IN_COMMENT>{
|
|
\n {
|
|
ECHOS(yytext);
|
|
BEGIN INITIAL;
|
|
}
|
|
. {
|
|
ECHOS(yytext);
|
|
}
|
|
}
|
|
|
|
<IN_MULTILINE_COMMENT>{
|
|
\*\/ {
|
|
ECHOS(yytext);
|
|
BEGIN INITIAL;
|
|
}
|
|
. {
|
|
ECHOS(yytext);
|
|
}
|
|
}
|
|
|
|
<IN_STRING>{
|
|
\\\" {
|
|
ECHOS(yytext);
|
|
}
|
|
\" {
|
|
ECHOS(yytext);
|
|
BEGIN INITIAL;
|
|
}
|
|
. {
|
|
ECHOS(yytext);
|
|
}
|
|
}
|
|
|
|
<IN_QUERY>{
|
|
\-\> { ; }
|
|
{identifier} {
|
|
kv_push(char *, query, strdup(yytext));
|
|
}
|
|
\" {
|
|
sdsfree(query_string_buffer);
|
|
query_string_buffer = sdsnew(yytext);
|
|
BEGIN IN_QUERY_STRING;
|
|
}
|
|
. {
|
|
char * expanded_query = expand_c_query();
|
|
ECHOS(expanded_query);
|
|
free(expanded_query);
|
|
|
|
ECHOS(yytext);
|
|
|
|
BEGIN INITIAL;
|
|
}
|
|
}
|
|
|
|
<IN_QUERY_STRING>{
|
|
\" {
|
|
query_string_buffer = sdscat(query_string_buffer, yytext);
|
|
kv_push(char *, query, strdup(query_string_buffer));
|
|
BEGIN IN_QUERY;
|
|
}
|
|
. {
|
|
query_string_buffer = sdscat(query_string_buffer, yytext);
|
|
}
|
|
}
|
|
|
|
%%
|
|
|
|
char * tbsp_c_expland_code(const char * const s) {
|
|
YY_BUFFER_STATE const b = yy_scan_string(s);
|
|
tbsp_c_lex();
|
|
tbsp_c__delete_buffer(b);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
// XXX this bleeds
|
|
char * expand_c_query(void) {
|
|
const char * const query_fmt = "ts_node_child_by_field_name(%s, %s, strlen(%s))";
|
|
char * r;
|
|
|
|
r = (char *)"tbnode";
|
|
for (int i = 0; i < kv_size(query); i++) {
|
|
asprintf(&r, query_fmt, r, kv_A(query, i), kv_A(query, i));
|
|
}
|
|
|
|
return r;
|
|
}
|
|
|
|
int tbsp_c_yy_init(void) {
|
|
kv_init(query);
|
|
buffer = sdsnew("");
|
|
query_string_buffer = sdsnew("");
|
|
return 0;
|
|
}
|
|
|
|
int tbsp_c_yy_deinit(void) {
|
|
tbsp_c__delete_buffer(YY_CURRENT_BUFFER);
|
|
sdsfree(buffer);
|
|
sdsfree(query_string_buffer);
|
|
return 0;
|
|
}
|