#include "tree_sitter/parser.h"
#include <string.h>
enum TokenType {
DOLLAR_QUOTED_STRING,
};
void *tree_sitter_postgres_external_scanner_create(void) { return NULL; }
void tree_sitter_postgres_external_scanner_destroy(void *payload) { (void)payload; }
unsigned tree_sitter_postgres_external_scanner_serialize(void *payload, char *buffer) {
(void)payload; (void)buffer; return 0;
}
void tree_sitter_postgres_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
(void)payload; (void)buffer; (void)length;
}
static bool is_tag_start_char(int c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
c == '_' || c >= 0x80;
}
static bool is_tag_char(int c) {
return is_tag_start_char(c) || (c >= '0' && c <= '9');
}
static void skip_whitespace(TSLexer *lexer) {
while (lexer->lookahead == ' ' || lexer->lookahead == '\t' ||
lexer->lookahead == '\n' || lexer->lookahead == '\r') {
lexer->advance(lexer, true);
}
}
bool tree_sitter_postgres_external_scanner_scan(
void *payload, TSLexer *lexer, const bool *valid_symbols
) {
(void)payload;
if (!valid_symbols[DOLLAR_QUOTED_STRING]) return false;
skip_whitespace(lexer);
if (lexer->lookahead != '$') return false;
lexer->advance(lexer, false);
char tag[64];
int tag_len = 0;
if (is_tag_start_char(lexer->lookahead)) {
do {
if (tag_len >= 63) return false;
tag[tag_len++] = (char)lexer->lookahead;
lexer->advance(lexer, false);
} while (is_tag_char(lexer->lookahead));
}
if (lexer->lookahead != '$') return false;
lexer->advance(lexer, false);
while (lexer->lookahead != 0) {
if (lexer->lookahead == '$') {
lexer->advance(lexer, false);
int i = 0;
while (i < tag_len && lexer->lookahead == (unsigned char)tag[i]) {
lexer->advance(lexer, false);
i++;
}
if (i == tag_len && lexer->lookahead == '$') {
lexer->advance(lexer, false);
lexer->result_symbol = DOLLAR_QUOTED_STRING;
return true;
}
continue;
}
lexer->advance(lexer, false);
}
return false;
}