#include "tree_sitter/array.h"
#include "tree_sitter/parser.h"
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
enum TokenType {
TQ_STRING,
TQ_SIGIL_STRING,
ERROR_SENTINEL
};
static inline void advance(TSLexer* lexer) {
lexer->advance(lexer, false);
}
static inline void skip(TSLexer* lexer) {
lexer->advance(lexer, true);
}
static inline bool is_whitespace(TSLexer* lexer) {
return (
(lexer->lookahead >= 0x01 && lexer->lookahead <= 0x20) ||
(lexer->lookahead >= 0x80 && lexer->lookahead <= 0xA0));
}
bool tree_sitter_erlang_external_scanner_scan(
void* unused_payload,
TSLexer* lexer,
const bool* valid_symbols) {
(void)unused_payload;
if (valid_symbols[TQ_STRING] || valid_symbols[TQ_SIGIL_STRING]) {
while (is_whitespace(lexer)) {
skip(lexer);
}
bool is_sigil_string = false;
if (valid_symbols[TQ_SIGIL_STRING]) {
if (lexer->lookahead == '~') {
is_sigil_string = true;
advance(lexer);
switch (lexer->lookahead) {
case 's':
case 'S':
case 'b':
case 'B':
advance(lexer);
break;
case '"':
break;
default:
return false;
}
}
}
uint16_t delimiter_count = 0;
if (lexer->lookahead == '"') {
advance(lexer);
if (lexer->lookahead == '"') {
advance(lexer);
if (lexer->lookahead == '"') {
advance(lexer);
delimiter_count = 3;
while (lexer->lookahead == '"') {
delimiter_count++;
advance(lexer);
}
while (lexer->lookahead != '\n' && is_whitespace(lexer)) {
advance(lexer);
}
if (lexer->lookahead == '\n') {
advance(lexer);
} else {
return false;
}
for (;;) {
if (lexer->lookahead == '\n') {
advance(lexer);
while (lexer->lookahead != '\n' && is_whitespace(lexer)) {
advance(lexer);
}
uint16_t check = delimiter_count;
while (check > 0) {
if (lexer->lookahead != '"') {
break;
} else {
advance(lexer);
}
check--;
}
if (check <= 0) {
lexer->mark_end(lexer);
if (is_sigil_string) {
lexer->result_symbol = TQ_SIGIL_STRING;
} else {
lexer->result_symbol = TQ_STRING;
}
return true;
}
} else {
if (lexer->eof(lexer)) {
return false;
} else {
advance(lexer);
}
}
}
}
}
}
}
return false;
}
unsigned tree_sitter_erlang_external_scanner_serialize(
void* unused_payload,
char* unused_buffer) {
(void)unused_payload;
(void)unused_buffer;
return 0;
}
void tree_sitter_erlang_external_scanner_deserialize(
void* unused_payload,
const char* unused_buffer,
unsigned unused_length) {
(void)unused_payload;
(void)unused_buffer;
(void)unused_length;
}
void* tree_sitter_erlang_external_scanner_create() {
return 0;
}
void tree_sitter_erlang_external_scanner_destroy(void* unused_payload) {
(void)unused_payload;
}