queries c.h c.scm cpp.h cpp.scm cuda.h cuda.scm glsl.h glsl.scm go.h go.scm javascript.h javascript.scm kotlin.h kotlin.scm lua.h lua.scm odin.h odin.scm php.h php.scm python.h python.scm rust.h rust.scm tcl.h tcl.scm zig.h zig.scm
tests
depth_test
sub level1.c
level0.c
test.c test.cpp test.cu test.cuh test.glsl test.go test.js test.kt test.lua test.odin test.php test.py test.rs test.tcl test.zig
vendor
tree-sitter
lib
include
tree_sitter api.h parser.h
src
unicode ICU_SHA LICENSE README.md ptypes.h umachine.h urename.h utf.h utf16.h utf8.h
alloc.c alloc.h array.h atomic.h clock.h error_costs.h get_changed_ranges.c get_changed_ranges.h host.h language.c language.h length.h lexer.c lexer.h lib.c node.c parser.c point.h query.c reduce_action.h reusable_node.h stack.c stack.h subtree.c subtree.h tree.c tree.h tree_cursor.c tree_cursor.h unicode.h
LICENSE Makefile
tree-sitter-c
src
tree_sitter parser.h
grammar.json node-types.json parser.c
LICENSE Makefile
tree-sitter-cpp
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-cuda
src
tree_sitter alloc.h array.h parser.h runtime.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-glsl
src
tree_sitter alloc.h array.h parser.h runtime.h
grammar.json node-types.json parser.c
LICENSE Makefile
tree-sitter-go
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c
LICENSE Makefile
tree-sitter-javascript
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-kotlin
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-lua
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE.md Makefile
tree-sitter-odin
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-php
src
common common.mak define-grammar.js scanner.h
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-python
src
tree_sitter parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-rust
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-tcl
src
tree_sitter parser.h
grammar.json node-types.json parser.c scanner.c
LICENSE Makefile
tree-sitter-template Makefile
tree-sitter-zig
src
tree_sitter alloc.h array.h parser.h
grammar.json node-types.json parser.c
LICENSE Makefile
.clang-format .gitattributes .gitignore LICENSE Makefile README.md abicheck.c compile_flags.txt file.c file.h list.c list.h main.c tests.sh tpool.c tpool.h
vendor/tree-sitter-cuda/src/scanner.c raw
  1#include "tree_sitter/alloc.h"
  2#include "tree_sitter/parser.h"
  3
  4#include <assert.h>
  5#include <string.h>
  6#include <wctype.h>
  7
  8enum TokenType { RAW_STRING_DELIMITER, RAW_STRING_CONTENT };
  9
 10/// The spec limits delimiters to 16 chars
 11#define MAX_DELIMITER_LENGTH 16
 12
 13typedef struct {
 14    uint8_t delimiter_length;
 15    wchar_t delimiter[MAX_DELIMITER_LENGTH];
 16} Scanner;
 17
 18static inline void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
 19
 20static inline void reset(Scanner *scanner) {
 21    scanner->delimiter_length = 0;
 22    memset(scanner->delimiter, 0, sizeof scanner->delimiter);
 23}
 24
 25/// Scan the raw string delimiter in R"delimiter(content)delimiter"
 26static bool scan_raw_string_delimiter(Scanner *scanner, TSLexer *lexer) {
 27    if (scanner->delimiter_length > 0) {
 28        // Closing delimiter: must exactly match the opening delimiter.
 29        // We already checked this when scanning content, but this is how we
 30        // know when to stop. We can't stop at ", because R"""hello""" is valid.
 31        for (int i = 0; i < scanner->delimiter_length; ++i) {
 32            if (lexer->lookahead != scanner->delimiter[i]) {
 33                return false;
 34            }
 35            advance(lexer);
 36        }
 37        reset(scanner);
 38        return true;
 39    }
 40
 41    // Opening delimiter: record the d-char-sequence up to (.
 42    // d-char is any basic character except parens, backslashes, and spaces.
 43    for (;;) {
 44        if (scanner->delimiter_length >= MAX_DELIMITER_LENGTH || lexer->eof(lexer) || lexer->lookahead == '\\' ||
 45            iswspace(lexer->lookahead)) {
 46            return false;
 47        }
 48        if (lexer->lookahead == '(') {
 49            // Rather than create a token for an empty delimiter, we fail and
 50            // let the grammar fall back to a delimiter-less rule.
 51            return scanner->delimiter_length > 0;
 52        }
 53        scanner->delimiter[scanner->delimiter_length++] = lexer->lookahead;
 54        advance(lexer);
 55    }
 56}
 57
 58/// Scan the raw string content in R"delimiter(content)delimiter"
 59static bool scan_raw_string_content(Scanner *scanner, TSLexer *lexer) {
 60    // The progress made through the delimiter since the last ')'.
 61    // The delimiter may not contain ')' so a single counter suffices.
 62    for (int delimiter_index = -1;;) {
 63        // If we hit EOF, consider the content to terminate there.
 64        // This forms an incomplete raw_string_literal, and models the code
 65        // well.
 66        if (lexer->eof(lexer)) {
 67            lexer->mark_end(lexer);
 68            return true;
 69        }
 70
 71        if (delimiter_index >= 0) {
 72            if (delimiter_index == scanner->delimiter_length) {
 73                if (lexer->lookahead == '"') {
 74                    return true;
 75                }
 76                delimiter_index = -1;
 77            } else {
 78                if (lexer->lookahead == scanner->delimiter[delimiter_index]) {
 79                    delimiter_index += 1;
 80                } else {
 81                    delimiter_index = -1;
 82                }
 83            }
 84        }
 85
 86        if (delimiter_index == -1 && lexer->lookahead == ')') {
 87            // The content doesn't include the )delimiter" part.
 88            // We must still scan through it, but exclude it from the token.
 89            lexer->mark_end(lexer);
 90            delimiter_index = 0;
 91        }
 92
 93        advance(lexer);
 94    }
 95}
 96
 97void *tree_sitter_cuda_external_scanner_create() {
 98    Scanner *scanner = (Scanner *)ts_calloc(1, sizeof(Scanner));
 99    memset(scanner, 0, sizeof(Scanner));
100    return scanner;
101}
102
103bool tree_sitter_cuda_external_scanner_scan(void *payload, TSLexer *lexer, const bool *valid_symbols) {
104    Scanner *scanner = (Scanner *)payload;
105
106    if (valid_symbols[RAW_STRING_DELIMITER] && valid_symbols[RAW_STRING_CONTENT]) {
107        // we're in error recovery
108        return false;
109    }
110
111    // No skipping leading whitespace: raw-string grammar is space-sensitive.
112    if (valid_symbols[RAW_STRING_DELIMITER]) {
113        lexer->result_symbol = RAW_STRING_DELIMITER;
114        return scan_raw_string_delimiter(scanner, lexer);
115    }
116
117    if (valid_symbols[RAW_STRING_CONTENT]) {
118        lexer->result_symbol = RAW_STRING_CONTENT;
119        return scan_raw_string_content(scanner, lexer);
120    }
121
122    return false;
123}
124
125unsigned tree_sitter_cuda_external_scanner_serialize(void *payload, char *buffer) {
126    static_assert(MAX_DELIMITER_LENGTH * sizeof(wchar_t) < TREE_SITTER_SERIALIZATION_BUFFER_SIZE,
127                  "Serialized delimiter is too long!");
128
129    Scanner *scanner = (Scanner *)payload;
130    size_t size = scanner->delimiter_length * sizeof(wchar_t);
131    memcpy(buffer, scanner->delimiter, size);
132    return (unsigned)size;
133}
134
135void tree_sitter_cuda_external_scanner_deserialize(void *payload, const char *buffer, unsigned length) {
136    assert(length % sizeof(wchar_t) == 0 && "Can't decode serialized delimiter!");
137
138    Scanner *scanner = (Scanner *)payload;
139    scanner->delimiter_length = length / sizeof(wchar_t);
140    if (length > 0) {
141        memcpy(&scanner->delimiter[0], buffer, length);
142    }
143}
144
145void tree_sitter_cuda_external_scanner_destroy(void *payload) {
146    Scanner *scanner = (Scanner *)payload;
147    ts_free(scanner);
148}