{"id":13716146,"url":"https://github.com/shnarazk/tree-sitter-bqn","last_synced_at":"2025-04-12T20:13:48.517Z","repository":{"id":165557639,"uuid":"640889528","full_name":"shnarazk/tree-sitter-bqn","owner":"shnarazk","description":"BQN grammar for tree-sitter","archived":false,"fork":false,"pushed_at":"2025-02-03T09:14:06.000Z","size":6855,"stargazers_count":16,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-12T20:13:42.725Z","etag":null,"topics":["bqn","parser","tree-sitter"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shnarazk.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-15T10:43:13.000Z","updated_at":"2025-04-09T10:25:11.000Z","dependencies_parsed_at":"2023-11-11T02:24:05.910Z","dependency_job_id":"5e2a216c-5c06-4412-953e-8c421c5afadd","html_url":"https://github.com/shnarazk/tree-sitter-bqn","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Ftree-sitter-bqn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Ftree-sitter-bqn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Ftree-sitter-bqn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Ftree-sitter-bqn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shnarazk","download_url":"https://codeload.github.com/shnarazk/tree-sitter-bqn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625517,"owners_count":21135514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bqn","parser","tree-sitter"],"created_at":"2024-08-03T00:01:07.532Z","updated_at":"2025-04-12T20:13:48.485Z","avatar_url":"https://github.com/shnarazk.png","language":"C","funding_links":[],"categories":["IDE/Editors"],"sub_categories":[],"readme":"# tree-sitter-bqn\n\n**Finally, [BQN](https://mlochbaum.github.io/BQN) programmers get AST-based editing features.**\n\n![](https://user-images.githubusercontent.com/997855/242257497-ec2578eb-45e2-46cd-9a52-cc761e1cdc11.png)\n\n## Implementation memo\n\n- A simplified grammar\n\nThis `tree-sitter-bqn` provides a parser for a simplified BQN grammar, in which blocks (`subExpr`, `FuncExpr`, `_m1Expr` and `_m2_Expr`) are unified as a typeless `block` type.\n\nSo you get the following from `{⋆}{𝔾𝔽¨𝕩}+{𝔽´}{↕10}`:\n\n```\n(source_file [0, 0] - [1, 0]\n  (STMT [0, 0] - [0, 15]\n    (EXPR [0, 0] - [0, 15]\n      (subExpr [0, 0] - [0, 15]\n        (arg [0, 0] - [0, 15]\n          (subject [0, 0] - [0, 3]\n            (atom [0, 0] - [0, 3]\n              (block [0, 0] - [0, 3]\n                (CASE_end [0, 1] - [0, 2]\n                  (BODY [0, 1] - [0, 2]\n                    (STMT [0, 1] - [0, 2]\n                      (EXPR [0, 1] - [0, 2]\n                        (FuncExpr [0, 1] - [0, 2]\n                          (Train [0, 1] - [0, 2]\n                            (Fork [0, 1] - [0, 2]\n                              (Derv [0, 1] - [0, 2]\n                                (Func [0, 1] - [0, 2]\n                                  (symbol_Fl [0, 1] - [0, 2])))))))))))))\n          (Derv [0, 3] - [0, 11]\n            (Func [0, 3] - [0, 11]\n              (block [0, 3] - [0, 11]\n                (CASE_end [0, 4] - [0, 10]\n                  (BODY [0, 4] - [0, 10]\n                    (STMT [0, 4] - [0, 10]\n                      (EXPR [0, 4] - [0, 10]\n                        (FuncExpr [0, 4] - [0, 10]\n                          (Train [0, 4] - [0, 10]\n                            (Fork [0, 4] - [0, 10]\n                              (Derv [0, 4] - [0, 10]\n                                (Operand [0, 4] - [0, 8]\n                                  (Derv [0, 4] - [0, 8]\n                                    (Func [0, 4] - [0, 8]\n                                      (specialname_F [0, 4] - [0, 8]))))\n                                (mod_1 [0, 8] - [0, 10]\n                                  (symbol__ml [0, 8] - [0, 10])))))))))))))\n          (subExpr [0, 11] - [0, 15]\n            (arg [0, 11] - [0, 15]\n              (subject [0, 11] - [0, 15]\n                (atom [0, 11] - [0, 15]\n                  (block [0, 11] - [0, 15]\n                    (CASE_end [0, 12] - [0, 14]\n                      (BODY [0, 12] - [0, 14]\n                        (STMT [0, 12] - [0, 14]\n                          (EXPR [0, 12] - [0, 14]\n                            (subExpr [0, 12] - [0, 14]\n                              (arg [0, 12] - [0, 14]\n                                (subject [0, 12] - [0, 14]\n                                  (atom [0, 12] - [0, 14]\n                                    (symbol_sl [0, 12] - [0, 14]\n                                      (number [0, 12] - [0, 14])))))))))))))))))))\n```\n\n- This is a CFG but not LR(1)\n\nThanks to GLR parser, `(((+))(((⌜))))((˜))((↕)10)` is parsed as\n\n```\n(source_file [0, 0] - [0, 31]\n  (STMT [0, 0] - [0, 31]\n    (EXPR [0, 0] - [0, 31]\n      (subExpr [0, 0] - [0, 31]\n        (arg [0, 0] - [0, 31]\n          (Derv [0, 0] - [0, 22]\n            (Operand [0, 0] - [0, 16]\n              (Derv [0, 0] - [0, 16]\n                (Func [0, 0] - [0, 16]\n                  (FuncExpr [0, 1] - [0, 15]\n                    (Train [0, 1] - [0, 15]\n                      (Fork [0, 1] - [0, 15]\n                        (Derv [0, 1] - [0, 15]\n                          (Operand [0, 1] - [0, 6]\n                            (Derv [0, 1] - [0, 6]\n                              (Func [0, 1] - [0, 6]\n                                (FuncExpr [0, 2] - [0, 5]\n                                  (Train [0, 2] - [0, 5]\n                                    (Fork [0, 2] - [0, 5]\n                                      (Derv [0, 2] - [0, 5]\n                                        (Func [0, 2] - [0, 5]\n                                          (FuncExpr [0, 3] - [0, 4]\n                                            (Train [0, 3] - [0, 4]\n                                              (Fork [0, 3] - [0, 4]\n                                                (Derv [0, 3] - [0, 4]\n                                                  (Func [0, 3] - [0, 4]\n                                                    (symbol_Fl [0, 3] - [0, 4]))))))))))))))\n                          (mod_1 [0, 6] - [0, 15]\n                            (m1_Expr [0, 7] - [0, 14]\n                              (mod_1 [0, 7] - [0, 14]\n                                (m1_Expr [0, 8] - [0, 13]\n                                  (mod_1 [0, 8] - [0, 13]\n                                    (m1_Expr [0, 9] - [0, 12]\n                                      (mod_1 [0, 9] - [0, 12]\n                                        (symbol__ml [0, 9] - [0, 12])))))))))))))))\n            (mod_1 [0, 16] - [0, 22]\n              (m1_Expr [0, 17] - [0, 21]\n                (mod_1 [0, 17] - [0, 21]\n                  (m1_Expr [0, 18] - [0, 20]\n                    (mod_1 [0, 18] - [0, 20]\n                      (symbol__ml [0, 18] - [0, 20])))))))\n          (subExpr [0, 22] - [0, 31]\n            (arg [0, 22] - [0, 31]\n              (subject [0, 22] - [0, 31]\n                (atom [0, 22] - [0, 31]\n                  (subExpr [0, 23] - [0, 30]\n                    (arg [0, 23] - [0, 30]\n                      (Derv [0, 23] - [0, 28]\n                        (Func [0, 23] - [0, 28]\n                          (FuncExpr [0, 24] - [0, 27]\n                            (Train [0, 24] - [0, 27]\n                              (Fork [0, 24] - [0, 27]\n                                (Derv [0, 24] - [0, 27]\n                                  (Func [0, 24] - [0, 27]\n                                    (symbol_Fl [0, 24] - [0, 27]))))))))\n                      (subExpr [0, 28] - [0, 30]\n                        (arg [0, 28] - [0, 30]\n                          (subject [0, 28] - [0, 30]\n                            (atom [0, 28] - [0, 30]\n                              (symbol_sl [0, 28] - [0, 30]\n                                (number [0, 28] - [0, 30])))))))))))))))))\n```\n\n## References\n\n- [Specification BQN grammar](https://mlochbaum.github.io/BQN/spec/grammar.html)\n- [tree-sitter tutorial](https://tree-sitter.github.io/tree-sitter/creating-parsers)\n- [target color schema](https://github.com/helix-editor/helix/blob/53f47bc47771c94dab51626ca025be28e62eba0c/runtime/themes/solarized_light.toml#L1-L23)\n- [textobjects](https://docs.helix-editor.com/guides/textobject.html)\n\n# A configuration for Helix\n\nAre you a [Helix](https://helix-editor.com/) user? Then try:\n\n1. Add the following to your $CONFIG/helix/languages.toml (Note: this does not include settings for bqnlsp. Please check [the wiki](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers#bqn) about it.)\n\n```toml\n[[language]]\nname = \"bqn\"\nlanguage-id = \"bqn\"\nfile-types = [\"bqn\"]\ninjection-regex = \"bqn\"\nscope = \"source.bqn\"\nroots = []\ncomment-token = \"#\"\nindent = { tab-width = 2, unit = \"  \" }\nshebangs = [\"BQN\", \"CBQN\", \"bqn\", \"cbqn\"]\n\n[[grammar]]\nname = \"bqn\"\nsource.git = \"https://github.com/shnarazk/tree-sitter-bqn\"\nsource.rev = \"a56f2d20ee42d39afe67730eeb13c2f41e1b0877\" or something new\n\n[language.auto-pairs]\n'(' = ')'\n'{' = '}'\n'[' = ']'\n\"'\" = \"'\"\n'\"' = '\"'\n'⟨' = '⟩'\n```\n\n2. Build up on shell:\n\n```\n$ hx -g fetch\n$ hx -g build\n```\n\n3. Copy query files:\n\n```\n$ mkdir -p $HELIX/runtime/queries/bqn\n$ cp -r queries $HELIX/runtime/queries/bqn\n```\n\nNow you can:\n- expand/shrink selection by moving up/down on AST as we expect\n- indent after `:`, `?`, `{`, `⟨` and so on, and outdent at `}`, `⟩`, `;` and so on\n- traverse function blocks by `]f` and `[f`\n- traverse function headers by `]a` and `[a`\n- traverse namespaces by `]t` and `[t`\n- traverse comments by `]c` and `[c`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshnarazk%2Ftree-sitter-bqn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshnarazk%2Ftree-sitter-bqn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshnarazk%2Ftree-sitter-bqn/lists"}