#include "tree_sitter/parser.h"
enum TokenType { NEWLINE, BLOCK_COMMENT };
void *tree_sitter_decl_external_scanner_create(void) { return NULL; }
void tree_sitter_decl_external_scanner_destroy(void *p) {}
unsigned tree_sitter_decl_external_scanner_serialize(void *p, char *b) { return 0; }
void tree_sitter_decl_external_scanner_deserialize(void *p, const char *b, unsigned n) {}
static bool scan_block_comment(TSLexer *lexer) {
lexer->advance(lexer, false);
if (lexer->lookahead != '*') return false;
lexer->advance(lexer, false);
unsigned depth = 1;
while (depth > 0) {
if (lexer->eof(lexer)) return false; int32_t c = lexer->lookahead;
lexer->advance(lexer, false);
if (c == '/' && lexer->lookahead == '*') { depth++; lexer->advance(lexer, false); }
else if (c == '*' && lexer->lookahead == '/') { depth--; lexer->advance(lexer, false); }
}
lexer->result_symbol = BLOCK_COMMENT;
lexer->mark_end(lexer);
return true;
}
bool tree_sitter_decl_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
if (valid_symbols[BLOCK_COMMENT] && lexer->lookahead == '/') {
return scan_block_comment(lexer);
}
if (!valid_symbols[NEWLINE]) return false;
bool saw_newline = false;
for (;;) {
int32_t c = lexer->lookahead;
if (c == '\n') {
saw_newline = true;
lexer->advance(lexer, false);
} else if (c == ' ' || c == '\t' || c == '\r') {
lexer->advance(lexer, saw_newline ? false : true);
} else {
break;
}
}
if (!saw_newline) return false;
lexer->result_symbol = NEWLINE;
lexer->mark_end(lexer);
return true;
}