1#include "tree_sitter/parser.h"
43#define OPERATOR_COUNT 20
46 "->",
".",
"&&",
"||",
"??",
"=",
"==",
47 "+",
"-",
"!",
"throws",
"rethrows",
"default",
"where",
48 "else",
"catch",
"as",
"as?",
"as!",
"async"};
124#define RESERVED_OP_COUNT 31
127 "/",
"=",
"-",
"+",
"!",
"*",
"%",
"<",
">",
"&",
"|",
128 "^",
"?",
"~",
".",
"..",
"->",
"/*",
"*/",
"+=",
"-=",
"*=",
129 "/=",
"%=",
">>",
"<<",
"++",
"--",
"===",
"...",
"..<"};
160#define NON_CONSUMING_CROSS_SEMI_CHAR_COUNT 3
207 buffer[0] = (hash_count >> 24) & 0xff;
208 buffer[1] = (hash_count >> 16) & 0xff;
209 buffer[2] = (hash_count >> 8) & 0xff;
210 buffer[3] = (hash_count) & 0xff;
221 uint32_t hash_count =
222 ((((uint32_t)buffer[0]) << 24) | (((uint32_t)buffer[1]) << 16) |
223 (((uint32_t)buffer[2]) << 8) | (((uint32_t)buffer[3])));
228static void advance(TSLexer *lexer) { lexer->advance(lexer,
false); }
231 return iswspace(character) || (((int32_t)
';') == character);
235 int32_t encountered = 0;
237 if (encountered_operator[op_idx]) {
247 if (encountered_reserved_ops[op_idx] == 2) {
257 bool is_first_char = !char_idx;
274 return is_first_char || first_char ==
'.';
279 return char_idx != 1 || first_char !=
'/';
281 if ((cur_char >= 0x00A1 && cur_char <= 0x00A7) || (cur_char == 0x00A9) ||
282 (cur_char == 0x00AB) || (cur_char == 0x00AC) || (cur_char == 0x00AE) ||
283 (cur_char >= 0x00B0 && cur_char <= 0x00B1) || (cur_char == 0x00B6) ||
284 (cur_char == 0x00BB) || (cur_char == 0x00BF) || (cur_char == 0x00D7) ||
285 (cur_char == 0x00F7) || (cur_char >= 0x2016 && cur_char <= 0x2017) ||
286 (cur_char >= 0x2020 && cur_char <= 0x2027) ||
287 (cur_char >= 0x2030 && cur_char <= 0x203E) ||
288 (cur_char >= 0x2041 && cur_char <= 0x2053) ||
289 (cur_char >= 0x2055 && cur_char <= 0x205E) ||
290 (cur_char >= 0x2190 && cur_char <= 0x23FF) ||
291 (cur_char >= 0x2500 && cur_char <= 0x2775) ||
292 (cur_char >= 0x2794 && cur_char <= 0x2BFF) ||
293 (cur_char >= 0x2E00 && cur_char <= 0x2E7F) ||
294 (cur_char >= 0x3001 && cur_char <= 0x3003) ||
295 (cur_char >= 0x3008 && cur_char <= 0x3020) || (cur_char == 0x3030)) {
297 }
else if ((cur_char >= 0x0300 && cur_char <= 0x036f) ||
298 (cur_char >= 0x1DC0 && cur_char <= 0x1DFF) ||
299 (cur_char >= 0x20D0 && cur_char <= 0x20FF) ||
300 (cur_char >= 0xFE00 && cur_char <= 0xFE0F) ||
301 (cur_char >= 0xFE20 && cur_char <= 0xFE2F) ||
302 (cur_char >= 0xE0100 && cur_char <= 0xE01EF)) {
303 return !is_first_char;
311 bool mark_end,
const int32_t prior_char,
316 possible_operators[op_idx] =
318 (!prior_char ||
OPERATORS[op_idx][0] == prior_char);
321 reserved_operators[op_idx] =
326 int32_t first_char = prior_char ? prior_char : lexer->lookahead;
327 int32_t last_examined_char = first_char;
329 int32_t str_idx = prior_char ? 1 : 0;
330 int32_t full_match = -1;
333 if (!possible_operators[op_idx]) {
337 if (
OPERATORS[op_idx][str_idx] ==
'\0') {
342 switch (lexer->lookahead) {
370 if (iswalnum(lexer->lookahead) &&
375 if (!iswspace(lexer->lookahead) &&
382 lexer->mark_end(lexer);
386 possible_operators[op_idx] =
false;
390 if (
OPERATORS[op_idx][str_idx] != lexer->lookahead) {
391 possible_operators[op_idx] =
false;
397 if (!reserved_operators[op_idx]) {
402 reserved_operators[op_idx] = 0;
406 if (
RESERVED_OPS[op_idx][str_idx] != lexer->lookahead) {
407 reserved_operators[op_idx] = 0;
412 reserved_operators[op_idx] = 2;
417 possible_custom_operator =
418 possible_custom_operator &&
422 if (encountered_ops == 0) {
423 if (!possible_custom_operator) {
425 }
else if (mark_end && full_match == -1) {
426 lexer->mark_end(lexer);
430 last_examined_char = lexer->lookahead;
431 lexer->advance(lexer,
false);
434 if (encountered_ops == 0 &&
440 if (full_match != -1) {
446 if (suppressing_symbols) {
447 for (uint64_t suppressor = 0; suppressor <
TOKEN_COUNT; suppressor++) {
448 if (!(suppressing_symbols & 1 << suppressor)) {
453 if (valid_symbols[suppressor]) {
463 if ((last_examined_char !=
'<' || iswspace(lexer->lookahead)) && mark_end) {
464 lexer->mark_end(lexer);
474 const bool *valid_symbols,
bool mark_end,
476 if (lexer->lookahead !=
'/') {
482 if (lexer->lookahead !=
'*') {
488 bool after_star =
false;
489 unsigned nesting_depth = 1;
491 switch (lexer->lookahead) {
503 if (nesting_depth == 0) {
505 lexer->mark_end(lexer);
513 if (lexer->lookahead ==
'*') {
528 const bool *valid_symbols,
535 if (lookahead ==
';') {
538 lexer->advance(lexer,
false);
544 lexer->advance(lexer,
true);
546 lexer->mark_end(lexer);
549 (lookahead ==
'\n' || lookahead ==
'\r')) {
556 bool has_seen_single_comment =
false;
557 while (lexer->lookahead ==
'/') {
563 any_comment =
eat_comment(lexer, valid_symbols,
false,
564 &multiline_comment_result);
570 if (!has_seen_single_comment) {
571 lexer->mark_end(lexer);
572 *symbol_result = multiline_comment_result;
581 }
else if (lexer->lookahead ==
'/') {
588 has_seen_single_comment =
true;
589 while (lexer->lookahead !=
'\n' && lexer->lookahead !=
'\0') {
590 lexer->advance(lexer,
true);
592 }
else if (iswspace(lexer->lookahead)) {
601 while (iswspace(lexer->lookahead)) {
604 lexer->advance(lexer,
true);
611 false,
'\0', &operator_result);
642#define DIRECTIVE_COUNT 4
651 possible_directives[dir_idx] =
true;
655 int32_t full_match = -1;
658 if (!possible_directives[dir_idx]) {
662 uint8_t expected_char =
DIRECTIVES[dir_idx][str_idx];
663 if (expected_char ==
'\0') {
664 full_match = dir_idx;
665 lexer->mark_end(lexer);
668 if (expected_char != lexer->lookahead) {
669 possible_directives[dir_idx] =
false;
674 uint8_t match_count = 0;
676 if (possible_directives[dir_idx]) {
681 if (match_count == 0) {
685 lexer->advance(lexer,
false);
689 if (full_match == -1) {
698 const bool *valid_symbols,
703 }
else if (hash_count == 0) {
705 while (lexer->lookahead ==
'#') {
710 if (hash_count == 0) {
714 if (lexer->lookahead ==
'"') {
716 }
else if (hash_count == 1) {
717 lexer->mark_end(lexer);
740 while (lexer->lookahead !=
'\0') {
741 uint8_t last_char =
'\0';
746 while (lexer->lookahead !=
'#' && lexer->lookahead !=
'\0') {
747 last_char = lexer->lookahead;
749 if (last_char !=
'\\' || lexer->lookahead ==
'\\') {
755 lexer->mark_end(lexer);
760 uint32_t current_hash_count = 0;
761 while (lexer->lookahead ==
'#' && current_hash_count < hash_count) {
762 current_hash_count += 1;
771 if (current_hash_count == hash_count) {
772 if (last_char ==
'\\' && lexer->lookahead ==
'(') {
778 }
else if (last_char ==
'"') {
781 lexer->mark_end(lexer);
794 const bool *valid_symbols) {
803 lexer->result_symbol = ws_result;
823 lexer->mark_end(lexer);
824 lexer->result_symbol = comment_result;
841 lexer->result_symbol = operator_result;
843 lexer->mark_end(lexer);
849 lexer->result_symbol = ws_result;
857 bool saw_raw_str_part =
859 if (saw_raw_str_part) {
860 lexer->result_symbol = raw_str_result;
void tree_sitter_swift_external_scanner_destroy(void *payload)
void tree_sitter_swift_external_scanner_deserialize(void *payload, const char *buffer, unsigned length)
static enum ParseDirective eat_comment(TSLexer *lexer, const bool *valid_symbols, bool mark_end, enum TokenType *symbol_result)
static int32_t encountered_op_count(bool *encountered_operator)
void * tree_sitter_swift_external_scanner_create()
static void advance(TSLexer *lexer)
void tree_sitter_swift_external_scanner_reset(void *payload)
#define NON_CONSUMING_CROSS_SEMI_CHAR_COUNT
static enum ParseDirective eat_whitespace(TSLexer *lexer, const bool *valid_symbols, enum TokenType *symbol_result)
const uint32_t NON_CONSUMING_CROSS_SEMI_CHARS[NON_CONSUMING_CROSS_SEMI_CHAR_COUNT]
const char * RESERVED_OPS[RESERVED_OP_COUNT]
ParseDirective
All possible results of having performed some sort of parsing.
@ CONTINUE_PARSING_NOTHING_FOUND
@ STOP_PARSING_NOTHING_FOUND
@ STOP_PARSING_END_OF_FILE
@ STOP_PARSING_TOKEN_FOUND
@ CONTINUE_PARSING_SLASH_CONSUMED
@ CONTINUE_PARSING_TOKEN_FOUND
const uint64_t OP_SYMBOL_SUPPRESSOR[OPERATOR_COUNT]
static bool is_legal_custom_operator(int32_t char_idx, int32_t first_char, int32_t cur_char)
bool tree_sitter_swift_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols)
static bool eat_raw_str_part(struct ScannerState *state, TSLexer *lexer, const bool *valid_symbols, enum TokenType *symbol_result)
@ RAW_STR_CONTINUING_INDICATOR
@ NIL_COALESCING_OPERATOR
unsigned tree_sitter_swift_external_scanner_serialize(void *payload, char *buffer)
static bool should_treat_as_wspace(int32_t character)
static enum TokenType find_possible_compiler_directive(TSLexer *lexer)
static bool is_cross_semi_token(enum TokenType op)
const char * OPERATORS[OPERATOR_COUNT]
enum TokenType OP_SYMBOLS[OPERATOR_COUNT]
const char * DIRECTIVES[OPERATOR_COUNT]
static bool any_reserved_ops(uint8_t *encountered_reserved_ops)
enum IllegalTerminatorGroup OP_ILLEGAL_TERMINATORS[OPERATOR_COUNT]
static bool eat_operators(TSLexer *lexer, const bool *valid_symbols, bool mark_end, const int32_t prior_char, enum TokenType *symbol_result)
#define RESERVED_OP_COUNT
enum TokenType DIRECTIVE_SYMBOLS[DIRECTIVE_COUNT]
uint32_t ongoing_raw_str_hash_count