From e122239506d85f8ef69f207f1042177d609274ab Mon Sep 17 00:00:00 2001 From: i582 <51853996+i582@users.noreply.github.com> Date: Tue, 22 Jul 2025 16:27:47 +0400 Subject: [PATCH] fix(func/grammar): accept `<` and `>` as part of identifier Fixes #60 --- .../func-language-configuration.json | 2 +- package.json | 2 +- .../func/tree-sitter-func/grammar.js | 2 +- .../func/tree-sitter-func/src/grammar.json | 2 +- .../func/tree-sitter-func/src/parser.c | 60 +++++++++--------- .../tree-sitter-func/tree-sitter-func.wasm | Bin 79282 -> 79420 bytes 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/editors/code/src/languages/func-language-configuration.json b/editors/code/src/languages/func-language-configuration.json index ae453ec5..d7e185c1 100644 --- a/editors/code/src/languages/func-language-configuration.json +++ b/editors/code/src/languages/func-language-configuration.json @@ -25,7 +25,7 @@ "increaseIndentPattern": "^(.*\\{[^}\"']*|.*\\([^\\)\"']*|.*\\[[^\\]\"']*)$", "decreaseIndentPattern": "^\\s*[\\}\\]\\)]" }, - "wordPattern": "`[^`]+`|[A-Za-z_$:][^\\s+\\-*\\/%,.;(){}\\[\\]=<>|\\^~]*", + "wordPattern": "`[^`]+`|[A-Za-z_$:][^\\s+\\-*\\/%,.;(){}\\[\\]=|\\^~]*", "onEnterRules": [ { "beforeText": "^\\s*;;;.*$", diff --git a/package.json b/package.json index f0148833..3c6e4365 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "test:grammars:tolk": "cd ./server/src/languages/tolk/tree-sitter-tolk/ && tree-sitter test", "test:grammars:fift": "cd ./server/src/languages/fift/tree-sitter-fift/ && tree-sitter test", "test:grammars:tlb": "cd ./server/src/languages/tlb/tree-sitter-tlb/ && tree-sitter test", - "play:grammars:func": "cd ./server/src/languages/func/tree-sitter-func/ && tree-sitter build --wasm && tree-sitter playground", + "play:grammars:func": "cd ./server/src/languages/func/tree-sitter-func/ && tree-sitter generate && tree-sitter build --wasm && tree-sitter playground", "parse:grammars:func": "cd ./server/src/languages/func/tree-sitter-func/ && tree-sitter parse -D --open-log main.fc", "test:e2e": "yarn test:e2e:tolk", "test:e2e:compile": "tsc -p ./server/src/e2e/tsconfig.json", diff --git a/server/src/languages/func/tree-sitter-func/grammar.js b/server/src/languages/func/tree-sitter-func/grammar.js index f0840939..358dd728 100644 --- a/server/src/languages/func/tree-sitter-func/grammar.js +++ b/server/src/languages/func/tree-sitter-func/grammar.js @@ -382,7 +382,7 @@ const FUNC_GRAMMAR = { slice_string_literal: _ => /"[^"]*"[sa]/, // actually, FunC identifiers are much more flexible - identifier: _ => /`[^`]+`|[a-zA-Z0-9_\$%][^\s\+\-\*\/%,\.;\(\)\{\}\[\]=<>\|\^\~]*/, + identifier: _ => /`[^`]+`|[a-zA-Z0-9_\$%][^\s\+\-\*\/%,\.;\(\)\{\}\[\]=\|\^\~]*/, underscore: _ => "_", // multiline_comment: $ => seq('{-', repeat(choice(/./, $.multiline_comment)), '-}'), diff --git a/server/src/languages/func/tree-sitter-func/src/grammar.json b/server/src/languages/func/tree-sitter-func/src/grammar.json index e0859fdd..f451e9e3 100644 --- a/server/src/languages/func/tree-sitter-func/src/grammar.json +++ b/server/src/languages/func/tree-sitter-func/src/grammar.json @@ -2552,7 +2552,7 @@ }, "identifier": { "type": "PATTERN", - "value": "`[^`]+`|[a-zA-Z0-9_\\$%][^\\s\\+\\-\\*\\/%,\\.;\\(\\)\\{\\}\\[\\]=<>\\|\\^\\~]*" + "value": "`[^`]+`|[a-zA-Z0-9_\\$%][^\\s\\+\\-\\*\\/%,\\.;\\(\\)\\{\\}\\[\\]=\\|\\^\\~]*" }, "underscore": { "type": "STRING", diff --git a/server/src/languages/func/tree-sitter-func/src/parser.c b/server/src/languages/func/tree-sitter-func/src/parser.c index b3f7549c..c10e84d8 100644 --- a/server/src/languages/func/tree-sitter-func/src/parser.c +++ b/server/src/languages/func/tree-sitter-func/src/parser.c @@ -1980,8 +1980,8 @@ static const TSStateId ts_primary_state_ids[STATE_COUNT] = { }; static const TSCharacterRange sym_identifier_character_set_1[] = { - {0, 0x08}, {0x0e, 0x1f}, {'!', '$'}, {'&', '\''}, {'0', ':'}, {'?', 'Z'}, {'\\', '\\'}, {'_', 'z'}, - {0x7f, 0x10ffff}, + {0, 0x08}, {0x0e, 0x1f}, {'!', '$'}, {'&', '\''}, {'0', ':'}, {'<', '<'}, {'>', 'Z'}, {'\\', '\\'}, + {'_', 'z'}, {0x7f, 0x10ffff}, }; static bool ts_lex(TSLexer *lexer, TSStateId state) { @@ -2569,7 +2569,8 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { lookahead == ' ' || lookahead == '%' || ('(' <= lookahead && lookahead <= '/') || - (';' <= lookahead && lookahead <= '>') || + lookahead == ';' || + lookahead == '=' || lookahead == '[' || lookahead == ']' || lookahead == '^' || @@ -2590,7 +2591,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { case 93: ACCEPT_TOKEN(sym_version_identifier); if (('0' <= lookahead && lookahead <= '9')) ADVANCE(93); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 94: ACCEPT_TOKEN(sym_version_identifier); @@ -2600,7 +2601,8 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { lookahead == ' ' || lookahead == '%' || ('(' <= lookahead && lookahead <= '/') || - (';' <= lookahead && lookahead <= '>') || + lookahead == ';' || + lookahead == '=' || lookahead == '[' || lookahead == ']' || lookahead == '^' || @@ -2815,7 +2817,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { case 149: ACCEPT_TOKEN(anon_sym_PERCENT); if (lookahead == '=') ADVANCE(114); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 150: ACCEPT_TOKEN(anon_sym_TILDE_SLASH); @@ -2868,7 +2870,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { ACCEPT_TOKEN(aux_sym_number_literal_token1); if (lookahead == 'x') ADVANCE(192); if (('0' <= lookahead && lookahead <= '9')) ADVANCE(164); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 163: ACCEPT_TOKEN(aux_sym_number_literal_token1); @@ -2878,7 +2880,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { case 164: ACCEPT_TOKEN(aux_sym_number_literal_token1); if (('0' <= lookahead && lookahead <= '9')) ADVANCE(164); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 165: ACCEPT_TOKEN(aux_sym_number_literal_token1); @@ -2889,7 +2891,7 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { if (('0' <= lookahead && lookahead <= '9') || ('A' <= lookahead && lookahead <= 'F') || ('a' <= lookahead && lookahead <= 'f')) ADVANCE(166); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 167: ACCEPT_TOKEN(aux_sym_number_literal_token1); @@ -2928,103 +2930,103 @@ static bool ts_lex(TSLexer *lexer, TSStateId state) { case 174: ACCEPT_TOKEN(sym_identifier); if (lookahead == '-') ADVANCE(79); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 175: ACCEPT_TOKEN(sym_identifier); if (lookahead == '-') ADVANCE(68); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 176: ACCEPT_TOKEN(sym_identifier); if (lookahead == '-') ADVANCE(41); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 177: ACCEPT_TOKEN(sym_identifier); if (lookahead == '=') ADVANCE(114); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 178: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'e') ADVANCE(176); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 179: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'l') ADVANCE(180); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 180: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'l') ADVANCE(184); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 181: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'm') ADVANCE(185); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 182: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'o') ADVANCE(181); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 183: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'o') ADVANCE(186); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 184: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'o') ADVANCE(189); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 185: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'p') ADVANCE(188); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 186: ACCEPT_TOKEN(sym_identifier); if (lookahead == 't') ADVANCE(174); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 187: ACCEPT_TOKEN(sym_identifier); if (lookahead == 't') ADVANCE(178); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 188: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'u') ADVANCE(187); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 189: ACCEPT_TOKEN(sym_identifier); if (lookahead == 'w') ADVANCE(175); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 190: ACCEPT_TOKEN(sym_identifier); if (('0' <= lookahead && lookahead <= '9')) ADVANCE(93); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 191: ACCEPT_TOKEN(sym_identifier); if (('0' <= lookahead && lookahead <= '9')) ADVANCE(94); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 192: ACCEPT_TOKEN(sym_identifier); if (('0' <= lookahead && lookahead <= '9') || ('A' <= lookahead && lookahead <= 'F') || ('a' <= lookahead && lookahead <= 'f')) ADVANCE(166); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 193: ACCEPT_TOKEN(sym_identifier); - if ((!eof && set_contains(sym_identifier_character_set_1, 9, lookahead))) ADVANCE(193); + if ((!eof && set_contains(sym_identifier_character_set_1, 10, lookahead))) ADVANCE(193); END_STATE(); case 194: ACCEPT_TOKEN(sym_comment); diff --git a/server/src/languages/func/tree-sitter-func/tree-sitter-func.wasm b/server/src/languages/func/tree-sitter-func/tree-sitter-func.wasm index bc98c6420d9ae7f015e51c57ab29e6467406fccf..409045edfaf3346daa76b71cb183388bd12e9fa9 100755 GIT binary patch delta 8057 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 l5lqWpDavr|=o3Bdv$_|RG`QX1$GWsevtIe+ zR9WQ-Lqxs7XO=EfKWjGcY+Z{XH@LMO`c&>Cx_x zQRm7iPDMstax!W>88u>nVehDF&zUeDjPql$C`v`dfaFB<^F;I$wHyo9uuE+Y3wVCj zx)JG?ikRBu#Po%j3@4rHEBd=?b}Kb6v6}v_n!;4n^iNJrbzDugs7X}w8mp;s)fA+n zrY1Qxed22Rh<>h`Jt{V@vzmUcn*3DM^h-`nRa{M#=Sjg^X;KFO&mkE&^pQL&I!RJbZ~ zQ&CZooQmG@nDiFqZcJKKOx|QQ<*u5XRMeCwr>0k2O)sQ1u@m8_Qu6|<@e-~ssi-MS zPEF6anx3N6RilzsJp8K%|57(Pom0_Mnw*{Etx6Y>FjGRl98<*^4Zkc|hA~Vkt?&8Uly!06i4=R%it%W}FCle%Ty-ew zB(j;!S%IRGk|IuX&F=hg!pSKzU0+B?vTx}L+R>+c%?dQhgZMg%kE0;#EAD9p&;B>#aAYz_&<$WD(~F|q+)#vGfx7+Hv~RSxMIBX{BR zkVA4^KOV_p0`U*y1ypHgPkk3>oP2mC8ZkQ}LAUSd6OMMmo2wwk%8yYB`Ud+4yMu%; zmlohPVZ3!p|Ft()WTnH*d2t1EOK%RN4!^UK_-u^=e&=PS;oX;dZ-v)g7JdcJ4h0P> zSdWH>@x0)Ngh%x?&bclT-X|EnC{NfDN1<_hPV)}XJeau;W8^gi_i(S!g zLbm`uTjPCStC&L!FbsHr@mK6iZxhgjW@vUrO(FRgjjj3TF&Z>`PdVl3_@2oBUNtJH GJn%oB8Q