add minimal Zed syntax highlighting for Ferro (#2)
* add minimal Ferro tree-sitter grammar * add temporary tree-sitter generation workflow * generate Ferro tree-sitter parser * drop custom grammar in favor of Rust grammar reuse * remove temporary tree-sitter generation workflow * add Zed extension manifest for Ferro * configure Ferro files for Zed * add Ferro syntax highlighting queries * remove generated custom tree-sitter parser * remove generated custom tree-sitter node types * tighten Ferro Zed highlight queries * add minimal Ferro tree-sitter grammar * point Zed at Ferro grammar * refresh Ferro highlights --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
github-actions[bot]
parent
deafd27939
commit
83ce26c209
@@ -0,0 +1,11 @@
|
||||
id = "ferro"
|
||||
name = "Ferro"
|
||||
version = "0.0.1"
|
||||
schema_version = 1
|
||||
authors = ["sebastianrcnt"]
|
||||
description = "Ferro syntax highlighting for Zed"
|
||||
repository = "https://github.com/sebastianrcnt/doslang"
|
||||
|
||||
[grammars.ferro]
|
||||
repository = "https://github.com/sebastianrcnt/doslang"
|
||||
rev = "40316bb34f5acbaf34979cdf2dce296ae752d81d"
|
||||
@@ -0,0 +1,6 @@
|
||||
name = "Ferro"
|
||||
grammar = "ferro"
|
||||
path_suffixes = ["fe"]
|
||||
line_comments = ["// "]
|
||||
tab_size = 4
|
||||
hard_tabs = false
|
||||
@@ -0,0 +1,12 @@
|
||||
; Ferro syntax highlighting for Zed.
|
||||
|
||||
(line_comment) @comment
|
||||
(block_comment) @comment
|
||||
(string_literal) @string
|
||||
(char_literal) @string
|
||||
(integer_literal) @number
|
||||
(builtin) @function.builtin
|
||||
(builtin_type) @type.builtin
|
||||
(keyword) @keyword
|
||||
(operator) @operator
|
||||
(punctuation) @punctuation.delimiter
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
// Minimal Tree-sitter grammar for Ferro syntax highlighting in Zed.
|
||||
// This intentionally models lexical structure rather than full Ferro semantics.
|
||||
|
||||
module.exports = grammar({
|
||||
name: "ferro",
|
||||
|
||||
extras: $ => [
|
||||
/[\s\uFEFF\u2060\u200B]/,
|
||||
],
|
||||
|
||||
rules: {
|
||||
source_file: $ => repeat(choice(
|
||||
$.line_comment,
|
||||
$.block_comment,
|
||||
$.string_literal,
|
||||
$.char_literal,
|
||||
$.integer_literal,
|
||||
$.builtin,
|
||||
$.builtin_type,
|
||||
$.keyword,
|
||||
$.identifier,
|
||||
$.operator,
|
||||
$.punctuation,
|
||||
)),
|
||||
|
||||
line_comment: _ => token(seq("//", /[^\n]*/)),
|
||||
|
||||
// Ferro block comments may nest. Keeping this rule recursive makes syntax
|
||||
// highlighting follow the compiler lexer instead of flattening nested /* */.
|
||||
block_comment: $ => seq(
|
||||
"/*",
|
||||
repeat(choice(
|
||||
$.block_comment,
|
||||
/[^*/]+/,
|
||||
/\*[^/]/,
|
||||
/\/[^*]/,
|
||||
)),
|
||||
"*/",
|
||||
),
|
||||
|
||||
string_literal: _ => token(seq(
|
||||
'"',
|
||||
repeat(choice(
|
||||
/[^"\\\n\r]/,
|
||||
/\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|[nrt\\'"0])/,
|
||||
)),
|
||||
'"',
|
||||
)),
|
||||
|
||||
char_literal: _ => token(seq(
|
||||
"'",
|
||||
choice(
|
||||
/[^'\\\n\r]/,
|
||||
/\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|[nrt\\'"0])/,
|
||||
),
|
||||
"'",
|
||||
)),
|
||||
|
||||
integer_literal: _ => token(prec(2, choice(
|
||||
/0[xX][0-9A-Fa-f_]+/,
|
||||
/0[bB][01_]+/,
|
||||
/0[oO][0-7_]+/,
|
||||
/[0-9][0-9_]*/,
|
||||
))),
|
||||
|
||||
builtin: _ => token(prec(3, /@[A-Za-z_][A-Za-z0-9_]*/)),
|
||||
|
||||
builtin_type: _ => token(prec(3, choice(
|
||||
"i8", "i16", "i32",
|
||||
"u8", "u16", "u32",
|
||||
"usize", "isize",
|
||||
"bool", "char", "void", "str",
|
||||
))),
|
||||
|
||||
keyword: _ => token(prec(3, choice(
|
||||
"unit", "import", "pub", "fn", "struct", "packed", "enum", "error",
|
||||
"const", "static", "var", "let", "mut",
|
||||
"if", "else", "while", "for", "in", "match",
|
||||
"return", "break", "continue", "defer",
|
||||
"unsafe", "critical", "shared", "atomic", "comptime", "asm",
|
||||
"try", "catch", "orelse", "as", "extern",
|
||||
"interrupt", "interrupt_safe", "far",
|
||||
"true", "false", "null", "undefined",
|
||||
"self", "Self", "type",
|
||||
"and", "or", "not",
|
||||
))),
|
||||
|
||||
identifier: _ => /[A-Za-z_][A-Za-z0-9_]*/,
|
||||
|
||||
operator: _ => token(choice(
|
||||
"<<=", ">>=",
|
||||
"+=", "-=", "*=", "/=", "%=", "&=", "|=", "^=",
|
||||
"==", "!=", "<=", ">=", "<<", ">>", "->", "=>", "..",
|
||||
"+%", "-%", "*%",
|
||||
"+", "-", "*", "/", "%", "=", "<", ">", "&", "|", "^", "~", "!", "?",
|
||||
)),
|
||||
|
||||
punctuation: _ => token(choice(
|
||||
"(", ")", "{", "}", "[", "]", ",", ";", ":", ".",
|
||||
)),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
[
|
||||
{
|
||||
"type": "block_comment",
|
||||
"named": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "block_comment",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "source_file",
|
||||
"named": true,
|
||||
"root": true,
|
||||
"fields": {},
|
||||
"children": {
|
||||
"multiple": true,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "block_comment",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "builtin",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "builtin_type",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "char_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "integer_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "keyword",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "line_comment",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "operator",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "punctuation",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "string_literal",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "*/",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "/*",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "builtin",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "builtin_type",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "char_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "integer_literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "keyword",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "line_comment",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "operator",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "punctuation",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "string_literal",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
+1744
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
#ifndef TREE_SITTER_PARSER_H_
|
||||
#define TREE_SITTER_PARSER_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#define ts_builtin_sym_error ((TSSymbol)-1)
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
#ifndef TREE_SITTER_API_H_
|
||||
typedef uint16_t TSStateId;
|
||||
typedef uint16_t TSSymbol;
|
||||
typedef uint16_t TSFieldId;
|
||||
typedef struct TSLanguage TSLanguage;
|
||||
typedef struct TSLanguageMetadata { uint8_t major_version; uint8_t minor_version; uint8_t patch_version; } TSLanguageMetadata;
|
||||
#endif
|
||||
typedef struct { TSFieldId field_id; uint8_t child_index; bool inherited; } TSFieldMapEntry;
|
||||
typedef struct { uint16_t index; uint16_t length; } TSMapSlice;
|
||||
typedef struct { bool visible; bool named; bool supertype; } TSSymbolMetadata;
|
||||
typedef struct TSLexer TSLexer;
|
||||
struct TSLexer { int32_t lookahead; TSSymbol result_symbol; void (*advance)(TSLexer *, bool); void (*mark_end)(TSLexer *); uint32_t (*get_column)(TSLexer *); bool (*is_at_included_range_start)(const TSLexer *); bool (*eof)(const TSLexer *); void (*log)(const TSLexer *, const char *, ...); };
|
||||
typedef enum { TSParseActionTypeShift, TSParseActionTypeReduce, TSParseActionTypeAccept, TSParseActionTypeRecover } TSParseActionType;
|
||||
typedef union { struct { uint8_t type; TSStateId state; bool extra; bool repetition; } shift; struct { uint8_t type; uint8_t child_count; TSSymbol symbol; int16_t dynamic_precedence; uint16_t production_id; } reduce; uint8_t type; } TSParseAction;
|
||||
typedef struct { uint16_t lex_state; uint16_t external_lex_state; } TSLexMode;
|
||||
typedef struct { uint16_t lex_state; uint16_t external_lex_state; uint16_t reserved_word_set_id; } TSLexerMode;
|
||||
typedef union { TSParseAction action; struct { uint8_t count; bool reusable; } entry; } TSParseActionEntry;
|
||||
typedef struct { int32_t start; int32_t end; } TSCharacterRange;
|
||||
struct TSLanguage { uint32_t abi_version; uint32_t symbol_count; uint32_t alias_count; uint32_t token_count; uint32_t external_token_count; uint32_t state_count; uint32_t large_state_count; uint32_t production_id_count; uint32_t field_count; uint16_t max_alias_sequence_length; const uint16_t *parse_table; const uint16_t *small_parse_table; const uint32_t *small_parse_table_map; const TSParseActionEntry *parse_actions; const char * const *symbol_names; const char * const *field_names; const TSMapSlice *field_map_slices; const TSFieldMapEntry *field_map_entries; const TSSymbolMetadata *symbol_metadata; const TSSymbol *public_symbol_map; const uint16_t *alias_map; const TSSymbol *alias_sequences; const TSLexerMode *lex_modes; bool (*lex_fn)(TSLexer *, TSStateId); bool (*keyword_lex_fn)(TSLexer *, TSStateId); TSSymbol keyword_capture_token; struct { const bool *states; const TSSymbol *symbol_map; void *(*create)(void); void (*destroy)(void *); bool (*scan)(void *, TSLexer *, const bool *); unsigned (*serialize)(void *, char *); void (*deserialize)(void *, const char *, unsigned); } external_scanner; const TSStateId *primary_state_ids; const char *name; const TSSymbol *reserved_words; uint16_t max_reserved_word_set_size; uint32_t supertype_count; const TSSymbol *supertype_symbols; const TSMapSlice *supertype_map_slices; const TSSymbol *supertype_map_entries; TSLanguageMetadata metadata; };
|
||||
static inline bool set_contains(const TSCharacterRange *ranges, uint32_t len, int32_t lookahead) { uint32_t index=0,size=len; while(size>1){uint32_t half=size/2,mid=index+half; const TSCharacterRange *r=&ranges[mid]; if(lookahead>=r->start&&lookahead<=r->end)return true; else if(lookahead>r->end)index=mid; size-=half;} const TSCharacterRange *r=&ranges[index]; return lookahead>=r->start&&lookahead<=r->end; }
|
||||
#ifdef _MSC_VER
|
||||
#define UNUSED __pragma(warning(suppress : 4101))
|
||||
#else
|
||||
#define UNUSED __attribute__((unused))
|
||||
#endif
|
||||
#define START_LEXER() bool result=false; bool skip=false; UNUSED bool eof=false; int32_t lookahead; goto start; next_state: lexer->advance(lexer,skip); start: skip=false; lookahead=lexer->lookahead;
|
||||
#define ADVANCE(state_value) { state=state_value; goto next_state; }
|
||||
#define ADVANCE_MAP(...) { static const uint16_t map[]={__VA_ARGS__}; for(uint32_t i=0;i<sizeof(map)/sizeof(map[0]);i+=2){if(map[i]==lookahead){state=map[i+1];goto next_state;}} }
|
||||
#define SKIP(state_value) { skip=true; state=state_value; goto next_state; }
|
||||
#define ACCEPT_TOKEN(symbol_value) result=true; lexer->result_symbol=symbol_value; lexer->mark_end(lexer);
|
||||
#define END_STATE() return result;
|
||||
#define SMALL_STATE(id) ((id)-LARGE_STATE_COUNT)
|
||||
#define STATE(id) id
|
||||
#define ACTIONS(id) id
|
||||
#define SHIFT(state_value) {{.shift={.type=TSParseActionTypeShift,.state=(state_value)}}}
|
||||
#define SHIFT_REPEAT(state_value) {{.shift={.type=TSParseActionTypeShift,.state=(state_value),.repetition=true}}}
|
||||
#define SHIFT_EXTRA() {{.shift={.type=TSParseActionTypeShift,.extra=true}}}
|
||||
#define REDUCE(symbol_name,children,precedence,prod_id) {{.reduce={.type=TSParseActionTypeReduce,.symbol=symbol_name,.child_count=children,.dynamic_precedence=precedence,.production_id=prod_id},}}
|
||||
#define RECOVER() {{.type=TSParseActionTypeRecover}}
|
||||
#define ACCEPT_INPUT() {{.type=TSParseActionTypeAccept}}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user