├── .gitignore ├── CHANGELOG.md ├── COPYING.txt ├── README.md ├── doc ├── credits.md ├── limits.md ├── resources.md ├── scope.md ├── testing.md ├── use.md └── what-and-why.md ├── grammar.js ├── package.json ├── queries └── highlights.scm ├── src ├── grammar.json ├── node-types.json ├── parser.c └── tree_sitter │ └── parser.h └── test └── corpus ├── anon_fn_lit.txt ├── bool_lit.txt ├── char_lit.txt ├── comment.txt ├── derefing_lit.txt ├── dis_expr.txt ├── evaling_lit.txt ├── kwd_lit.txt ├── list_lit.txt ├── map_lit.txt ├── meta_lit.txt ├── nil_lit.txt ├── ns_map_lit.txt ├── num_lit.txt ├── old_meta.lit ├── quoting_lit.txt ├── read_cond_lit.txt ├── regex_lit.txt ├── set_lit.txt ├── splicing_read_cond_lit.txt ├── str_lit.txt ├── sym_lit.txt ├── sym_val_lit.txt ├── syn_quoting_lit.txt ├── tagged_or_ctor_lit.txt ├── unquote_splicing_lit.txt ├── unquoting_lit.txt ├── var_quoting_lit.txt └── vec_lit.txt /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bin 3 | build 4 | *.log 5 | 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | Bits may be missing and/or inaccurate :) 4 | 5 | ### Future? 6 | 7 | * Handle zero bytes? 8 | * Decide about inline use (e.g. add some \_bare\_\* constructs? stop using?) 9 | ([#41](https://github.com/sogaiu/tree-sitter-clojure/issues/41)) 10 | 11 | ### v0.0.13 - 2024-05-15 12 | 13 | * Features and Fixes 14 | * Increase API number from 13 to 14 15 | ([#60](https://github.com/sogaiu/tree-sitter-clojure/issues/60)) 16 | * Remove Node and Rust Bindings 17 | ([#61](https://github.com/sogaiu/tree-sitter-clojure/issues/61)) 18 | * Update version info in package.json 19 | 20 | * Docs 21 | * What and why doc - update bindings info 22 | 23 | ### v0.0.12 - 2023-05-07 24 | 25 | * Features and Fixes 26 | * Loosen sym_val_lit definition 27 | ([#51](https://github.com/sogaiu/tree-sitter-clojure/issues/51)) 28 | * Handle metadata that is an evaling_lit 29 | ([#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35), 30 | [#46](https://github.com/sogaiu/tree-sitter-clojure/issues/46), 31 | [#50](https://github.com/sogaiu/tree-sitter-clojure/issues/50)) 32 | * Handle construct used for ClojureDart's parameterized types 33 | ([#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35), 34 | [#44](https://github.com/sogaiu/tree-sitter-clojure/pull/44), 35 | [#46](https://github.com/sogaiu/tree-sitter-clojure/issues/46)) 36 | * Generate parser.c and friends with tree-sitter 0.20.7 (ABI 13) 37 | ([#26](https://github.com/sogaiu/tree-sitter-clojure/pull/26), 38 | [#34](https://github.com/sogaiu/tree-sitter-clojure/issues/34), 39 | [#45](https://github.com/sogaiu/tree-sitter-clojure/issues/45)) 40 | * Docs 41 | * README 42 | * Add section on "what and why" 43 | ([#38](https://github.com/sogaiu/tree-sitter-clojure/issues/38)) 44 | * Add section pointing to other docs 45 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 46 | * Move resources list to own document 47 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 48 | * Remove npm-related descriptions 49 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 50 | * Use doc - mostly new users added 51 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 52 | * Scope doc - corrections and refinements 53 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 54 | * Testing doc - link and format updates 55 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 56 | * What and why doc - added 57 | ([#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 58 | * Limits doc - added 59 | * notes.txt - removed 60 | * Developer-related 61 | * Improve maintainability of grammar.js 62 | ([#39](https://github.com/sogaiu/tree-sitter-clojure/issues/39), 63 | [#40](https://github.com/sogaiu/tree-sitter-clojure/issues/40)) 64 | * Remove dependence on npm 65 | ([#36](https://github.com/sogaiu/tree-sitter-clojure/issues/36), 66 | [#37](https://github.com/sogaiu/tree-sitter-clojure/issues/37), 67 | [#38](https://github.com/sogaiu/tree-sitter-clojure/issues/38), 68 | [#45](https://github.com/sogaiu/tree-sitter-clojure/issues/45)) 69 | * Cleanup package.json 70 | ([#34](https://github.com/sogaiu/tree-sitter-clojure/issues/34), 71 | [#36](https://github.com/sogaiu/tree-sitter-clojure/issues/36), 72 | [#37](https://github.com/sogaiu/tree-sitter-clojure/issues/37), 73 | [#38](https://github.com/sogaiu/tree-sitter-clojure/issues/38), 74 | [#45](https://github.com/sogaiu/tree-sitter-clojure/issues/45)) 75 | * Move corpus to test/corpus 76 | * Most developer-bits moved to separate repository 77 | ([#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35), 78 | [#36](https://github.com/sogaiu/tree-sitter-clojure/issues/36), 79 | [#39](https://github.com/sogaiu/tree-sitter-clojure/issues/39), 80 | [#42](https://github.com/sogaiu/tree-sitter-clojure/issues/42), 81 | [#43](https://github.com/sogaiu/tree-sitter-clojure/issues/43), 82 | [#45](https://github.com/sogaiu/tree-sitter-clojure/issues/45), 83 | [#46](https://github.com/sogaiu/tree-sitter-clojure/issues/46), 84 | [#47](https://github.com/sogaiu/tree-sitter-clojure/issues/47)) 85 | * Credits 86 | * borkdude 87 | ([#51](https://github.com/sogaiu/tree-sitter-clojure/issues/51)) 88 | * cgrand 89 | ([#44](https://github.com/sogaiu/tree-sitter-clojure/pull/44)) 90 | * dannyfreeman 91 | ([#26](https://github.com/sogaiu/tree-sitter-clojure/pull/26), 92 | [#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35), 93 | [#37](https://github.com/sogaiu/tree-sitter-clojure/issues/37), 94 | [#38](https://github.com/sogaiu/tree-sitter-clojure/issues/38), 95 | [#39](https://github.com/sogaiu/tree-sitter-clojure/issues/39), 96 | [#40](https://github.com/sogaiu/tree-sitter-clojure/issues/40), 97 | [#41](https://github.com/sogaiu/tree-sitter-clojure/issues/41), 98 | [#42](https://github.com/sogaiu/tree-sitter-clojure/issues/42), 99 | [#43](https://github.com/sogaiu/tree-sitter-clojure/issues/43), 100 | [#46](https://github.com/sogaiu/tree-sitter-clojure/issues/46), 101 | [#48](https://github.com/sogaiu/tree-sitter-clojure/pull/48), 102 | [#49](https://github.com/sogaiu/tree-sitter-clojure/issues/49), 103 | [#51](https://github.com/sogaiu/tree-sitter-clojure/issues/51)) 104 | * dmiller 105 | ([#42](https://github.com/sogaiu/tree-sitter-clojure/issues/42)) 106 | * IGJoshua 107 | ([#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35)) 108 | * NoahTheDuke 109 | ([#26](https://github.com/sogaiu/tree-sitter-clojure/pull/26), 110 | [#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35), 111 | [#37](https://github.com/sogaiu/tree-sitter-clojure/issues/37), 112 | [#38](https://github.com/sogaiu/tree-sitter-clojure/issues/38), 113 | [#39](https://github.com/sogaiu/tree-sitter-clojure/issues/39), 114 | [#40](https://github.com/sogaiu/tree-sitter-clojure/issues/40), 115 | [#42](https://github.com/sogaiu/tree-sitter-clojure/issues/42)) 116 | * phronmophobic 117 | ([#35](https://github.com/sogaiu/tree-sitter-clojure/issues/35)) 118 | 119 | ### v0.0.11 - 2023-01-22 120 | 121 | * Update version info in package.json 122 | 123 | ### v0.0.10 - 2023-01-06 124 | 125 | * Tokenize symbols and keywords further 126 | ([#31](https://github.com/sogaiu/tree-sitter-clojure/issues/31)) - 127 | dannyfreeman 128 | * Address symbols after metadata issue 129 | ([#21](https://github.com/sogaiu/tree-sitter-clojure/issues/21)) - 130 | dannyfreeman 131 | * Change formatting of grammar.js 132 | 133 | ### v0.0.9 - 2022-06-03 134 | 135 | * Add corpus for light testing 136 | * Add highlighting queries for difftastic 137 | ([#20](https://github.com/sogaiu/tree-sitter-clojure/issues/20)) 138 | * Remove web-tree-sitter dependency 139 | ([#19](https://github.com/sogaiu/tree-sitter-clojure/issues/19)) 140 | * Re-add binding.gyp 141 | 142 | ### v0.0.8 - 2021-03-17 143 | 144 | * Upgrade tree-sitter to 0.19.3 145 | * Add Cargo.toml 146 | * Upgrade tree-sitter to 0.19.2 147 | * Add generated bindings directory and content 148 | 149 | ### v0.0.7 - 2021-01-05 150 | 151 | * CC0-1.0 ([#11](https://github.com/sogaiu/tree-sitter-clojure/issues/11)) 152 | * Tweak grammar.js 153 | 154 | ### v0.0.3 - 2020-10-30 155 | 156 | * Add generated src directory and content 157 | * Major renaming 158 | * More fields 159 | * Refine metadata bits 160 | * Refine \_bare\_\* constructs usage 161 | * Address discard / number parsing issue 162 | ([#7](https://github.com/sogaiu/tree-sitter-clojure/issues/7)) 163 | * Octal number tweak 164 | * Restore visibility of comment nodes 165 | * ? 166 | 167 | ### v0.0.2 - 2020-09-02 168 | 169 | * Handle whitespace explicitly, no extras 170 | * Start using some \_bare\_\* constructs 171 | * ? 172 | 173 | ### v0.0.1 - 2020-07-05 174 | 175 | * First tagging 176 | -------------------------------------------------------------------------------- /COPYING.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter-clojure 2 | 3 | A tree-sitter grammar for Clojure and ClojureScript 4 | 5 | ## What the Repository Provides 6 | 7 | This repository provides some files used to create various artifacts 8 | (e.g. dynamic libraries) used for handling Clojure and ClojureScript 9 | source code via tree-sitter. 10 | 11 | Please see the [what and why document](doc/what-and-why.md) for 12 | detailed information. 13 | 14 | ## Potential Changes Announcements 15 | 16 | Changes may occur because: 17 | 18 | 1. There may be unanticipated important use cases we may want to 19 | account for 20 | 2. The grammar depends on tree-sitter which remains in flux (and is 21 | still pre 1.0) 22 | 3. It's possible we missed something or got something wrong about 23 | Clojure and we might want to remedy that 24 | 25 | To get a heads-up before such changes occur, please consider 26 | subscribing to the [Potential Changes Announcements 27 | issue](https://github.com/sogaiu/tree-sitter-clojure/issues/33) to be 28 | notified beforehand. 29 | 30 | Note that previously tagged versions may work fine depending on the 31 | use case. See the [changelog](CHANGELOG.md) for details. 32 | 33 | ## Other Documents 34 | 35 | There are some documents in the [`doc` directory](doc/) covering 36 | topics such as: 37 | 38 | * [Scope](doc/scope.md) 39 | * [Limits](doc/limits.md) 40 | * [Testing](doc/testing.md) 41 | * [Uses](doc/use.md) 42 | 43 | ## Acknowledgments 44 | 45 | Please see the [credits](doc/credits.md). 46 | 47 | -------------------------------------------------------------------------------- /doc/credits.md: -------------------------------------------------------------------------------- 1 | ## Credits 2 | 3 | Many people were directly and indirectly involved in bringing about tree-sitter-clojure. I may have missed some people below, please let me know if I have. Thanks to all! 4 | 5 | * Aerijo - Guide to your first Tree-sitter grammar 6 | * ahlinc - tree-sitter work 7 | * alehatsman - nvim-treesitter and related discussion 8 | * alexmiller - clojure-related inquiries and docs 9 | * andrewchambers - discussion 10 | * bbatsov - discussions and clojure-ts-mode 11 | * bfredl - neovim and tree-sitter work 12 | * borkdude - analyze-reify, babashka, clj-kondo, edamame, and more 13 | * carocad - parcera and discussions 14 | * cgrand - ClojureDart and related reader explanation 15 | * clojars - including everyone who has uploaded there 16 | * CoenraadS - Bracket-Pair-Colorizer-2 17 | * dannyfreeman - grammar.js enhancements and fixes, clojure-ts-mode and discussions 18 | * dmiller - ClojureCLR consultation 19 | * EvegeniyPeshkov - syntax-highlighter 20 | * georgewfraser - vscode-tree-sitter 21 | * gfredericks - test.check, generators, and discussions 22 | * GrayJack - discussions and tree-sitter-janet 23 | * hitode909 - vscode-perl-outline 24 | * iarenaza - discussions 25 | * IGJoshua - ClojureCLR investigations 26 | * jafingerhut - clojure-related inquiries and haironfire research 27 | * jeff-hykin - tree-sitter and VSCode related 28 | * kolja - nrepl-alliance and tree-sitter question concerning Clojure on StackOverflow 29 | * lread - rewrite-cljc and discussions 30 | * mauricioszabo - clover and repl-tooling 31 | * maxbrunsfeld - tree-sitter and related 32 | * monnier - emacs-tree-sitter related 33 | * NoahTheDuke - discussion and suggestions 34 | * nwjsmith - tree-sitter upgrade 35 | * oakmac - tree-sitter-clojure.oakmac, conj 2018 unsession, advice, etc. 36 | * p00f - nvim-ts-rainbow 37 | * pedrorgirardi - discussions, vscode and tree-sitter-clojure bits 38 | * PEZ - calva, vscode tips, and general discussion 39 | * phronmophobic - dewey, discussion, and repository data 40 | * pyrmont - review, error-spotting, fix, and discussions 41 | * rewinfrey - helpful bits from tree-sitter-haskell 42 | * richhickey - clojure, etc. 43 | * rrudakov - discussions and clojure-ts-mode 44 | * Saikyun - discussions 45 | * seancorfield - clojure-related inquiries 46 | * SergeevPavel - tree-sitter-clojure.SergeevPavel (fork of tree-sitter-clojure.Tavistock with further work) 47 | * SevereOverfl0w - tree-sitter and vim info 48 | * shackra - tree-sitter-query.el 49 | * SignSpice - discussion 50 | * snoe - discussions 51 | * Tavistock - tree-sitter-clojure.Tavistock 52 | * th0rex - emacs-tree-sitter related 53 | * theHamsta - neovim, nvim-treesitter, tree-sitter-commonlisp 54 | * tobias - clojars work 55 | * tonsky - sublime-clojure work with test data, clojure north talk, alabaster theme 56 | * ubolonton - emacs-tree-sitter 57 | * vigoux - nvim-treesitter and related 58 | * Wilfred - difftastic, bug reporting, and discussion 59 | 60 | -------------------------------------------------------------------------------- /doc/limits.md: -------------------------------------------------------------------------------- 1 | # Limits 2 | 3 | The following items are known to not necessarily work: 4 | 5 | * [Some template 6 | files](https://github.com/sogaiu/tree-sitter-clojure/issues/42#issuecomment-1426727973) - 7 | these are often not strictly speaking Clojure, though they look pretty close 8 | * Other code that is not standard Clojure 9 | [1](https://github.com/fjarri/clojure-scribble#basic-usage) 10 | [2](https://github.com/dgrnbrg/piplin/blob/4c39386413d62ec9c2d679fa4c742313d97f75ef/src/piplin/mips.clj#L12) 11 | because it uses functionality that modifies Clojure's reader behavior 12 | in certain ways [1](https://github.com/jwymanm/chiara#the-syntax) 13 | [2](https://github.com/dgrnbrg/piplin/blob/4c39386413d62ec9c2d679fa4c742313d97f75ef/src/piplin/types/bits.clj#L231-L251) 14 | * Some older Clojure code - for example, `^` used to mean "wrap the 15 | following thing in `(meta ...)`" 16 | [1](https://github.com/clojure/clojure/blob/1.0.x/src/jvm/clojure/lang/LispReader.java#L71) 17 | [2](https://github.com/clojure/clojure/blob/1.0.x/src/clj/clojure/zip.clj#L58) 18 | * [ClojureCLR's pipe syntax for 19 | symbols](https://github.com/sogaiu/tree-sitter-clojure/issues/35#issuecomment-1407320526) 20 | ([comment at #42](https://github.com/sogaiu/tree-sitter-clojure/issues/42#issuecomment-1450290140)) 21 | * [Files that contain one or more 22 | zero-bytes](https://github.com/sogaiu/tree-sitter-clojure/issues/42#issuecomment-1430546851) 23 | [1](https://github.com/santifa/clj-dbase/blob/a269ca62d529cf82cec7bffce2e38b71458c6087/src/clj_dbase/core.clj#L121) 24 | [2](https://github.com/ont-app/vocabulary/blob/5929b9b1a16b07dc60f1012070da684e8f073326/resources/uri-escapes.edn) - 25 | this might be a tree-sitter limitation 26 | 27 | See [#42](https://github.com/sogaiu/tree-sitter-clojure/issues/42) for 28 | more details. 29 | -------------------------------------------------------------------------------- /doc/resources.md: -------------------------------------------------------------------------------- 1 | # Resources 2 | 3 | Below is a list of resources related to tree-sitter and/or Clojure. 4 | 5 | Some may be a bit dated at this point. 6 | 7 | * [Guide to your first Tree-sitter 8 | grammar](https://gist.github.com/Aerijo/df27228d70c633e088b0591b8857eeef) 9 | * [sublime-clojure](https://github.com/tonsky/sublime-clojure) 10 | * [syntax-highlighter](https://github.com/EvgeniyPeshkov/syntax-highlighter) 11 | * [tree-sitter](http://tree-sitter.github.io/tree-sitter/) 12 | * [tree-sitter-clojure.oakmac](https://github.com/oakmac/tree-sitter-clojure) 13 | * [tree-sitter-clojure.SergeevPavel](https://github.com/SergeevPavel/tree-sitter-clojure) 14 | * [tree-sitter-clojure.Tavistock](https://github.com/Tavistock/tree-sitter-clojure) 15 | * [vscode-tree-sitter](https://github.com/georgewfraser/vscode-tree-sitter) 16 | * [web-tree-sitter 17 | API](https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/tree-sitter-web.d.ts) 18 | -------------------------------------------------------------------------------- /doc/scope.md: -------------------------------------------------------------------------------- 1 | # Scope of tree-sitter-clojure 2 | 3 | ## TLDR 4 | 5 | Only "primitives" 6 | (e.g. [symbols](https://github.com/sogaiu/tree-sitter-clojure/blob/c00293fb0cd5ce3a7005c0601e9b546c1ea73094/grammar.js#L280-L282), 7 | [lists](https://github.com/sogaiu/tree-sitter-clojure/blob/c00293fb0cd5ce3a7005c0601e9b546c1ea73094/grammar.js#L307-L309), 8 | etc.) are supported, i.e. no higher level constructs like `defn`. 9 | 10 | ## The Details 11 | 12 | ### Why 13 | 14 | For some background, Clojure (and other Lisps) have runtime extensible 15 | "syntax" via macros, but AFAIU tree-sitter's current design assumes a 16 | fixed syntax. 17 | 18 | Keeping the above in mind, below are some of the factors that 19 | influenced the current stance on scope: 20 | 21 | * Clojure has no language specification. This means it's unclear what 22 | to try to support in the grammar. For example, `defn` is defined in 23 | the `clojure.core` namespace, but then so are a lot of other things 24 | and `clojure.core` is not a small namespace. 25 | 26 | * Each additional item added to the grammar tends to increase the 27 | difficulty of getting the grammar to function correctly (or well 28 | enough). In the event that an issue is discovered or a much desired 29 | feature surfaces, the more items there already are in the grammar, 30 | generally, the harder it may be to accomodate / adjust. 31 | 32 | * Handling more things might lead to degraded performance. Apart from 33 | possibly that being a negative for end-user use, that might also 34 | lead to more waiting time while testing across large samples of code 35 | (which has been essential because of the lack of a specification). 36 | 37 | ### Alternatives 38 | 39 | It is possible to [use tree-sitter-clojure as a 40 | base](https://github.com/tree-sitter/tree-sitter/issues/645) to add 41 | additional constructs to a "derived" grammar. For example, such a 42 | grammar might be specialized to look for "definitions". At least in 43 | [emacs-tree-sitter](https://github.com/ubolonton/emacs-tree-sitter), 44 | [it is technically possibly to have multiple grammars be used on 45 | single 46 | buffer](https://github.com/ubolonton/emacs-tree-sitter/discussions/129#discussioncomment-502836): 47 | 48 | > If you want 2 parse trees in the same buffer instead, you would need 49 | > to define an advice for tree-sitter--do-parse, as well as additional 50 | > buffer-local variables for the secondary grammar. 51 | 52 | Apparently it became possible in September of 2020 for [queries to 53 | match on any of a node's 54 | supertypes](https://github.com/tree-sitter/tree-sitter/pull/738). It 55 | may be possible to make a list supertype that is "composed of" `defn` 56 | and things that are not `defn`. 57 | [tree-sitter-clojure-def](https://github.com/sogaiu/tree-sitter-clojure-def) 58 | is an attempt at realizing this apoproach. 59 | 60 | However, depending on one's goals, it might make more sense to 61 | consider leveraging [clj-kondo's analysis 62 | capabilities](https://github.com/clj-kondo/clj-kondo/tree/master/analysis) 63 | as clj-kondo already understands Clojure pretty well. IIUC, 64 | [clojure-lsp does 65 | this](https://github.com/clojure-lsp/clojure-lsp/blob/14724457f0d553795dfe16317d3ee6c5fc97d4ba/deps.edn#L21). 66 | 67 | ### Miscellaneous Points 68 | 69 | * Earlier attempts at adding `def` and friends resulted in 70 | unacceptably high error rates [1]. The tests were conducted against 71 | code from [Clojars](https://clojars.org/) (uncontrived code) [2]. 72 | 73 | * For use cases like structural editing, it seems important to be able 74 | to distinguish between the following sorts of cases: 75 | * `defn` used for defining a function, and 76 | * [Using the symbol `defn` within a macro to construct code to 77 | define a 78 | function](https://github.com/Raynes/conch/blob/685f2c73138f376f2aa0623053dfdaba350a04f4/src/me/raynes/conch.clj#L251-L252) 79 | 80 | AFAICT, the approach taken in tree-sitter-clojure-def does not 81 | make telling these sorts of things apart possible. 82 | 83 | * It doesn't seem possible to support all "defining" macros like 84 | `defsomething` 85 | (e.g. https://github.com/redplanetlabs/specter/blob/efaf35558a2c0068f5b6a8ef1dbbd0912702bdbd/src/clj/com/rpl/specter.cljc#L57-L60) 86 | since a user's Clojure code can define these. 87 | 88 | ## Footnotes 89 | 90 | * [1] Author's opinion :) 91 | * [2] Two of the previous tree-sitter-clojure attempts (by 92 | [oakmac](https://github.com/oakmac/tree-sitter-clojure) and 93 | [Tavistock](https://github.com/Tavistock/tree-sitter-clojure)) also 94 | had unacceptably high error rates. The former of those two grammars 95 | tried to handle higher level constructs and it had a notably higher 96 | error rate. After trying to modify that grammar to address the error 97 | rate unsuccessfully, it seemed like the two points were related. Note 98 | though that this is just a suspicion. 99 | 100 | ## References 101 | 102 | * https://www.reddit.com/r/Clojure/comments/fkc6uv/is_anyone_working_on_a_treesitter_parser_for/fksmf67/ 103 | * https://github.com/sogaiu/tree-sitter-clojure/issues/15#issuecomment-880729889 104 | -------------------------------------------------------------------------------- /doc/testing.md: -------------------------------------------------------------------------------- 1 | # Testing tree-sitter-clojure 2 | 3 | ## TLDR 4 | 5 | [tree-sitter-clojure](https://github.com/sogaiu/tree-sitter-clojure) 6 | has been tested using a variety of methods. 7 | 8 | _Note_: Current serious testing is done via the code and instructions 9 | in the [ts-clojure](https://github.com/sogaiu/ts-clojure) repository. 10 | The description below is left for historical purposes. 11 | 12 | ## The Details 13 | 14 | This document will touch on some of those methods and why they were 15 | attempted: 16 | 17 | 1. Using corpus data from other tree-sitter-clojure attempts 18 | 2. Using Clojure source from [Clojars](https://clojars.org/) 19 | 3. Generative testing via 20 | [Hypothesis](https://github.com/HypothesisWorks/hypothesis) 21 | 22 | Other employed methods that won't be covered (in much, if any, detail) 23 | here: 24 | 25 | 1. Sporadic manual invocations 26 | 2. Using [tonsky's 27 | sublime-clojure](https://github.com/tonsky/sublime-clojure) test 28 | data 29 | 3. Generative testing via 30 | [test.check](https://github.com/clojure/test.check/) 31 | 4. [Manual inspection of the 32 | grammar](https://github.com/sogaiu/tree-sitter-clojure/issues/3) 33 | 34 | ## Using corpus data from other tree-sitter-clojure attempts 35 | 36 | There were at least two previous attempts at implementing 37 | tree-sitter-clojure, [one by 38 | oakmac](https://github.com/oakmac/tree-sitter-clojure) and [another by 39 | Tavistock](https://github.com/Tavistock/tree-sitter-clojure). 40 | Important things were learned by trying to make these attempts work, 41 | but for reasons not covered here, a separate attempt was started. 42 | 43 | Both earlier attempts had 44 | [corpus](https://github.com/oakmac/tree-sitter-clojure/tree/master/corpus) 45 | [data](https://github.com/Tavistock/tree-sitter-clojure/tree/master/corpus) 46 | that could be adapted for testing. Consequently, 47 | [tsclj-tests-parser](https://github.com/sogaiu/tsclj-tests-parser) was 48 | created to extract [the relevant data as plain 49 | files](https://github.com/sogaiu/tsclj-tests-parser/-/tree/master/test-files). 50 | These were in turn fed to tree-sitter's `parse` command using the 51 | tree-sitter-clojure grammar to check for parsing errors. 52 | 53 | If changes are made to tree-sitter-clojure's grammar, this method can 54 | be used to quickly check for some forms of undesirable breakage. 55 | (This could be taken a bit further by adapting the content as corpus 56 | data for tree-sitter-clojure.) 57 | 58 | ### But... 59 | 60 | One issue with this approach is that it relies on manually identifying 61 | and spelling out appropriate test cases, which in the case of Clojure, 62 | is complicated by the lack of a language specification. 63 | 64 | Apart from detailed research, this was partially addressed by testing 65 | against a large sample of Clojure source code written by the 66 | community. 67 | 68 | ## Using Clojure source from Clojars 69 | 70 | The most fruitful method of testing was working with Clojure source 71 | written by humans for purposes other than for testing 72 | tree-sitter-clojure. 73 | 74 | ### Where to get samples of Clojure source 75 | 76 | Initially, repositories were cloned from a variety of locations, but 77 | before long a decision was made to switch to using "release" jars from 78 | Clojars. 79 | 80 | The latter decision was motivated by wanting source that was less 81 | likely to be "broken" in various ways. Compared to "release" jar 82 | content from Clojars, the default branch of a repository seemed to 83 | have a higher probability of "not quite working". Although the 84 | Clojars "release" idea was an improvement, weeding out inappropriate 85 | Clojure source was still necessary. 86 | 87 | A variety of approaches were used to come up with a specific list of 88 | jars from Clojars, but the most recent attempt is 89 | [gen-clru-list](https://github.com/sogaiu/gen-clru-list). This is 90 | basically a [babashka](https://github.com/babashka/babashka) script 91 | that fetches [Clojars' 92 | feed.clj](https://github.com/clojars/clojars-web/wiki/Data#useful-extracts-from-the-poms), 93 | does some processing, and writes out a list of urls. For reference, 94 | this approach currently yields a number of urls in the neighborhood of 95 | 19,000. 96 | 97 | ### How to check retrieved Clojure samples 98 | 99 | The retrieved content was initially checked using 100 | [a-tsclj-checker](https://github.com/sogaiu/a-tsclj-checker) (an 101 | adaptation of 102 | [analyze-reify](https://github.com/borkdude/analyze-reify)) which uses 103 | [Rust bindings for 104 | tree-sitter](https://github.com/tree-sitter/tree-sitter/tree/master/lib/binding_rust) 105 | and tree-sitter-clojure to parse Clojure source code. Notably, it can 106 | traverse directories and also operate on `.jar` files. 107 | 108 | Once an error is detected, it is easier to investigate if one has 109 | direct access to the Clojure source file in question (as compared with 110 | rummaging around `.jar` files). Thus, it was decided to create a 111 | single directory tree containing extracted data from all retrieved 112 | jars. On a side note, the single directory tree took less than 2 GB 113 | of disk space. 114 | 115 | A less fancy, but easier to maintain (i.e. not written in Rust) tool -- 116 | [ts-grammar-checker](https://github.com/sogaiu/ts-grammar-checker) -- was 117 | developed as an alternative to `a-tsclj-checker`. Strictly speaking, 118 | `ts-grammar-checker` may not be necessary as one can probably employ 119 | tree-sitter's `parse` command in combination with `find`, `xargs` and the like 120 | if on some kind of \*nix. An example of a comparable invocation is: 121 | 122 | ``` 123 | find ~/src/clojars-cljish -type f -regex '.*\.clj[cs]?$' -print0 | xargs -0 tree-sitter parse --quiet > my-results.txt 124 | ``` 125 | 126 | `a-tsclj-checker` is the fastest tool but it has not been updated to 127 | the most recent version of tree-sitter-clojure. `ts-grammar-checker` 128 | is not quite as fast, but it can be easily adapted to work with other 129 | tree-sitter grammars (e.g. it's 130 | [used](https://github.com/sogaiu/ts-grammar-checker/-/blob/master/janet-checker.janet) 131 | for 132 | [tree-sitter-janet-simple](https://github.com/sogaiu/tree-sitter-janet-simple) 133 | as well). However, it does not support accessing content within 134 | `.jar` files. 135 | 136 | Across somewhat less than 150,000 files (.clj, .cljc, .cljs), 137 | `a-tsclj-checker` typically takes a little less than 30 seconds, while 138 | `ts-grammar-checker` typically takes a bit more than 100 seconds (at 139 | least on the author's machine). In subjective terms, it hasn't felt 140 | terribly different because knowing there is at least a 30 second wait, 141 | [one typically doesn't sit waiting at a prompt for execution 142 | completion](https://xkcd.com/303/). 143 | 144 | For any files that parse with errors, it can be handy to apply 145 | [clj-kondo](https://github.com/clj-kondo/clj-kondo). The specific 146 | details that `clj-kondo` reported were often helpful when examining 147 | individual files, but that diagnostic information also provided a way 148 | to partition the files into groups. Subjectively it can feel more 149 | manageable to deal with 5 groups of files compared with 100 separate 150 | files (though it's true that the grouping does not always turn out to 151 | be that meaningful). 152 | 153 | An individual "suspect" file is typically viewed manually in an editor 154 | (usually one that has `clj-kondo` support enabled) and examined for 155 | "issues". 156 | 157 | In practice, testing the grammar against appropriate Clojure source 158 | from Clojars has been the most useful in finding issues with the 159 | grammar. The lack of a specification for Clojure increased the 160 | difficulty of creating an appropriate grammar, but having a large 161 | sample of code to test against helped to mitigate this a bit. On more 162 | than one occasion some version of the grammar failed to parse some 163 | legitimate Clojure source and subsequent investigation revealed that 164 | the grammar had not accounted for an uncommom and/or unanticipated 165 | usage. 166 | 167 | ### But... 168 | 169 | This method has a significant weakness as there could be cases where 170 | tree-sitter would parse successfully but the result could be 171 | inappropriate. For example, if the grammar definition was faulty, 172 | something which should be parsed as a symbol might end up parsed as a 173 | number with no error reported. 174 | 175 | To partially address this issue, generative / property-based testing 176 | was attempted. 177 | 178 | ## Generative testing via Hypothesis 179 | 180 | Initially, [some effort was made to use 181 | test.check](https://gist.github.com/sogaiu/c0d668d050b63e298ef63549e357f9d2). 182 | However, [an outstanding issue with 183 | test.check](https://github.com/clojure/test.check/blob/master/doc/growth-and-shrinking.md#unnecessary-bind) 184 | (aka TCHECK-112) seemed very likely to be relevant for the types of 185 | tests being considered. Also, the approach used 186 | [libpython-clj](https://github.com/clj-python/libpython-clj) to call 187 | tree-sitter via [Python bindings for 188 | tree-sitter](https://github.com/tree-sitter/py-tree-sitter). Although 189 | invoking tree-sitter via Python worked, it was awkward to connect this 190 | with `test.check`. For the above reasons, the `test.check` + 191 | `libpython-clj` approach (neat as it was) was abandoned. 192 | 193 | Interestingly, Python's Hypothesis doesn't suffer from test.check's 194 | ["long-standing Hard 195 | Problem"](https://clojure.atlassian.net/browse/TCHECK-112) so that was 196 | given a try. 197 | [prop-test-ts-clj](https://github.com/sogaiu/prop-test-ts-clj) and 198 | [hypothesis-grammar-clojure](https://github.com/sogaiu/hypothesis-grammar-clojure) 199 | are the resulting bits. 200 | 201 | At least [one 202 | issue](https://github.com/sogaiu/tree-sitter-clojure/issues/7) was 203 | discovered and it also turned out that 204 | [parcera](https://github.com/carocad/parcera) was 205 | [affected](https://github.com/carocad/parcera/issues/86). 206 | 207 | The code was also adapted a bit to test 208 | [Calva](https://github.com/BetterThanTomorrow/calva). Some issues 209 | were discovered and [reported 210 | upstream](https://github.com/BetterThanTomorrow/calva/issues/802). 211 | 212 | ### But... 213 | 214 | A drawback of this approach is that details of the tree-sitter-clojure 215 | grammar became embedded in the tests. One consequence is that if 216 | tree-sitter-clojure's grammar changes, then the tests may need to be 217 | updated to reflect changes in the grammar (if there is an intent to 218 | continue to use them). 219 | 220 | ## Summary 221 | 222 | tree-sitter-clojure has been tested in a variety ways attempting to 223 | address various real-world constraints (e.g. lack of a language 224 | specification, limitations of tree-sitter's approach for a language 225 | with extensible syntax, etc.). AFAICT, for what it sets out to do, it 226 | seems to work pretty well so far. 227 | -------------------------------------------------------------------------------- /doc/use.md: -------------------------------------------------------------------------------- 1 | ## Use Information 2 | 3 | tree-sitter-clojure has been used in or by the following: 4 | 5 | * [clojure-ts-mode](https://github.com/clojure-emacs/clojure-ts-mode) 6 | 7 | * [Cursorless](https://github.com/cursorless-dev/cursorless) 8 | 9 | * [difftastic](https://github.com/Wilfred/difftastic) 10 | 11 | * [Helix Editor](https://github.com/helix-editor/helix) 12 | 13 | * [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) 14 | 15 | * [Semgrep](https://github.com/returntocorp/semgrep) 16 | 17 | * [tree-sitter-langs](https://github.com/emacs-tree-sitter/tree-sitter-langs) 18 | 19 | * Exploring [alternative highlighting 20 | ideas](https://github.com/ubolonton/emacs-tree-sitter/issues/68) and 21 | [an early emacs user 22 | foray](https://ag91.github.io/blog/2021/06/22/how-(simple-is)-to-install-a-clojure-tree-sitter-grammar-and-use-it-from-emacs/), 23 | both via 24 | [emacs-tree-sitter](https://github.com/ubolonton/emacs-tree-sitter). 25 | 26 | -------------------------------------------------------------------------------- /doc/what-and-why.md: -------------------------------------------------------------------------------- 1 | # What the Repository Provides and Why 2 | 3 | This document describes what files and directories the repository 4 | provides and associated reasoning. First it covers things which are 5 | likely to remain in place for some time (except perhaps the `src` 6 | directory). This is followed by a description of things that are more 7 | likely to change or be removed. 8 | 9 | One might be interested in this content out of academic curiosity but 10 | more likely it might be because one is thinking of depending on the 11 | repository in some way. 12 | 13 | ## What and Why 14 | 15 | The order of the following files and directories is alphabetical and 16 | not meant to reflect relative importance. 17 | 18 | * `CHANGELOG.md` - this file contains a changelog. 19 | 20 | * `COPYING.txt` - this file contains license information for the 21 | repository. 22 | 23 | * `grammar.js` - this file contains a grammar description and is used 24 | in the process of generating parser source code that lives in `src`. 25 | It's likely that this (or something comparable) will continue to be 26 | provided assuming tree-sitter doesn't change the way it works. 27 | 28 | * `package.json` - this file is needed by a 29 | [component](https://github.com/cursorless-dev/vscode-parse-tree/) of 30 | [Cursorless](https://www.cursorless.org/). It uses our grammar via 31 | yarn and `package.json` seems to be essential [1]. 32 | 33 | * `queries` - this directory and the simple file it contains are 34 | provided on request from 35 | [`difftastic`](https://github.com/Wilfred/difftastic) folks. The 36 | file it contains doesn't contain much and is not likely to be the 37 | sort of thing one expects to be used in an editor. 38 | 39 | * `README.md` - this file contains the repository's README content. 40 | 41 | * `src` - this directory contains source files that are generated [2] 42 | from `grammar.js`. The files are typically used to generate a 43 | dynamic library / shared object that can be used by the tree-sitter 44 | library to handle Clojure / ClojureScript source code. Although the 45 | content of this directory is generated, the files are provided 46 | because in practice, multiple parties have already become dependant 47 | on them. There have been opinions voiced that this should not 48 | remain so, but change in that direction has not been widespread. We 49 | would prefer not to be hosting this directory and its content, but 50 | are leaving it in place for the time being. See 51 | [here](https://github.com/sogaiu/ts-questions/blob/master/questions/should-parser-source-be-committed/README.md) 52 | for more on the topic if interested. 53 | 54 | * `test/corpus` - this directory contains tree-sitter's corpus 55 | test-related files. 56 | 57 | ## Other Content 58 | 59 | The rest of the content of the repository is currently documentation 60 | that lives in the `doc` directory. 61 | 62 | ## About Bindings 63 | 64 | The repository does not host any bindings (e.g. for Rust, Node, or 65 | other programming language). 66 | 67 | They should be straight-forward to generate as long as one has a 68 | suitable `tree-sitter` cli and the `grammar.js` file mentioned above. 69 | See some [official 70 | docs](https://github.com/tree-sitter/tree-sitter/blob/master/docs/section-3-creating-parsers.md#command-generate) 71 | for further information. 72 | 73 | N.B. it might be better to remove `package.json` before running 74 | `tree-sitter generate` so that appropriate binding information is 75 | placed in the `package.json` which is freshly created by the 76 | invocation. 77 | 78 | ## Footnotes 79 | 80 | [1] The file `package.json` may also be required if it's important to 81 | use some of the capabilities of the `tree-sitter` cli such as the 82 | `tags` and `highlight` subcommands (which we don't typically use). 83 | 84 | It's not necessary for all subcommands though (e.g. neither the 85 | `generate` nor `test` subcommands seem to require it). Its presence 86 | also doesn't signify necessary use of `npm`. 87 | 88 | Possibly contrary to what might be indicated elsewhere, `npm` is 89 | not necessary for certain core parts of tree-sitter grammar 90 | development. However, at the moment, an appropriate version of `node` 91 | _is_ required for the `generate` subcommand to work. 92 | 93 | [2] If the grammar uses an external scanner, `src` may contain 94 | non-generated files such as `scanner.c`, `scanner.cc`, etc. In the 95 | current case, no external scanner is used and the `src` directory 96 | content is entirely generated. 97 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | // one aim is to try to parse what is correct (in the sense of 2 | // officially supported), but also be looser in parsing additional 3 | // things. this is more or less in line with advice from tree-sitter 4 | // folks. 5 | 6 | function regex(...patts) { 7 | return RegExp(patts.join("")); 8 | } 9 | 10 | // java.lang.Character.isWhitespace AND comma 11 | // 12 | // Space Separator (Zs) but NOT including (U+00A0, U+2007, U+202F) 13 | // U+0020, U+1680, U+2000, U+2001, U+2002, U+2003, U+2004, U+2005, 14 | // U+2006, U+2008, U+2009, U+200A, U+205F, U+3000 15 | // Line Separator (Zl) 16 | // U+2028 17 | // Paragraph Separator (Zp) 18 | // U+2029 19 | // Horizontal Tabulation 20 | // \t 21 | // Line Feed 22 | // \n 23 | // Vertical Tabulation 24 | // U+000B 25 | // Form Feed 26 | // \f 27 | // Carriage Return 28 | // \r 29 | // File Separator 30 | // U+001C 31 | // Group Separator 32 | // U+001D 33 | // Record Separator 34 | // U+001E 35 | // Unit Separator 36 | // U+001F 37 | const WHITESPACE_CHAR = 38 | regex("[", 39 | "\\f\\n\\r\\t, ", 40 | "\\u000B\\u001C\\u001D\\u001E\\u001F", 41 | "\\u2028\\u2029\\u1680", 42 | "\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008", 43 | "\\u2009\\u200a\\u205f\\u3000", 44 | "]"); 45 | 46 | const WHITESPACE = 47 | token(repeat1(WHITESPACE_CHAR)); 48 | 49 | const COMMENT = 50 | token(regex('(;|#!).*\n?')); 51 | 52 | const DIGIT = 53 | regex('[0-9]'); 54 | 55 | const ALPHANUMERIC = 56 | regex('[0-9a-zA-Z]'); 57 | 58 | const HEX_DIGIT = 59 | regex('[0-9a-fA-F]'); 60 | 61 | const OCTAL_DIGIT = 62 | regex('[0-7]'); 63 | 64 | const HEX_NUMBER = 65 | seq("0", 66 | regex('[xX]'), 67 | repeat1(HEX_DIGIT), 68 | optional("N")); 69 | 70 | const OCTAL_NUMBER = 71 | seq("0", 72 | repeat1(OCTAL_DIGIT), 73 | optional("N")); 74 | 75 | // XXX: not constraining number before r/R 76 | // XXX: not constraining portion after r/R 77 | const RADIX_NUMBER = 78 | seq(repeat1(DIGIT), 79 | regex('[rR]'), 80 | repeat1(ALPHANUMERIC)); 81 | 82 | const RATIO = 83 | seq(repeat1(DIGIT), 84 | "/", 85 | repeat1(DIGIT)); 86 | 87 | const DOUBLE = 88 | seq(repeat1(DIGIT), 89 | optional(seq(".", 90 | repeat(DIGIT))), 91 | optional(seq(regex('[eE]'), 92 | optional(regex('[+-]')), 93 | repeat1(DIGIT))), 94 | optional("M")); 95 | 96 | const INTEGER = 97 | seq(repeat1(DIGIT), 98 | optional(regex('[MN]'))); 99 | 100 | const NUMBER = 101 | token(prec(10, seq(optional(regex('[+-]')), 102 | choice(HEX_NUMBER, 103 | OCTAL_NUMBER, 104 | RADIX_NUMBER, 105 | RATIO, 106 | DOUBLE, 107 | INTEGER)))); 108 | 109 | const NIL = 110 | token('nil'); 111 | 112 | const BOOLEAN = 113 | token(choice('false', 114 | 'true')); 115 | 116 | const KEYWORD_HEAD = 117 | regex("[^", 118 | "\\f\\n\\r\\t ", 119 | "()", 120 | "\\[\\]", 121 | "{}", 122 | '"', 123 | "@~^;`", 124 | "\\\\", 125 | ",:/", 126 | "\\u000B\\u001C\\u001D\\u001E\\u001F", 127 | "\\u2028\\u2029\\u1680", 128 | "\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008", 129 | "\\u2009\\u200a\\u205f\\u3000", 130 | "]"); 131 | 132 | const KEYWORD_BODY = 133 | choice(regex("[:']"), KEYWORD_HEAD); 134 | 135 | const KEYWORD_NAMESPACED_BODY = 136 | token(repeat1(choice(regex("[:'/]"), KEYWORD_HEAD))); 137 | 138 | const KEYWORD_NO_SIGIL = 139 | token(seq(KEYWORD_HEAD, 140 | repeat(KEYWORD_BODY))); 141 | 142 | const KEYWORD_MARK = 143 | token(":"); 144 | 145 | const AUTO_RESOLVE_MARK = 146 | token("::"); 147 | 148 | const STRING = 149 | token(seq('"', 150 | repeat(regex('[^"\\\\]')), 151 | repeat(seq("\\", 152 | regex("."), 153 | repeat(regex('[^"\\\\]')))), 154 | '"')); 155 | 156 | // XXX: better to match \o378 as a single item 157 | const OCTAL_CHAR = 158 | seq("o", 159 | choice(seq(DIGIT, DIGIT, DIGIT), 160 | seq(DIGIT, DIGIT), 161 | seq(DIGIT))); 162 | 163 | const NAMED_CHAR = 164 | choice("backspace", 165 | "formfeed", 166 | "newline", 167 | "return", 168 | "space", 169 | "tab"); 170 | 171 | // XXX: outside of: (c >= '\uD800' && c <= '\uDFFF') - LispReader.java 172 | // but not doing this 173 | const UNICODE = 174 | seq("u", 175 | HEX_DIGIT, 176 | HEX_DIGIT, 177 | HEX_DIGIT, 178 | HEX_DIGIT); 179 | 180 | // XXX: not quite sure what this is supposed to be... 181 | // return Character.valueOf(token.charAt(0)); -- LispReader.java 182 | // java char is 16 bits...what can tree-sitter manage? 183 | // 184 | // XXX: null is supposed to be usable but putting \x00 below 185 | // does not seem to work 186 | const ANY_CHAR = 187 | regex('.|\n'); 188 | 189 | const CHARACTER = 190 | token(seq("\\", 191 | choice(OCTAL_CHAR, 192 | NAMED_CHAR, 193 | UNICODE, 194 | ANY_CHAR))); 195 | 196 | const SYMBOL_HEAD = 197 | regex("[^", 198 | "\\f\\n\\r\\t ", 199 | "/", 200 | "()\\[\\]{}", 201 | '"', 202 | "@~^;`", 203 | "\\\\", 204 | ",:#'0-9", 205 | "\\u000B\\u001C\\u001D\\u001E\\u001F", 206 | "\\u2028\\u2029\\u1680", 207 | "\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008", 208 | "\\u2009\\u200a\\u205f\\u3000", 209 | "]"); 210 | 211 | const NS_DELIMITER = 212 | token("/"); 213 | 214 | const SYMBOL_BODY = 215 | choice(SYMBOL_HEAD, 216 | regex("[:#'0-9]")); 217 | 218 | const SYMBOL_NAMESPACED_NAME = 219 | token(repeat1(choice(SYMBOL_HEAD, 220 | regex("[/:#'0-9]")))); 221 | 222 | // XXX: no attempt is made to enforce certain complex things, e.g. 223 | // 224 | // Symbols beginning or ending with ':' are reserved by Clojure. 225 | // A symbol can contain one or more non-repeating ':'s 226 | const SYMBOL = 227 | token(seq(SYMBOL_HEAD, 228 | repeat(SYMBOL_BODY))); 229 | 230 | module.exports = grammar({ 231 | name: 'clojure', 232 | 233 | extras: $ => 234 | [], 235 | 236 | conflicts: $ => 237 | [], 238 | 239 | inline: $ => 240 | [$._kwd_leading_slash, 241 | $._kwd_just_slash, 242 | $._kwd_qualified, 243 | $._kwd_unqualified, 244 | $._kwd_marker, 245 | $._sym_qualified, 246 | $._sym_unqualified], 247 | 248 | rules: { 249 | // THIS MUST BE FIRST -- even though this doesn't look like it matters 250 | source: $ => 251 | repeat(choice($._form, 252 | $._gap)), 253 | 254 | _gap: $ => 255 | choice($._ws, 256 | $.comment, 257 | $.dis_expr), 258 | 259 | _ws: $ => 260 | WHITESPACE, 261 | 262 | comment: $ => 263 | COMMENT, 264 | 265 | dis_expr: $ => 266 | seq(field('marker', "#_"), 267 | repeat($._gap), 268 | field('value', $._form)), 269 | 270 | _form: $ => 271 | choice($.num_lit, // atom-ish 272 | $.kwd_lit, 273 | $.str_lit, 274 | $.char_lit, 275 | $.nil_lit, 276 | $.bool_lit, 277 | $.sym_lit, 278 | // basic collection-ish 279 | $.list_lit, 280 | $.map_lit, 281 | $.vec_lit, 282 | // dispatch reader macros 283 | $.set_lit, 284 | $.anon_fn_lit, 285 | $.regex_lit, 286 | $.read_cond_lit, 287 | $.splicing_read_cond_lit, 288 | $.ns_map_lit, 289 | $.var_quoting_lit, 290 | $.sym_val_lit, 291 | $.evaling_lit, 292 | $.tagged_or_ctor_lit, 293 | // some other reader macros 294 | $.derefing_lit, 295 | $.quoting_lit, 296 | $.syn_quoting_lit, 297 | $.unquote_splicing_lit, 298 | $.unquoting_lit), 299 | 300 | num_lit: $ => 301 | NUMBER, 302 | 303 | kwd_lit: $ => 304 | choice($._kwd_leading_slash, 305 | $._kwd_just_slash, 306 | $._kwd_qualified, 307 | $._kwd_unqualified), 308 | 309 | // (namespace :/usr/bin/env) ; => "" 310 | // (name :/usr/bin/env) ; => "usr/bin/env" 311 | _kwd_leading_slash: $ => 312 | seq(field('marker', $._kwd_marker), 313 | field('delimiter', NS_DELIMITER), 314 | field('name', alias(KEYWORD_NAMESPACED_BODY, $.kwd_name))), 315 | 316 | // (namespace :/) ;=> nil 317 | // (name :/) ;=> "/" 318 | _kwd_just_slash: $ => 319 | seq(field('marker', $._kwd_marker), 320 | field('name', alias(NS_DELIMITER, $.kwd_name))), 321 | 322 | _kwd_qualified: $ => 323 | prec(2, seq(field('marker', $._kwd_marker), 324 | field('namespace', alias(KEYWORD_NO_SIGIL, $.kwd_ns)), 325 | field('delimiter', NS_DELIMITER), 326 | field('name', alias(KEYWORD_NAMESPACED_BODY, $.kwd_name)))), 327 | 328 | _kwd_unqualified: $ => 329 | prec(1, seq(field('marker', $._kwd_marker), 330 | field('name', alias(KEYWORD_NO_SIGIL, $.kwd_name)))), 331 | 332 | _kwd_marker: $ => 333 | choice(KEYWORD_MARK, AUTO_RESOLVE_MARK), 334 | 335 | str_lit: $ => 336 | STRING, 337 | 338 | char_lit: $ => 339 | CHARACTER, 340 | 341 | nil_lit: $ => 342 | NIL, 343 | 344 | bool_lit: $ => 345 | BOOLEAN, 346 | 347 | sym_lit: $ => 348 | seq(repeat($._metadata_lit), 349 | choice($._sym_qualified, $._sym_unqualified)), 350 | 351 | _sym_qualified: $ => 352 | prec(1, seq(field("namespace", alias(SYMBOL, $.sym_ns)), 353 | field("delimiter", NS_DELIMITER), 354 | field("name", alias(SYMBOL_NAMESPACED_NAME, $.sym_name)))), 355 | 356 | _sym_unqualified: $ => 357 | field('name', alias(choice(NS_DELIMITER, // division symbol 358 | SYMBOL), 359 | $.sym_name)), 360 | 361 | _metadata_lit: $ => 362 | seq(choice(field("meta", $.meta_lit), 363 | field("old_meta", $.old_meta_lit)), 364 | optional(repeat($._gap))), 365 | 366 | meta_lit: $ => 367 | seq(field('marker', "^"), 368 | repeat($._gap), 369 | field('value', $._form)), 370 | 371 | old_meta_lit: $ => 372 | seq(field('marker', "#^"), 373 | repeat($._gap), 374 | field('value', $._form)), 375 | 376 | list_lit: $ => 377 | seq(repeat($._metadata_lit), 378 | $._bare_list_lit), 379 | 380 | _bare_list_lit: $ => 381 | seq(field('open', "("), 382 | repeat(choice(field('value', $._form), 383 | $._gap)), 384 | field('close', ")")), 385 | 386 | map_lit: $ => 387 | seq(repeat($._metadata_lit), 388 | $._bare_map_lit), 389 | 390 | _bare_map_lit: $ => 391 | seq(field('open', "{"), 392 | repeat(choice(field('value', $._form), 393 | $._gap)), 394 | field('close', "}")), 395 | 396 | vec_lit: $ => 397 | seq(repeat($._metadata_lit), 398 | $._bare_vec_lit), 399 | 400 | _bare_vec_lit: $ => 401 | seq(field('open', "["), 402 | repeat(choice(field('value', $._form), 403 | $._gap)), 404 | field('close', "]")), 405 | 406 | set_lit: $ => 407 | seq(repeat($._metadata_lit), 408 | $._bare_set_lit), 409 | 410 | _bare_set_lit: $ => 411 | seq(field('marker', "#"), 412 | field('open', "{"), 413 | repeat(choice(field('value', $._form), 414 | $._gap)), 415 | field('close', "}")), 416 | 417 | anon_fn_lit: $ => 418 | seq(repeat($._metadata_lit), 419 | field('marker', "#"), 420 | $._bare_list_lit), 421 | 422 | regex_lit: $ => 423 | seq(field('marker', "#"), 424 | STRING), 425 | 426 | read_cond_lit: $ => 427 | seq(repeat($._metadata_lit), 428 | field('marker', "#?"), 429 | // whitespace possible, but neither comment nor discard 430 | repeat($._ws), 431 | $._bare_list_lit), 432 | 433 | splicing_read_cond_lit: $ => 434 | // XXX: metadata here doesn't seem to make sense, but the repl 435 | // will accept: [^:x #?@(:clj [[:a]] :cljr [[:b]])] 436 | seq(repeat($._metadata_lit), 437 | field('marker', "#?@"), 438 | // whitespace possible, but neither comment nor discard 439 | repeat($._ws), 440 | $._bare_list_lit), 441 | 442 | auto_res_mark: $ => 443 | AUTO_RESOLVE_MARK, 444 | 445 | ns_map_lit: $ => 446 | seq(repeat($._metadata_lit), 447 | field('marker', "#"), 448 | field('prefix', choice($.auto_res_mark, 449 | $.kwd_lit)), 450 | repeat($._gap), 451 | $._bare_map_lit), 452 | 453 | var_quoting_lit: $ => 454 | seq(repeat($._metadata_lit), 455 | field('marker', "#'"), 456 | repeat($._gap), 457 | // XXX: symbol, reader conditional, and tagged literal can work 458 | // any other things? 459 | field('value', $._form)), 460 | 461 | sym_val_lit: $ => 462 | seq(field('marker', "##"), 463 | repeat($._gap), 464 | field('value', $._form)), 465 | 466 | evaling_lit: $ => 467 | seq(repeat($._metadata_lit), // ^:x #=(vector 1) 468 | field('marker', "#="), 469 | repeat($._gap), 470 | field('value', choice($.list_lit, 471 | $.read_cond_lit, 472 | // #= ^:a java.lang.String 473 | $.sym_lit))), 474 | 475 | // #uuid "00000000-0000-0000-0000-000000000000" 476 | // #user.Fun[1 2] 477 | // #user.Fun{:a 1 :b 2} 478 | tagged_or_ctor_lit: $ => 479 | seq(repeat($._metadata_lit), 480 | field('marker', "#"), 481 | // # uuid "00000000-0000-0000-0000-000000000000" 482 | // # #_ 1 uuid "00000000-0000-0000-0000-000000000000" 483 | // etc. 484 | repeat($._gap), 485 | // # ^:a uuid "00000000-0000-0000-0000-000000000000" 486 | field('tag', $.sym_lit), 487 | repeat($._gap), 488 | field('value', $._form)), 489 | 490 | derefing_lit: $ => 491 | seq(repeat($._metadata_lit), 492 | field('marker', "@"), 493 | repeat($._gap), 494 | field('value', $._form)), 495 | 496 | quoting_lit: $ => 497 | seq(repeat($._metadata_lit), 498 | field('marker', "'"), 499 | repeat($._gap), 500 | field('value', $._form)), 501 | 502 | syn_quoting_lit: $ => 503 | seq(repeat($._metadata_lit), 504 | field('marker', "`"), 505 | repeat($._gap), 506 | field('value', $._form)), 507 | 508 | unquote_splicing_lit: $ => 509 | // XXX: metadata here doesn't seem to make sense, but the repl 510 | // will accept: `(^:x ~@[:a :b :c]) 511 | seq(repeat($._metadata_lit), 512 | field('marker', "~@"), 513 | repeat($._gap), 514 | field('value', $._form)), 515 | 516 | unquoting_lit: $ => 517 | seq(repeat($._metadata_lit), 518 | field('marker', "~"), 519 | repeat($._gap), 520 | field('value', $._form)), 521 | } 522 | }); 523 | 524 | // Local Variables: 525 | // mode: js-mode 526 | // js-indent-align-list-continuation: t 527 | // js-indent-level: 2 528 | // End: 529 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-sitter-clojure", 3 | "version": "0.0.13", 4 | "description": "Clojure grammar for tree-sitter", 5 | "tree-sitter": [ 6 | { 7 | "scope": "source.clojure", 8 | "file-types": [ 9 | "bb", 10 | "clj", 11 | "cljc", 12 | "cljs" 13 | ] 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /queries/highlights.scm: -------------------------------------------------------------------------------- 1 | ;; Literals 2 | 3 | (num_lit) @number 4 | 5 | [ 6 | (char_lit) 7 | (str_lit) 8 | ] @string 9 | 10 | [ 11 | (bool_lit) 12 | (nil_lit) 13 | ] @constant.builtin 14 | 15 | (kwd_lit) @constant 16 | 17 | ;; Comments 18 | 19 | (comment) @comment 20 | 21 | ;; Treat quasiquotation as operators for the purpose of highlighting. 22 | 23 | [ 24 | "'" 25 | "`" 26 | "~" 27 | "@" 28 | "~@" 29 | ] @operator 30 | -------------------------------------------------------------------------------- /src/grammar.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clojure", 3 | "rules": { 4 | "source": { 5 | "type": "REPEAT", 6 | "content": { 7 | "type": "CHOICE", 8 | "members": [ 9 | { 10 | "type": "SYMBOL", 11 | "name": "_form" 12 | }, 13 | { 14 | "type": "SYMBOL", 15 | "name": "_gap" 16 | } 17 | ] 18 | } 19 | }, 20 | "_gap": { 21 | "type": "CHOICE", 22 | "members": [ 23 | { 24 | "type": "SYMBOL", 25 | "name": "_ws" 26 | }, 27 | { 28 | "type": "SYMBOL", 29 | "name": "comment" 30 | }, 31 | { 32 | "type": "SYMBOL", 33 | "name": "dis_expr" 34 | } 35 | ] 36 | }, 37 | "_ws": { 38 | "type": "TOKEN", 39 | "content": { 40 | "type": "REPEAT1", 41 | "content": { 42 | "type": "PATTERN", 43 | "value": "[\\f\\n\\r\\t, \\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 44 | } 45 | } 46 | }, 47 | "comment": { 48 | "type": "TOKEN", 49 | "content": { 50 | "type": "PATTERN", 51 | "value": "(;|#!).*\\n?" 52 | } 53 | }, 54 | "dis_expr": { 55 | "type": "SEQ", 56 | "members": [ 57 | { 58 | "type": "FIELD", 59 | "name": "marker", 60 | "content": { 61 | "type": "STRING", 62 | "value": "#_" 63 | } 64 | }, 65 | { 66 | "type": "REPEAT", 67 | "content": { 68 | "type": "SYMBOL", 69 | "name": "_gap" 70 | } 71 | }, 72 | { 73 | "type": "FIELD", 74 | "name": "value", 75 | "content": { 76 | "type": "SYMBOL", 77 | "name": "_form" 78 | } 79 | } 80 | ] 81 | }, 82 | "_form": { 83 | "type": "CHOICE", 84 | "members": [ 85 | { 86 | "type": "SYMBOL", 87 | "name": "num_lit" 88 | }, 89 | { 90 | "type": "SYMBOL", 91 | "name": "kwd_lit" 92 | }, 93 | { 94 | "type": "SYMBOL", 95 | "name": "str_lit" 96 | }, 97 | { 98 | "type": "SYMBOL", 99 | "name": "char_lit" 100 | }, 101 | { 102 | "type": "SYMBOL", 103 | "name": "nil_lit" 104 | }, 105 | { 106 | "type": "SYMBOL", 107 | "name": "bool_lit" 108 | }, 109 | { 110 | "type": "SYMBOL", 111 | "name": "sym_lit" 112 | }, 113 | { 114 | "type": "SYMBOL", 115 | "name": "list_lit" 116 | }, 117 | { 118 | "type": "SYMBOL", 119 | "name": "map_lit" 120 | }, 121 | { 122 | "type": "SYMBOL", 123 | "name": "vec_lit" 124 | }, 125 | { 126 | "type": "SYMBOL", 127 | "name": "set_lit" 128 | }, 129 | { 130 | "type": "SYMBOL", 131 | "name": "anon_fn_lit" 132 | }, 133 | { 134 | "type": "SYMBOL", 135 | "name": "regex_lit" 136 | }, 137 | { 138 | "type": "SYMBOL", 139 | "name": "read_cond_lit" 140 | }, 141 | { 142 | "type": "SYMBOL", 143 | "name": "splicing_read_cond_lit" 144 | }, 145 | { 146 | "type": "SYMBOL", 147 | "name": "ns_map_lit" 148 | }, 149 | { 150 | "type": "SYMBOL", 151 | "name": "var_quoting_lit" 152 | }, 153 | { 154 | "type": "SYMBOL", 155 | "name": "sym_val_lit" 156 | }, 157 | { 158 | "type": "SYMBOL", 159 | "name": "evaling_lit" 160 | }, 161 | { 162 | "type": "SYMBOL", 163 | "name": "tagged_or_ctor_lit" 164 | }, 165 | { 166 | "type": "SYMBOL", 167 | "name": "derefing_lit" 168 | }, 169 | { 170 | "type": "SYMBOL", 171 | "name": "quoting_lit" 172 | }, 173 | { 174 | "type": "SYMBOL", 175 | "name": "syn_quoting_lit" 176 | }, 177 | { 178 | "type": "SYMBOL", 179 | "name": "unquote_splicing_lit" 180 | }, 181 | { 182 | "type": "SYMBOL", 183 | "name": "unquoting_lit" 184 | } 185 | ] 186 | }, 187 | "num_lit": { 188 | "type": "TOKEN", 189 | "content": { 190 | "type": "PREC", 191 | "value": 10, 192 | "content": { 193 | "type": "SEQ", 194 | "members": [ 195 | { 196 | "type": "CHOICE", 197 | "members": [ 198 | { 199 | "type": "PATTERN", 200 | "value": "[+-]" 201 | }, 202 | { 203 | "type": "BLANK" 204 | } 205 | ] 206 | }, 207 | { 208 | "type": "CHOICE", 209 | "members": [ 210 | { 211 | "type": "SEQ", 212 | "members": [ 213 | { 214 | "type": "STRING", 215 | "value": "0" 216 | }, 217 | { 218 | "type": "PATTERN", 219 | "value": "[xX]" 220 | }, 221 | { 222 | "type": "REPEAT1", 223 | "content": { 224 | "type": "PATTERN", 225 | "value": "[0-9a-fA-F]" 226 | } 227 | }, 228 | { 229 | "type": "CHOICE", 230 | "members": [ 231 | { 232 | "type": "STRING", 233 | "value": "N" 234 | }, 235 | { 236 | "type": "BLANK" 237 | } 238 | ] 239 | } 240 | ] 241 | }, 242 | { 243 | "type": "SEQ", 244 | "members": [ 245 | { 246 | "type": "STRING", 247 | "value": "0" 248 | }, 249 | { 250 | "type": "REPEAT1", 251 | "content": { 252 | "type": "PATTERN", 253 | "value": "[0-7]" 254 | } 255 | }, 256 | { 257 | "type": "CHOICE", 258 | "members": [ 259 | { 260 | "type": "STRING", 261 | "value": "N" 262 | }, 263 | { 264 | "type": "BLANK" 265 | } 266 | ] 267 | } 268 | ] 269 | }, 270 | { 271 | "type": "SEQ", 272 | "members": [ 273 | { 274 | "type": "REPEAT1", 275 | "content": { 276 | "type": "PATTERN", 277 | "value": "[0-9]" 278 | } 279 | }, 280 | { 281 | "type": "PATTERN", 282 | "value": "[rR]" 283 | }, 284 | { 285 | "type": "REPEAT1", 286 | "content": { 287 | "type": "PATTERN", 288 | "value": "[0-9a-zA-Z]" 289 | } 290 | } 291 | ] 292 | }, 293 | { 294 | "type": "SEQ", 295 | "members": [ 296 | { 297 | "type": "REPEAT1", 298 | "content": { 299 | "type": "PATTERN", 300 | "value": "[0-9]" 301 | } 302 | }, 303 | { 304 | "type": "STRING", 305 | "value": "/" 306 | }, 307 | { 308 | "type": "REPEAT1", 309 | "content": { 310 | "type": "PATTERN", 311 | "value": "[0-9]" 312 | } 313 | } 314 | ] 315 | }, 316 | { 317 | "type": "SEQ", 318 | "members": [ 319 | { 320 | "type": "REPEAT1", 321 | "content": { 322 | "type": "PATTERN", 323 | "value": "[0-9]" 324 | } 325 | }, 326 | { 327 | "type": "CHOICE", 328 | "members": [ 329 | { 330 | "type": "SEQ", 331 | "members": [ 332 | { 333 | "type": "STRING", 334 | "value": "." 335 | }, 336 | { 337 | "type": "REPEAT", 338 | "content": { 339 | "type": "PATTERN", 340 | "value": "[0-9]" 341 | } 342 | } 343 | ] 344 | }, 345 | { 346 | "type": "BLANK" 347 | } 348 | ] 349 | }, 350 | { 351 | "type": "CHOICE", 352 | "members": [ 353 | { 354 | "type": "SEQ", 355 | "members": [ 356 | { 357 | "type": "PATTERN", 358 | "value": "[eE]" 359 | }, 360 | { 361 | "type": "CHOICE", 362 | "members": [ 363 | { 364 | "type": "PATTERN", 365 | "value": "[+-]" 366 | }, 367 | { 368 | "type": "BLANK" 369 | } 370 | ] 371 | }, 372 | { 373 | "type": "REPEAT1", 374 | "content": { 375 | "type": "PATTERN", 376 | "value": "[0-9]" 377 | } 378 | } 379 | ] 380 | }, 381 | { 382 | "type": "BLANK" 383 | } 384 | ] 385 | }, 386 | { 387 | "type": "CHOICE", 388 | "members": [ 389 | { 390 | "type": "STRING", 391 | "value": "M" 392 | }, 393 | { 394 | "type": "BLANK" 395 | } 396 | ] 397 | } 398 | ] 399 | }, 400 | { 401 | "type": "SEQ", 402 | "members": [ 403 | { 404 | "type": "REPEAT1", 405 | "content": { 406 | "type": "PATTERN", 407 | "value": "[0-9]" 408 | } 409 | }, 410 | { 411 | "type": "CHOICE", 412 | "members": [ 413 | { 414 | "type": "PATTERN", 415 | "value": "[MN]" 416 | }, 417 | { 418 | "type": "BLANK" 419 | } 420 | ] 421 | } 422 | ] 423 | } 424 | ] 425 | } 426 | ] 427 | } 428 | } 429 | }, 430 | "kwd_lit": { 431 | "type": "CHOICE", 432 | "members": [ 433 | { 434 | "type": "SYMBOL", 435 | "name": "_kwd_leading_slash" 436 | }, 437 | { 438 | "type": "SYMBOL", 439 | "name": "_kwd_just_slash" 440 | }, 441 | { 442 | "type": "SYMBOL", 443 | "name": "_kwd_qualified" 444 | }, 445 | { 446 | "type": "SYMBOL", 447 | "name": "_kwd_unqualified" 448 | } 449 | ] 450 | }, 451 | "_kwd_leading_slash": { 452 | "type": "SEQ", 453 | "members": [ 454 | { 455 | "type": "FIELD", 456 | "name": "marker", 457 | "content": { 458 | "type": "SYMBOL", 459 | "name": "_kwd_marker" 460 | } 461 | }, 462 | { 463 | "type": "FIELD", 464 | "name": "delimiter", 465 | "content": { 466 | "type": "TOKEN", 467 | "content": { 468 | "type": "STRING", 469 | "value": "/" 470 | } 471 | } 472 | }, 473 | { 474 | "type": "FIELD", 475 | "name": "name", 476 | "content": { 477 | "type": "ALIAS", 478 | "content": { 479 | "type": "TOKEN", 480 | "content": { 481 | "type": "REPEAT1", 482 | "content": { 483 | "type": "CHOICE", 484 | "members": [ 485 | { 486 | "type": "PATTERN", 487 | "value": "[:'/]" 488 | }, 489 | { 490 | "type": "PATTERN", 491 | "value": "[^\\f\\n\\r\\t ()\\[\\]{}\"@~^;`\\\\,:/\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 492 | } 493 | ] 494 | } 495 | } 496 | }, 497 | "named": true, 498 | "value": "kwd_name" 499 | } 500 | } 501 | ] 502 | }, 503 | "_kwd_just_slash": { 504 | "type": "SEQ", 505 | "members": [ 506 | { 507 | "type": "FIELD", 508 | "name": "marker", 509 | "content": { 510 | "type": "SYMBOL", 511 | "name": "_kwd_marker" 512 | } 513 | }, 514 | { 515 | "type": "FIELD", 516 | "name": "name", 517 | "content": { 518 | "type": "ALIAS", 519 | "content": { 520 | "type": "TOKEN", 521 | "content": { 522 | "type": "STRING", 523 | "value": "/" 524 | } 525 | }, 526 | "named": true, 527 | "value": "kwd_name" 528 | } 529 | } 530 | ] 531 | }, 532 | "_kwd_qualified": { 533 | "type": "PREC", 534 | "value": 2, 535 | "content": { 536 | "type": "SEQ", 537 | "members": [ 538 | { 539 | "type": "FIELD", 540 | "name": "marker", 541 | "content": { 542 | "type": "SYMBOL", 543 | "name": "_kwd_marker" 544 | } 545 | }, 546 | { 547 | "type": "FIELD", 548 | "name": "namespace", 549 | "content": { 550 | "type": "ALIAS", 551 | "content": { 552 | "type": "TOKEN", 553 | "content": { 554 | "type": "SEQ", 555 | "members": [ 556 | { 557 | "type": "PATTERN", 558 | "value": "[^\\f\\n\\r\\t ()\\[\\]{}\"@~^;`\\\\,:/\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 559 | }, 560 | { 561 | "type": "REPEAT", 562 | "content": { 563 | "type": "CHOICE", 564 | "members": [ 565 | { 566 | "type": "PATTERN", 567 | "value": "[:']" 568 | }, 569 | { 570 | "type": "PATTERN", 571 | "value": "[^\\f\\n\\r\\t ()\\[\\]{}\"@~^;`\\\\,:/\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 572 | } 573 | ] 574 | } 575 | } 576 | ] 577 | } 578 | }, 579 | "named": true, 580 | "value": "kwd_ns" 581 | } 582 | }, 583 | { 584 | "type": "FIELD", 585 | "name": "delimiter", 586 | "content": { 587 | "type": "TOKEN", 588 | "content": { 589 | "type": "STRING", 590 | "value": "/" 591 | } 592 | } 593 | }, 594 | { 595 | "type": "FIELD", 596 | "name": "name", 597 | "content": { 598 | "type": "ALIAS", 599 | "content": { 600 | "type": "TOKEN", 601 | "content": { 602 | "type": "REPEAT1", 603 | "content": { 604 | "type": "CHOICE", 605 | "members": [ 606 | { 607 | "type": "PATTERN", 608 | "value": "[:'/]" 609 | }, 610 | { 611 | "type": "PATTERN", 612 | "value": "[^\\f\\n\\r\\t ()\\[\\]{}\"@~^;`\\\\,:/\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 613 | } 614 | ] 615 | } 616 | } 617 | }, 618 | "named": true, 619 | "value": "kwd_name" 620 | } 621 | } 622 | ] 623 | } 624 | }, 625 | "_kwd_unqualified": { 626 | "type": "PREC", 627 | "value": 1, 628 | "content": { 629 | "type": "SEQ", 630 | "members": [ 631 | { 632 | "type": "FIELD", 633 | "name": "marker", 634 | "content": { 635 | "type": "SYMBOL", 636 | "name": "_kwd_marker" 637 | } 638 | }, 639 | { 640 | "type": "FIELD", 641 | "name": "name", 642 | "content": { 643 | "type": "ALIAS", 644 | "content": { 645 | "type": "TOKEN", 646 | "content": { 647 | "type": "SEQ", 648 | "members": [ 649 | { 650 | "type": "PATTERN", 651 | "value": "[^\\f\\n\\r\\t ()\\[\\]{}\"@~^;`\\\\,:/\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 652 | }, 653 | { 654 | "type": "REPEAT", 655 | "content": { 656 | "type": "CHOICE", 657 | "members": [ 658 | { 659 | "type": "PATTERN", 660 | "value": "[:']" 661 | }, 662 | { 663 | "type": "PATTERN", 664 | "value": "[^\\f\\n\\r\\t ()\\[\\]{}\"@~^;`\\\\,:/\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 665 | } 666 | ] 667 | } 668 | } 669 | ] 670 | } 671 | }, 672 | "named": true, 673 | "value": "kwd_name" 674 | } 675 | } 676 | ] 677 | } 678 | }, 679 | "_kwd_marker": { 680 | "type": "CHOICE", 681 | "members": [ 682 | { 683 | "type": "TOKEN", 684 | "content": { 685 | "type": "STRING", 686 | "value": ":" 687 | } 688 | }, 689 | { 690 | "type": "TOKEN", 691 | "content": { 692 | "type": "STRING", 693 | "value": "::" 694 | } 695 | } 696 | ] 697 | }, 698 | "str_lit": { 699 | "type": "TOKEN", 700 | "content": { 701 | "type": "SEQ", 702 | "members": [ 703 | { 704 | "type": "STRING", 705 | "value": "\"" 706 | }, 707 | { 708 | "type": "REPEAT", 709 | "content": { 710 | "type": "PATTERN", 711 | "value": "[^\"\\\\]" 712 | } 713 | }, 714 | { 715 | "type": "REPEAT", 716 | "content": { 717 | "type": "SEQ", 718 | "members": [ 719 | { 720 | "type": "STRING", 721 | "value": "\\" 722 | }, 723 | { 724 | "type": "PATTERN", 725 | "value": "." 726 | }, 727 | { 728 | "type": "REPEAT", 729 | "content": { 730 | "type": "PATTERN", 731 | "value": "[^\"\\\\]" 732 | } 733 | } 734 | ] 735 | } 736 | }, 737 | { 738 | "type": "STRING", 739 | "value": "\"" 740 | } 741 | ] 742 | } 743 | }, 744 | "char_lit": { 745 | "type": "TOKEN", 746 | "content": { 747 | "type": "SEQ", 748 | "members": [ 749 | { 750 | "type": "STRING", 751 | "value": "\\" 752 | }, 753 | { 754 | "type": "CHOICE", 755 | "members": [ 756 | { 757 | "type": "SEQ", 758 | "members": [ 759 | { 760 | "type": "STRING", 761 | "value": "o" 762 | }, 763 | { 764 | "type": "CHOICE", 765 | "members": [ 766 | { 767 | "type": "SEQ", 768 | "members": [ 769 | { 770 | "type": "PATTERN", 771 | "value": "[0-9]" 772 | }, 773 | { 774 | "type": "PATTERN", 775 | "value": "[0-9]" 776 | }, 777 | { 778 | "type": "PATTERN", 779 | "value": "[0-9]" 780 | } 781 | ] 782 | }, 783 | { 784 | "type": "SEQ", 785 | "members": [ 786 | { 787 | "type": "PATTERN", 788 | "value": "[0-9]" 789 | }, 790 | { 791 | "type": "PATTERN", 792 | "value": "[0-9]" 793 | } 794 | ] 795 | }, 796 | { 797 | "type": "SEQ", 798 | "members": [ 799 | { 800 | "type": "PATTERN", 801 | "value": "[0-9]" 802 | } 803 | ] 804 | } 805 | ] 806 | } 807 | ] 808 | }, 809 | { 810 | "type": "CHOICE", 811 | "members": [ 812 | { 813 | "type": "STRING", 814 | "value": "backspace" 815 | }, 816 | { 817 | "type": "STRING", 818 | "value": "formfeed" 819 | }, 820 | { 821 | "type": "STRING", 822 | "value": "newline" 823 | }, 824 | { 825 | "type": "STRING", 826 | "value": "return" 827 | }, 828 | { 829 | "type": "STRING", 830 | "value": "space" 831 | }, 832 | { 833 | "type": "STRING", 834 | "value": "tab" 835 | } 836 | ] 837 | }, 838 | { 839 | "type": "SEQ", 840 | "members": [ 841 | { 842 | "type": "STRING", 843 | "value": "u" 844 | }, 845 | { 846 | "type": "PATTERN", 847 | "value": "[0-9a-fA-F]" 848 | }, 849 | { 850 | "type": "PATTERN", 851 | "value": "[0-9a-fA-F]" 852 | }, 853 | { 854 | "type": "PATTERN", 855 | "value": "[0-9a-fA-F]" 856 | }, 857 | { 858 | "type": "PATTERN", 859 | "value": "[0-9a-fA-F]" 860 | } 861 | ] 862 | }, 863 | { 864 | "type": "PATTERN", 865 | "value": ".|\\n" 866 | } 867 | ] 868 | } 869 | ] 870 | } 871 | }, 872 | "nil_lit": { 873 | "type": "TOKEN", 874 | "content": { 875 | "type": "STRING", 876 | "value": "nil" 877 | } 878 | }, 879 | "bool_lit": { 880 | "type": "TOKEN", 881 | "content": { 882 | "type": "CHOICE", 883 | "members": [ 884 | { 885 | "type": "STRING", 886 | "value": "false" 887 | }, 888 | { 889 | "type": "STRING", 890 | "value": "true" 891 | } 892 | ] 893 | } 894 | }, 895 | "sym_lit": { 896 | "type": "SEQ", 897 | "members": [ 898 | { 899 | "type": "REPEAT", 900 | "content": { 901 | "type": "SYMBOL", 902 | "name": "_metadata_lit" 903 | } 904 | }, 905 | { 906 | "type": "CHOICE", 907 | "members": [ 908 | { 909 | "type": "SYMBOL", 910 | "name": "_sym_qualified" 911 | }, 912 | { 913 | "type": "SYMBOL", 914 | "name": "_sym_unqualified" 915 | } 916 | ] 917 | } 918 | ] 919 | }, 920 | "_sym_qualified": { 921 | "type": "PREC", 922 | "value": 1, 923 | "content": { 924 | "type": "SEQ", 925 | "members": [ 926 | { 927 | "type": "FIELD", 928 | "name": "namespace", 929 | "content": { 930 | "type": "ALIAS", 931 | "content": { 932 | "type": "TOKEN", 933 | "content": { 934 | "type": "SEQ", 935 | "members": [ 936 | { 937 | "type": "PATTERN", 938 | "value": "[^\\f\\n\\r\\t /()\\[\\]{}\"@~^;`\\\\,:#'0-9\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 939 | }, 940 | { 941 | "type": "REPEAT", 942 | "content": { 943 | "type": "CHOICE", 944 | "members": [ 945 | { 946 | "type": "PATTERN", 947 | "value": "[^\\f\\n\\r\\t /()\\[\\]{}\"@~^;`\\\\,:#'0-9\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 948 | }, 949 | { 950 | "type": "PATTERN", 951 | "value": "[:#'0-9]" 952 | } 953 | ] 954 | } 955 | } 956 | ] 957 | } 958 | }, 959 | "named": true, 960 | "value": "sym_ns" 961 | } 962 | }, 963 | { 964 | "type": "FIELD", 965 | "name": "delimiter", 966 | "content": { 967 | "type": "TOKEN", 968 | "content": { 969 | "type": "STRING", 970 | "value": "/" 971 | } 972 | } 973 | }, 974 | { 975 | "type": "FIELD", 976 | "name": "name", 977 | "content": { 978 | "type": "ALIAS", 979 | "content": { 980 | "type": "TOKEN", 981 | "content": { 982 | "type": "REPEAT1", 983 | "content": { 984 | "type": "CHOICE", 985 | "members": [ 986 | { 987 | "type": "PATTERN", 988 | "value": "[^\\f\\n\\r\\t /()\\[\\]{}\"@~^;`\\\\,:#'0-9\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 989 | }, 990 | { 991 | "type": "PATTERN", 992 | "value": "[/:#'0-9]" 993 | } 994 | ] 995 | } 996 | } 997 | }, 998 | "named": true, 999 | "value": "sym_name" 1000 | } 1001 | } 1002 | ] 1003 | } 1004 | }, 1005 | "_sym_unqualified": { 1006 | "type": "FIELD", 1007 | "name": "name", 1008 | "content": { 1009 | "type": "ALIAS", 1010 | "content": { 1011 | "type": "CHOICE", 1012 | "members": [ 1013 | { 1014 | "type": "TOKEN", 1015 | "content": { 1016 | "type": "STRING", 1017 | "value": "/" 1018 | } 1019 | }, 1020 | { 1021 | "type": "TOKEN", 1022 | "content": { 1023 | "type": "SEQ", 1024 | "members": [ 1025 | { 1026 | "type": "PATTERN", 1027 | "value": "[^\\f\\n\\r\\t /()\\[\\]{}\"@~^;`\\\\,:#'0-9\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 1028 | }, 1029 | { 1030 | "type": "REPEAT", 1031 | "content": { 1032 | "type": "CHOICE", 1033 | "members": [ 1034 | { 1035 | "type": "PATTERN", 1036 | "value": "[^\\f\\n\\r\\t /()\\[\\]{}\"@~^;`\\\\,:#'0-9\\u000B\\u001C\\u001D\\u001E\\u001F\\u2028\\u2029\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2008\\u2009\\u200a\\u205f\\u3000]" 1037 | }, 1038 | { 1039 | "type": "PATTERN", 1040 | "value": "[:#'0-9]" 1041 | } 1042 | ] 1043 | } 1044 | } 1045 | ] 1046 | } 1047 | } 1048 | ] 1049 | }, 1050 | "named": true, 1051 | "value": "sym_name" 1052 | } 1053 | }, 1054 | "_metadata_lit": { 1055 | "type": "SEQ", 1056 | "members": [ 1057 | { 1058 | "type": "CHOICE", 1059 | "members": [ 1060 | { 1061 | "type": "FIELD", 1062 | "name": "meta", 1063 | "content": { 1064 | "type": "SYMBOL", 1065 | "name": "meta_lit" 1066 | } 1067 | }, 1068 | { 1069 | "type": "FIELD", 1070 | "name": "old_meta", 1071 | "content": { 1072 | "type": "SYMBOL", 1073 | "name": "old_meta_lit" 1074 | } 1075 | } 1076 | ] 1077 | }, 1078 | { 1079 | "type": "CHOICE", 1080 | "members": [ 1081 | { 1082 | "type": "REPEAT", 1083 | "content": { 1084 | "type": "SYMBOL", 1085 | "name": "_gap" 1086 | } 1087 | }, 1088 | { 1089 | "type": "BLANK" 1090 | } 1091 | ] 1092 | } 1093 | ] 1094 | }, 1095 | "meta_lit": { 1096 | "type": "SEQ", 1097 | "members": [ 1098 | { 1099 | "type": "FIELD", 1100 | "name": "marker", 1101 | "content": { 1102 | "type": "STRING", 1103 | "value": "^" 1104 | } 1105 | }, 1106 | { 1107 | "type": "REPEAT", 1108 | "content": { 1109 | "type": "SYMBOL", 1110 | "name": "_gap" 1111 | } 1112 | }, 1113 | { 1114 | "type": "FIELD", 1115 | "name": "value", 1116 | "content": { 1117 | "type": "SYMBOL", 1118 | "name": "_form" 1119 | } 1120 | } 1121 | ] 1122 | }, 1123 | "old_meta_lit": { 1124 | "type": "SEQ", 1125 | "members": [ 1126 | { 1127 | "type": "FIELD", 1128 | "name": "marker", 1129 | "content": { 1130 | "type": "STRING", 1131 | "value": "#^" 1132 | } 1133 | }, 1134 | { 1135 | "type": "REPEAT", 1136 | "content": { 1137 | "type": "SYMBOL", 1138 | "name": "_gap" 1139 | } 1140 | }, 1141 | { 1142 | "type": "FIELD", 1143 | "name": "value", 1144 | "content": { 1145 | "type": "SYMBOL", 1146 | "name": "_form" 1147 | } 1148 | } 1149 | ] 1150 | }, 1151 | "list_lit": { 1152 | "type": "SEQ", 1153 | "members": [ 1154 | { 1155 | "type": "REPEAT", 1156 | "content": { 1157 | "type": "SYMBOL", 1158 | "name": "_metadata_lit" 1159 | } 1160 | }, 1161 | { 1162 | "type": "SYMBOL", 1163 | "name": "_bare_list_lit" 1164 | } 1165 | ] 1166 | }, 1167 | "_bare_list_lit": { 1168 | "type": "SEQ", 1169 | "members": [ 1170 | { 1171 | "type": "FIELD", 1172 | "name": "open", 1173 | "content": { 1174 | "type": "STRING", 1175 | "value": "(" 1176 | } 1177 | }, 1178 | { 1179 | "type": "REPEAT", 1180 | "content": { 1181 | "type": "CHOICE", 1182 | "members": [ 1183 | { 1184 | "type": "FIELD", 1185 | "name": "value", 1186 | "content": { 1187 | "type": "SYMBOL", 1188 | "name": "_form" 1189 | } 1190 | }, 1191 | { 1192 | "type": "SYMBOL", 1193 | "name": "_gap" 1194 | } 1195 | ] 1196 | } 1197 | }, 1198 | { 1199 | "type": "FIELD", 1200 | "name": "close", 1201 | "content": { 1202 | "type": "STRING", 1203 | "value": ")" 1204 | } 1205 | } 1206 | ] 1207 | }, 1208 | "map_lit": { 1209 | "type": "SEQ", 1210 | "members": [ 1211 | { 1212 | "type": "REPEAT", 1213 | "content": { 1214 | "type": "SYMBOL", 1215 | "name": "_metadata_lit" 1216 | } 1217 | }, 1218 | { 1219 | "type": "SYMBOL", 1220 | "name": "_bare_map_lit" 1221 | } 1222 | ] 1223 | }, 1224 | "_bare_map_lit": { 1225 | "type": "SEQ", 1226 | "members": [ 1227 | { 1228 | "type": "FIELD", 1229 | "name": "open", 1230 | "content": { 1231 | "type": "STRING", 1232 | "value": "{" 1233 | } 1234 | }, 1235 | { 1236 | "type": "REPEAT", 1237 | "content": { 1238 | "type": "CHOICE", 1239 | "members": [ 1240 | { 1241 | "type": "FIELD", 1242 | "name": "value", 1243 | "content": { 1244 | "type": "SYMBOL", 1245 | "name": "_form" 1246 | } 1247 | }, 1248 | { 1249 | "type": "SYMBOL", 1250 | "name": "_gap" 1251 | } 1252 | ] 1253 | } 1254 | }, 1255 | { 1256 | "type": "FIELD", 1257 | "name": "close", 1258 | "content": { 1259 | "type": "STRING", 1260 | "value": "}" 1261 | } 1262 | } 1263 | ] 1264 | }, 1265 | "vec_lit": { 1266 | "type": "SEQ", 1267 | "members": [ 1268 | { 1269 | "type": "REPEAT", 1270 | "content": { 1271 | "type": "SYMBOL", 1272 | "name": "_metadata_lit" 1273 | } 1274 | }, 1275 | { 1276 | "type": "SYMBOL", 1277 | "name": "_bare_vec_lit" 1278 | } 1279 | ] 1280 | }, 1281 | "_bare_vec_lit": { 1282 | "type": "SEQ", 1283 | "members": [ 1284 | { 1285 | "type": "FIELD", 1286 | "name": "open", 1287 | "content": { 1288 | "type": "STRING", 1289 | "value": "[" 1290 | } 1291 | }, 1292 | { 1293 | "type": "REPEAT", 1294 | "content": { 1295 | "type": "CHOICE", 1296 | "members": [ 1297 | { 1298 | "type": "FIELD", 1299 | "name": "value", 1300 | "content": { 1301 | "type": "SYMBOL", 1302 | "name": "_form" 1303 | } 1304 | }, 1305 | { 1306 | "type": "SYMBOL", 1307 | "name": "_gap" 1308 | } 1309 | ] 1310 | } 1311 | }, 1312 | { 1313 | "type": "FIELD", 1314 | "name": "close", 1315 | "content": { 1316 | "type": "STRING", 1317 | "value": "]" 1318 | } 1319 | } 1320 | ] 1321 | }, 1322 | "set_lit": { 1323 | "type": "SEQ", 1324 | "members": [ 1325 | { 1326 | "type": "REPEAT", 1327 | "content": { 1328 | "type": "SYMBOL", 1329 | "name": "_metadata_lit" 1330 | } 1331 | }, 1332 | { 1333 | "type": "SYMBOL", 1334 | "name": "_bare_set_lit" 1335 | } 1336 | ] 1337 | }, 1338 | "_bare_set_lit": { 1339 | "type": "SEQ", 1340 | "members": [ 1341 | { 1342 | "type": "FIELD", 1343 | "name": "marker", 1344 | "content": { 1345 | "type": "STRING", 1346 | "value": "#" 1347 | } 1348 | }, 1349 | { 1350 | "type": "FIELD", 1351 | "name": "open", 1352 | "content": { 1353 | "type": "STRING", 1354 | "value": "{" 1355 | } 1356 | }, 1357 | { 1358 | "type": "REPEAT", 1359 | "content": { 1360 | "type": "CHOICE", 1361 | "members": [ 1362 | { 1363 | "type": "FIELD", 1364 | "name": "value", 1365 | "content": { 1366 | "type": "SYMBOL", 1367 | "name": "_form" 1368 | } 1369 | }, 1370 | { 1371 | "type": "SYMBOL", 1372 | "name": "_gap" 1373 | } 1374 | ] 1375 | } 1376 | }, 1377 | { 1378 | "type": "FIELD", 1379 | "name": "close", 1380 | "content": { 1381 | "type": "STRING", 1382 | "value": "}" 1383 | } 1384 | } 1385 | ] 1386 | }, 1387 | "anon_fn_lit": { 1388 | "type": "SEQ", 1389 | "members": [ 1390 | { 1391 | "type": "REPEAT", 1392 | "content": { 1393 | "type": "SYMBOL", 1394 | "name": "_metadata_lit" 1395 | } 1396 | }, 1397 | { 1398 | "type": "FIELD", 1399 | "name": "marker", 1400 | "content": { 1401 | "type": "STRING", 1402 | "value": "#" 1403 | } 1404 | }, 1405 | { 1406 | "type": "SYMBOL", 1407 | "name": "_bare_list_lit" 1408 | } 1409 | ] 1410 | }, 1411 | "regex_lit": { 1412 | "type": "SEQ", 1413 | "members": [ 1414 | { 1415 | "type": "FIELD", 1416 | "name": "marker", 1417 | "content": { 1418 | "type": "STRING", 1419 | "value": "#" 1420 | } 1421 | }, 1422 | { 1423 | "type": "TOKEN", 1424 | "content": { 1425 | "type": "SEQ", 1426 | "members": [ 1427 | { 1428 | "type": "STRING", 1429 | "value": "\"" 1430 | }, 1431 | { 1432 | "type": "REPEAT", 1433 | "content": { 1434 | "type": "PATTERN", 1435 | "value": "[^\"\\\\]" 1436 | } 1437 | }, 1438 | { 1439 | "type": "REPEAT", 1440 | "content": { 1441 | "type": "SEQ", 1442 | "members": [ 1443 | { 1444 | "type": "STRING", 1445 | "value": "\\" 1446 | }, 1447 | { 1448 | "type": "PATTERN", 1449 | "value": "." 1450 | }, 1451 | { 1452 | "type": "REPEAT", 1453 | "content": { 1454 | "type": "PATTERN", 1455 | "value": "[^\"\\\\]" 1456 | } 1457 | } 1458 | ] 1459 | } 1460 | }, 1461 | { 1462 | "type": "STRING", 1463 | "value": "\"" 1464 | } 1465 | ] 1466 | } 1467 | } 1468 | ] 1469 | }, 1470 | "read_cond_lit": { 1471 | "type": "SEQ", 1472 | "members": [ 1473 | { 1474 | "type": "REPEAT", 1475 | "content": { 1476 | "type": "SYMBOL", 1477 | "name": "_metadata_lit" 1478 | } 1479 | }, 1480 | { 1481 | "type": "FIELD", 1482 | "name": "marker", 1483 | "content": { 1484 | "type": "STRING", 1485 | "value": "#?" 1486 | } 1487 | }, 1488 | { 1489 | "type": "REPEAT", 1490 | "content": { 1491 | "type": "SYMBOL", 1492 | "name": "_ws" 1493 | } 1494 | }, 1495 | { 1496 | "type": "SYMBOL", 1497 | "name": "_bare_list_lit" 1498 | } 1499 | ] 1500 | }, 1501 | "splicing_read_cond_lit": { 1502 | "type": "SEQ", 1503 | "members": [ 1504 | { 1505 | "type": "REPEAT", 1506 | "content": { 1507 | "type": "SYMBOL", 1508 | "name": "_metadata_lit" 1509 | } 1510 | }, 1511 | { 1512 | "type": "FIELD", 1513 | "name": "marker", 1514 | "content": { 1515 | "type": "STRING", 1516 | "value": "#?@" 1517 | } 1518 | }, 1519 | { 1520 | "type": "REPEAT", 1521 | "content": { 1522 | "type": "SYMBOL", 1523 | "name": "_ws" 1524 | } 1525 | }, 1526 | { 1527 | "type": "SYMBOL", 1528 | "name": "_bare_list_lit" 1529 | } 1530 | ] 1531 | }, 1532 | "auto_res_mark": { 1533 | "type": "TOKEN", 1534 | "content": { 1535 | "type": "STRING", 1536 | "value": "::" 1537 | } 1538 | }, 1539 | "ns_map_lit": { 1540 | "type": "SEQ", 1541 | "members": [ 1542 | { 1543 | "type": "REPEAT", 1544 | "content": { 1545 | "type": "SYMBOL", 1546 | "name": "_metadata_lit" 1547 | } 1548 | }, 1549 | { 1550 | "type": "FIELD", 1551 | "name": "marker", 1552 | "content": { 1553 | "type": "STRING", 1554 | "value": "#" 1555 | } 1556 | }, 1557 | { 1558 | "type": "FIELD", 1559 | "name": "prefix", 1560 | "content": { 1561 | "type": "CHOICE", 1562 | "members": [ 1563 | { 1564 | "type": "SYMBOL", 1565 | "name": "auto_res_mark" 1566 | }, 1567 | { 1568 | "type": "SYMBOL", 1569 | "name": "kwd_lit" 1570 | } 1571 | ] 1572 | } 1573 | }, 1574 | { 1575 | "type": "REPEAT", 1576 | "content": { 1577 | "type": "SYMBOL", 1578 | "name": "_gap" 1579 | } 1580 | }, 1581 | { 1582 | "type": "SYMBOL", 1583 | "name": "_bare_map_lit" 1584 | } 1585 | ] 1586 | }, 1587 | "var_quoting_lit": { 1588 | "type": "SEQ", 1589 | "members": [ 1590 | { 1591 | "type": "REPEAT", 1592 | "content": { 1593 | "type": "SYMBOL", 1594 | "name": "_metadata_lit" 1595 | } 1596 | }, 1597 | { 1598 | "type": "FIELD", 1599 | "name": "marker", 1600 | "content": { 1601 | "type": "STRING", 1602 | "value": "#'" 1603 | } 1604 | }, 1605 | { 1606 | "type": "REPEAT", 1607 | "content": { 1608 | "type": "SYMBOL", 1609 | "name": "_gap" 1610 | } 1611 | }, 1612 | { 1613 | "type": "FIELD", 1614 | "name": "value", 1615 | "content": { 1616 | "type": "SYMBOL", 1617 | "name": "_form" 1618 | } 1619 | } 1620 | ] 1621 | }, 1622 | "sym_val_lit": { 1623 | "type": "SEQ", 1624 | "members": [ 1625 | { 1626 | "type": "FIELD", 1627 | "name": "marker", 1628 | "content": { 1629 | "type": "STRING", 1630 | "value": "##" 1631 | } 1632 | }, 1633 | { 1634 | "type": "REPEAT", 1635 | "content": { 1636 | "type": "SYMBOL", 1637 | "name": "_gap" 1638 | } 1639 | }, 1640 | { 1641 | "type": "FIELD", 1642 | "name": "value", 1643 | "content": { 1644 | "type": "SYMBOL", 1645 | "name": "_form" 1646 | } 1647 | } 1648 | ] 1649 | }, 1650 | "evaling_lit": { 1651 | "type": "SEQ", 1652 | "members": [ 1653 | { 1654 | "type": "REPEAT", 1655 | "content": { 1656 | "type": "SYMBOL", 1657 | "name": "_metadata_lit" 1658 | } 1659 | }, 1660 | { 1661 | "type": "FIELD", 1662 | "name": "marker", 1663 | "content": { 1664 | "type": "STRING", 1665 | "value": "#=" 1666 | } 1667 | }, 1668 | { 1669 | "type": "REPEAT", 1670 | "content": { 1671 | "type": "SYMBOL", 1672 | "name": "_gap" 1673 | } 1674 | }, 1675 | { 1676 | "type": "FIELD", 1677 | "name": "value", 1678 | "content": { 1679 | "type": "CHOICE", 1680 | "members": [ 1681 | { 1682 | "type": "SYMBOL", 1683 | "name": "list_lit" 1684 | }, 1685 | { 1686 | "type": "SYMBOL", 1687 | "name": "read_cond_lit" 1688 | }, 1689 | { 1690 | "type": "SYMBOL", 1691 | "name": "sym_lit" 1692 | } 1693 | ] 1694 | } 1695 | } 1696 | ] 1697 | }, 1698 | "tagged_or_ctor_lit": { 1699 | "type": "SEQ", 1700 | "members": [ 1701 | { 1702 | "type": "REPEAT", 1703 | "content": { 1704 | "type": "SYMBOL", 1705 | "name": "_metadata_lit" 1706 | } 1707 | }, 1708 | { 1709 | "type": "FIELD", 1710 | "name": "marker", 1711 | "content": { 1712 | "type": "STRING", 1713 | "value": "#" 1714 | } 1715 | }, 1716 | { 1717 | "type": "REPEAT", 1718 | "content": { 1719 | "type": "SYMBOL", 1720 | "name": "_gap" 1721 | } 1722 | }, 1723 | { 1724 | "type": "FIELD", 1725 | "name": "tag", 1726 | "content": { 1727 | "type": "SYMBOL", 1728 | "name": "sym_lit" 1729 | } 1730 | }, 1731 | { 1732 | "type": "REPEAT", 1733 | "content": { 1734 | "type": "SYMBOL", 1735 | "name": "_gap" 1736 | } 1737 | }, 1738 | { 1739 | "type": "FIELD", 1740 | "name": "value", 1741 | "content": { 1742 | "type": "SYMBOL", 1743 | "name": "_form" 1744 | } 1745 | } 1746 | ] 1747 | }, 1748 | "derefing_lit": { 1749 | "type": "SEQ", 1750 | "members": [ 1751 | { 1752 | "type": "REPEAT", 1753 | "content": { 1754 | "type": "SYMBOL", 1755 | "name": "_metadata_lit" 1756 | } 1757 | }, 1758 | { 1759 | "type": "FIELD", 1760 | "name": "marker", 1761 | "content": { 1762 | "type": "STRING", 1763 | "value": "@" 1764 | } 1765 | }, 1766 | { 1767 | "type": "REPEAT", 1768 | "content": { 1769 | "type": "SYMBOL", 1770 | "name": "_gap" 1771 | } 1772 | }, 1773 | { 1774 | "type": "FIELD", 1775 | "name": "value", 1776 | "content": { 1777 | "type": "SYMBOL", 1778 | "name": "_form" 1779 | } 1780 | } 1781 | ] 1782 | }, 1783 | "quoting_lit": { 1784 | "type": "SEQ", 1785 | "members": [ 1786 | { 1787 | "type": "REPEAT", 1788 | "content": { 1789 | "type": "SYMBOL", 1790 | "name": "_metadata_lit" 1791 | } 1792 | }, 1793 | { 1794 | "type": "FIELD", 1795 | "name": "marker", 1796 | "content": { 1797 | "type": "STRING", 1798 | "value": "'" 1799 | } 1800 | }, 1801 | { 1802 | "type": "REPEAT", 1803 | "content": { 1804 | "type": "SYMBOL", 1805 | "name": "_gap" 1806 | } 1807 | }, 1808 | { 1809 | "type": "FIELD", 1810 | "name": "value", 1811 | "content": { 1812 | "type": "SYMBOL", 1813 | "name": "_form" 1814 | } 1815 | } 1816 | ] 1817 | }, 1818 | "syn_quoting_lit": { 1819 | "type": "SEQ", 1820 | "members": [ 1821 | { 1822 | "type": "REPEAT", 1823 | "content": { 1824 | "type": "SYMBOL", 1825 | "name": "_metadata_lit" 1826 | } 1827 | }, 1828 | { 1829 | "type": "FIELD", 1830 | "name": "marker", 1831 | "content": { 1832 | "type": "STRING", 1833 | "value": "`" 1834 | } 1835 | }, 1836 | { 1837 | "type": "REPEAT", 1838 | "content": { 1839 | "type": "SYMBOL", 1840 | "name": "_gap" 1841 | } 1842 | }, 1843 | { 1844 | "type": "FIELD", 1845 | "name": "value", 1846 | "content": { 1847 | "type": "SYMBOL", 1848 | "name": "_form" 1849 | } 1850 | } 1851 | ] 1852 | }, 1853 | "unquote_splicing_lit": { 1854 | "type": "SEQ", 1855 | "members": [ 1856 | { 1857 | "type": "REPEAT", 1858 | "content": { 1859 | "type": "SYMBOL", 1860 | "name": "_metadata_lit" 1861 | } 1862 | }, 1863 | { 1864 | "type": "FIELD", 1865 | "name": "marker", 1866 | "content": { 1867 | "type": "STRING", 1868 | "value": "~@" 1869 | } 1870 | }, 1871 | { 1872 | "type": "REPEAT", 1873 | "content": { 1874 | "type": "SYMBOL", 1875 | "name": "_gap" 1876 | } 1877 | }, 1878 | { 1879 | "type": "FIELD", 1880 | "name": "value", 1881 | "content": { 1882 | "type": "SYMBOL", 1883 | "name": "_form" 1884 | } 1885 | } 1886 | ] 1887 | }, 1888 | "unquoting_lit": { 1889 | "type": "SEQ", 1890 | "members": [ 1891 | { 1892 | "type": "REPEAT", 1893 | "content": { 1894 | "type": "SYMBOL", 1895 | "name": "_metadata_lit" 1896 | } 1897 | }, 1898 | { 1899 | "type": "FIELD", 1900 | "name": "marker", 1901 | "content": { 1902 | "type": "STRING", 1903 | "value": "~" 1904 | } 1905 | }, 1906 | { 1907 | "type": "REPEAT", 1908 | "content": { 1909 | "type": "SYMBOL", 1910 | "name": "_gap" 1911 | } 1912 | }, 1913 | { 1914 | "type": "FIELD", 1915 | "name": "value", 1916 | "content": { 1917 | "type": "SYMBOL", 1918 | "name": "_form" 1919 | } 1920 | } 1921 | ] 1922 | } 1923 | }, 1924 | "extras": [], 1925 | "conflicts": [], 1926 | "precedences": [], 1927 | "externals": [], 1928 | "inline": [ 1929 | "_kwd_leading_slash", 1930 | "_kwd_just_slash", 1931 | "_kwd_qualified", 1932 | "_kwd_unqualified", 1933 | "_kwd_marker", 1934 | "_sym_qualified", 1935 | "_sym_unqualified" 1936 | ], 1937 | "supertypes": [] 1938 | } 1939 | 1940 | -------------------------------------------------------------------------------- /src/tree_sitter/parser.h: -------------------------------------------------------------------------------- 1 | #ifndef TREE_SITTER_PARSER_H_ 2 | #define TREE_SITTER_PARSER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #define ts_builtin_sym_error ((TSSymbol)-1) 13 | #define ts_builtin_sym_end 0 14 | #define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024 15 | 16 | #ifndef TREE_SITTER_API_H_ 17 | typedef uint16_t TSStateId; 18 | typedef uint16_t TSSymbol; 19 | typedef uint16_t TSFieldId; 20 | typedef struct TSLanguage TSLanguage; 21 | #endif 22 | 23 | typedef struct { 24 | TSFieldId field_id; 25 | uint8_t child_index; 26 | bool inherited; 27 | } TSFieldMapEntry; 28 | 29 | typedef struct { 30 | uint16_t index; 31 | uint16_t length; 32 | } TSFieldMapSlice; 33 | 34 | typedef struct { 35 | bool visible; 36 | bool named; 37 | bool supertype; 38 | } TSSymbolMetadata; 39 | 40 | typedef struct TSLexer TSLexer; 41 | 42 | struct TSLexer { 43 | int32_t lookahead; 44 | TSSymbol result_symbol; 45 | void (*advance)(TSLexer *, bool); 46 | void (*mark_end)(TSLexer *); 47 | uint32_t (*get_column)(TSLexer *); 48 | bool (*is_at_included_range_start)(const TSLexer *); 49 | bool (*eof)(const TSLexer *); 50 | }; 51 | 52 | typedef enum { 53 | TSParseActionTypeShift, 54 | TSParseActionTypeReduce, 55 | TSParseActionTypeAccept, 56 | TSParseActionTypeRecover, 57 | } TSParseActionType; 58 | 59 | typedef union { 60 | struct { 61 | uint8_t type; 62 | TSStateId state; 63 | bool extra; 64 | bool repetition; 65 | } shift; 66 | struct { 67 | uint8_t type; 68 | uint8_t child_count; 69 | TSSymbol symbol; 70 | int16_t dynamic_precedence; 71 | uint16_t production_id; 72 | } reduce; 73 | uint8_t type; 74 | } TSParseAction; 75 | 76 | typedef struct { 77 | uint16_t lex_state; 78 | uint16_t external_lex_state; 79 | } TSLexMode; 80 | 81 | typedef union { 82 | TSParseAction action; 83 | struct { 84 | uint8_t count; 85 | bool reusable; 86 | } entry; 87 | } TSParseActionEntry; 88 | 89 | struct TSLanguage { 90 | uint32_t version; 91 | uint32_t symbol_count; 92 | uint32_t alias_count; 93 | uint32_t token_count; 94 | uint32_t external_token_count; 95 | uint32_t state_count; 96 | uint32_t large_state_count; 97 | uint32_t production_id_count; 98 | uint32_t field_count; 99 | uint16_t max_alias_sequence_length; 100 | const uint16_t *parse_table; 101 | const uint16_t *small_parse_table; 102 | const uint32_t *small_parse_table_map; 103 | const TSParseActionEntry *parse_actions; 104 | const char * const *symbol_names; 105 | const char * const *field_names; 106 | const TSFieldMapSlice *field_map_slices; 107 | const TSFieldMapEntry *field_map_entries; 108 | const TSSymbolMetadata *symbol_metadata; 109 | const TSSymbol *public_symbol_map; 110 | const uint16_t *alias_map; 111 | const TSSymbol *alias_sequences; 112 | const TSLexMode *lex_modes; 113 | bool (*lex_fn)(TSLexer *, TSStateId); 114 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 115 | TSSymbol keyword_capture_token; 116 | struct { 117 | const bool *states; 118 | const TSSymbol *symbol_map; 119 | void *(*create)(void); 120 | void (*destroy)(void *); 121 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 122 | unsigned (*serialize)(void *, char *); 123 | void (*deserialize)(void *, const char *, unsigned); 124 | } external_scanner; 125 | const TSStateId *primary_state_ids; 126 | }; 127 | 128 | /* 129 | * Lexer Macros 130 | */ 131 | 132 | #ifdef _MSC_VER 133 | #define UNUSED __pragma(warning(suppress : 4101)) 134 | #else 135 | #define UNUSED __attribute__((unused)) 136 | #endif 137 | 138 | #define START_LEXER() \ 139 | bool result = false; \ 140 | bool skip = false; \ 141 | UNUSED \ 142 | bool eof = false; \ 143 | int32_t lookahead; \ 144 | goto start; \ 145 | next_state: \ 146 | lexer->advance(lexer, skip); \ 147 | start: \ 148 | skip = false; \ 149 | lookahead = lexer->lookahead; 150 | 151 | #define ADVANCE(state_value) \ 152 | { \ 153 | state = state_value; \ 154 | goto next_state; \ 155 | } 156 | 157 | #define SKIP(state_value) \ 158 | { \ 159 | skip = true; \ 160 | state = state_value; \ 161 | goto next_state; \ 162 | } 163 | 164 | #define ACCEPT_TOKEN(symbol_value) \ 165 | result = true; \ 166 | lexer->result_symbol = symbol_value; \ 167 | lexer->mark_end(lexer); 168 | 169 | #define END_STATE() return result; 170 | 171 | /* 172 | * Parse Table Macros 173 | */ 174 | 175 | #define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT) 176 | 177 | #define STATE(id) id 178 | 179 | #define ACTIONS(id) id 180 | 181 | #define SHIFT(state_value) \ 182 | {{ \ 183 | .shift = { \ 184 | .type = TSParseActionTypeShift, \ 185 | .state = (state_value) \ 186 | } \ 187 | }} 188 | 189 | #define SHIFT_REPEAT(state_value) \ 190 | {{ \ 191 | .shift = { \ 192 | .type = TSParseActionTypeShift, \ 193 | .state = (state_value), \ 194 | .repetition = true \ 195 | } \ 196 | }} 197 | 198 | #define SHIFT_EXTRA() \ 199 | {{ \ 200 | .shift = { \ 201 | .type = TSParseActionTypeShift, \ 202 | .extra = true \ 203 | } \ 204 | }} 205 | 206 | #define REDUCE(symbol_val, child_count_val, ...) \ 207 | {{ \ 208 | .reduce = { \ 209 | .type = TSParseActionTypeReduce, \ 210 | .symbol = symbol_val, \ 211 | .child_count = child_count_val, \ 212 | __VA_ARGS__ \ 213 | }, \ 214 | }} 215 | 216 | #define RECOVER() \ 217 | {{ \ 218 | .type = TSParseActionTypeRecover \ 219 | }} 220 | 221 | #define ACCEPT_INPUT() \ 222 | {{ \ 223 | .type = TSParseActionTypeAccept \ 224 | }} 225 | 226 | #ifdef __cplusplus 227 | } 228 | #endif 229 | 230 | #endif // TREE_SITTER_PARSER_H_ 231 | -------------------------------------------------------------------------------- /test/corpus/anon_fn_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty Anonymous Function 3 | ================================================================================ 4 | 5 | #() 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (anon_fn_lit)) 11 | 12 | ================================================================================ 13 | Anonymous Function 14 | ================================================================================ 15 | 16 | #(+ % 8) 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (anon_fn_lit 22 | (sym_lit (sym_name)) 23 | (sym_lit (sym_name)) 24 | (num_lit))) 25 | -------------------------------------------------------------------------------- /test/corpus/bool_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | True 3 | ================================================================================ 4 | 5 | true 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (bool_lit)) 11 | 12 | ================================================================================ 13 | False 14 | ================================================================================ 15 | 16 | false 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (bool_lit)) 22 | -------------------------------------------------------------------------------- /test/corpus/char_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple Char 3 | ================================================================================ 4 | 5 | \a 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (char_lit)) 11 | 12 | ================================================================================ 13 | Octal Char 14 | ================================================================================ 15 | 16 | \o377 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (char_lit)) 22 | 23 | ================================================================================ 24 | Named Char 25 | ================================================================================ 26 | 27 | \backspace 28 | 29 | -------------------------------------------------------------------------------- 30 | 31 | (source 32 | (char_lit)) 33 | 34 | ================================================================================ 35 | Unicode Char 36 | ================================================================================ 37 | 38 | \u611B 39 | 40 | -------------------------------------------------------------------------------- 41 | 42 | (source 43 | (char_lit)) 44 | -------------------------------------------------------------------------------- /test/corpus/comment.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple Comment 3 | ================================================================================ 4 | 5 | ; a comment 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (comment)) 11 | 12 | ================================================================================ 13 | Two semicolons 14 | ================================================================================ 15 | 16 | ;; another comment 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (comment)) 22 | 23 | ================================================================================ 24 | Multiple lines 25 | ================================================================================ 26 | 27 | ;; first line 28 | ;; second line 29 | 30 | -------------------------------------------------------------------------------- 31 | 32 | (source 33 | (comment) 34 | (comment)) 35 | -------------------------------------------------------------------------------- /test/corpus/derefing_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple Deref 3 | ================================================================================ 4 | 5 | @x 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (derefing_lit 11 | (sym_lit (sym_name)))) 12 | 13 | ================================================================================ 14 | Deref of Call 15 | ================================================================================ 16 | 17 | @(ping y) 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | (source 22 | (derefing_lit 23 | (list_lit 24 | (sym_lit (sym_name)) 25 | (sym_lit (sym_name))))) 26 | -------------------------------------------------------------------------------- /test/corpus/dis_expr.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Discard Number 3 | ================================================================================ 4 | 5 | #_ 1 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (dis_expr 11 | (num_lit))) 12 | 13 | ================================================================================ 14 | Discard List 15 | ================================================================================ 16 | 17 | #_ (+ 1 1) 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | (source 22 | (dis_expr 23 | (list_lit 24 | (sym_lit (sym_name)) 25 | (num_lit) 26 | (num_lit)))) 27 | 28 | ================================================================================ 29 | Discard Map 30 | ================================================================================ 31 | 32 | #_ {:a 1 33 | :b 2} 34 | 35 | -------------------------------------------------------------------------------- 36 | 37 | (source 38 | (dis_expr 39 | (map_lit 40 | (kwd_lit (kwd_name)) 41 | (num_lit) 42 | (kwd_lit (kwd_name)) 43 | (num_lit)))) 44 | 45 | ================================================================================ 46 | Discard Multiple 47 | ================================================================================ 48 | 49 | (let [x 1 50 | #_ #_ y 2] 51 | (+ x 2)) 52 | 53 | -------------------------------------------------------------------------------- 54 | 55 | (source 56 | (list_lit 57 | (sym_lit (sym_name)) 58 | (vec_lit 59 | (sym_lit (sym_name)) 60 | (num_lit) 61 | (dis_expr 62 | (dis_expr 63 | (sym_lit (sym_name))) 64 | (num_lit))) 65 | (list_lit 66 | (sym_lit (sym_name)) 67 | (sym_lit (sym_name)) 68 | (num_lit)))) 69 | -------------------------------------------------------------------------------- /test/corpus/evaling_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Not Officially Supported 3 | ================================================================================ 4 | 5 | #=(+ 1 1) 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (evaling_lit 11 | (list_lit 12 | (sym_lit (sym_name)) 13 | (num_lit) 14 | (num_lit)))) 15 | -------------------------------------------------------------------------------- /test/corpus/kwd_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Keyword 3 | ================================================================================ 4 | 5 | :smile 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (kwd_lit 11 | (kwd_name))) 12 | 13 | ================================================================================ 14 | Keyword with Prefix 15 | ================================================================================ 16 | 17 | :fun/day 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | (source 22 | (kwd_lit 23 | (kwd_ns) 24 | (kwd_name))) 25 | 26 | ================================================================================ 27 | Autoresolving Keyword 28 | ================================================================================ 29 | 30 | ::run 31 | 32 | -------------------------------------------------------------------------------- 33 | 34 | (source 35 | (kwd_lit 36 | (kwd_name))) 37 | 38 | ================================================================================ 39 | Autoresolving Aliased Keyword 40 | ================================================================================ 41 | 42 | ::slow/dance 43 | 44 | -------------------------------------------------------------------------------- 45 | 46 | (source 47 | (kwd_lit 48 | (kwd_ns) 49 | (kwd_name))) 50 | 51 | 52 | ================================================================================ 53 | Division Symbol Keyword 54 | ================================================================================ 55 | 56 | :/ 57 | 58 | -------------------------------------------------------------------------------- 59 | 60 | (source 61 | (kwd_lit 62 | (kwd_name))) 63 | 64 | ================================================================================ 65 | Namespaced Division Symbol Keyword 66 | ================================================================================ 67 | 68 | :clojure.core// 69 | 70 | -------------------------------------------------------------------------------- 71 | 72 | (source 73 | (kwd_lit 74 | (kwd_ns) 75 | (kwd_name))) 76 | 77 | 78 | ================================================================================ 79 | Autoresolving Division Symbol Keyword 80 | ================================================================================ 81 | 82 | ::/ 83 | 84 | -------------------------------------------------------------------------------- 85 | 86 | (source 87 | (kwd_lit 88 | (kwd_name))) 89 | 90 | ================================================================================ 91 | Autoresolving Aliased Division Symbol Keyword 92 | ================================================================================ 93 | 94 | ::clojure// 95 | 96 | -------------------------------------------------------------------------------- 97 | 98 | (source 99 | (kwd_lit 100 | (kwd_ns) 101 | (kwd_name))) 102 | 103 | -------------------------------------------------------------------------------- /test/corpus/list_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty List 3 | ================================================================================ 4 | 5 | () 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (list_lit)) 11 | 12 | ================================================================================ 13 | List with Keywords 14 | ================================================================================ 15 | 16 | (:a :b :c) 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (list_lit 22 | (kwd_lit (kwd_name)) 23 | (kwd_lit (kwd_name)) 24 | (kwd_lit (kwd_name)))) 25 | 26 | ================================================================================ 27 | Call with Anonymous Function 28 | ================================================================================ 29 | 30 | (#(+ % 1) 1) 31 | 32 | -------------------------------------------------------------------------------- 33 | 34 | (source 35 | (list_lit 36 | (anon_fn_lit 37 | (sym_lit (sym_name)) 38 | (sym_lit (sym_name)) 39 | (num_lit)) 40 | (num_lit))) 41 | 42 | ================================================================================ 43 | Map Lookup 44 | ================================================================================ 45 | 46 | ({:a 1} :a) 47 | 48 | -------------------------------------------------------------------------------- 49 | 50 | (source 51 | (list_lit 52 | (map_lit 53 | (kwd_lit (kwd_name)) 54 | (num_lit)) 55 | (kwd_lit (kwd_name)))) 56 | 57 | ================================================================================ 58 | Map Lookup Alternate 59 | ================================================================================ 60 | 61 | (:b {:b 2}) 62 | 63 | -------------------------------------------------------------------------------- 64 | 65 | (source 66 | (list_lit 67 | (kwd_lit (kwd_name)) 68 | (map_lit 69 | (kwd_lit (kwd_name)) 70 | (num_lit)))) 71 | 72 | ================================================================================ 73 | Set Lookup 74 | ================================================================================ 75 | 76 | (#{:c :e} :e) 77 | 78 | -------------------------------------------------------------------------------- 79 | 80 | (source 81 | (list_lit 82 | (set_lit 83 | (kwd_lit (kwd_name)) 84 | (kwd_lit (kwd_name))) 85 | (kwd_lit (kwd_name)))) 86 | 87 | ================================================================================ 88 | Call with Symbol with Metadata 89 | ================================================================================ 90 | 91 | (.get ^ByteBuffer b) 92 | 93 | -------------------------------------------------------------------------------- 94 | 95 | (source 96 | (list_lit 97 | (sym_lit (sym_name)) 98 | (sym_lit 99 | (meta_lit 100 | (sym_lit (sym_name))) 101 | (sym_name)))) 102 | -------------------------------------------------------------------------------- /test/corpus/map_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty Map 3 | ================================================================================ 4 | 5 | {} 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (map_lit)) 11 | 12 | ================================================================================ 13 | Simple Map 14 | ================================================================================ 15 | 16 | {:a 1 :b 2} 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (map_lit 22 | (kwd_lit (kwd_name)) 23 | (num_lit) 24 | (kwd_lit (kwd_name)) 25 | (num_lit))) 26 | 27 | ================================================================================ 28 | Deeper Map 29 | ================================================================================ 30 | 31 | {:paths ["src"] 32 | :deps {clj-kondo/clj-kondo {:mvn/version "2020.09.09"}}} 33 | 34 | -------------------------------------------------------------------------------- 35 | 36 | (source 37 | (map_lit 38 | (kwd_lit (kwd_name)) 39 | (vec_lit 40 | (str_lit)) 41 | (kwd_lit (kwd_name)) 42 | (map_lit 43 | (sym_lit 44 | (sym_ns) 45 | (sym_name)) 46 | (map_lit 47 | (kwd_lit 48 | (kwd_ns) 49 | (kwd_name)) 50 | (str_lit))))) 51 | 52 | ================================================================================ 53 | Map with Comma 54 | ================================================================================ 55 | 56 | {:x 1, 57 | :y 2} 58 | 59 | -------------------------------------------------------------------------------- 60 | 61 | (source 62 | (map_lit 63 | (kwd_lit (kwd_name)) 64 | (num_lit) 65 | (kwd_lit (kwd_name)) 66 | (num_lit))) 67 | -------------------------------------------------------------------------------- /test/corpus/meta_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Symbol Metadata 3 | ================================================================================ 4 | 5 | ^String [] 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (vec_lit 11 | (meta_lit 12 | (sym_lit 13 | (sym_name))))) 14 | 15 | ================================================================================ 16 | Keyword Metadata 17 | ================================================================================ 18 | 19 | ^:private {} 20 | 21 | -------------------------------------------------------------------------------- 22 | 23 | (source 24 | (map_lit 25 | (meta_lit 26 | (kwd_lit 27 | (kwd_name))))) 28 | 29 | ================================================================================ 30 | String Metadata 31 | ================================================================================ 32 | 33 | ^"gnarly" {} 34 | 35 | -------------------------------------------------------------------------------- 36 | 37 | (source 38 | (map_lit 39 | (meta_lit 40 | (str_lit)))) 41 | 42 | ================================================================================ 43 | Map Metadata 44 | ================================================================================ 45 | 46 | ^{:x 0 :y 1} #{} 47 | 48 | -------------------------------------------------------------------------------- 49 | 50 | (source 51 | (set_lit 52 | (meta_lit 53 | (map_lit 54 | (kwd_lit 55 | (kwd_name)) 56 | (num_lit) 57 | (kwd_lit 58 | (kwd_name)) 59 | (num_lit))))) 60 | 61 | ================================================================================ 62 | Reader Conditional Metadata 63 | ================================================================================ 64 | 65 | ^#?(:clj "vanilla" :cljr "strawberry" :cljs "chocolate") [] 66 | 67 | -------------------------------------------------------------------------------- 68 | 69 | (source 70 | (vec_lit 71 | (meta_lit 72 | (read_cond_lit 73 | (kwd_lit 74 | (kwd_name)) 75 | (str_lit) 76 | (kwd_lit 77 | (kwd_name)) 78 | (str_lit) 79 | (kwd_lit 80 | (kwd_name)) 81 | (str_lit))))) 82 | 83 | ================================================================================ 84 | Multiple Bits of Metadata 85 | ================================================================================ 86 | 87 | ^:wake ^:sit ^:sleep #{} 88 | 89 | -------------------------------------------------------------------------------- 90 | 91 | (source 92 | (set_lit 93 | (meta_lit 94 | (kwd_lit 95 | (kwd_name))) 96 | (meta_lit 97 | (kwd_lit 98 | (kwd_name))) 99 | (meta_lit 100 | (kwd_lit 101 | (kwd_name))))) 102 | 103 | ================================================================================ 104 | Tagged Literal Metadata 105 | ================================================================================ 106 | 107 | ^#/(data) thing 108 | 109 | -------------------------------------------------------------------------------- 110 | 111 | (source 112 | (sym_lit 113 | (meta_lit 114 | (tagged_or_ctor_lit 115 | (sym_lit 116 | (sym_name)) 117 | (list_lit 118 | (sym_lit 119 | (sym_name))))) 120 | (sym_name))) 121 | 122 | ================================================================================ 123 | Evaling Literal Metadata 124 | ================================================================================ 125 | 126 | ^#=(keyword "a") [] 127 | 128 | -------------------------------------------------------------------------------- 129 | 130 | (source 131 | (vec_lit 132 | (meta_lit 133 | (evaling_lit 134 | (list_lit 135 | (sym_lit 136 | (sym_name)) 137 | (str_lit)))))) 138 | -------------------------------------------------------------------------------- /test/corpus/nil_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Nil 3 | ================================================================================ 4 | 5 | nil 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (nil_lit)) 11 | -------------------------------------------------------------------------------- /test/corpus/ns_map_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple Namespace Map 3 | ================================================================================ 4 | 5 | #:prefix{:a 1 :b 2} 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (ns_map_lit 11 | (kwd_lit (kwd_name)) 12 | (kwd_lit (kwd_name)) 13 | (num_lit) 14 | (kwd_lit (kwd_name)) 15 | (num_lit))) 16 | 17 | ================================================================================ 18 | Nested Namespace Maps 19 | ================================================================================ 20 | 21 | #:outer{:first "Terence" 22 | :last "Tao" 23 | :area #:inner{:name "Mathematics"}} 24 | 25 | -------------------------------------------------------------------------------- 26 | 27 | (source 28 | (ns_map_lit 29 | (kwd_lit (kwd_name)) 30 | (kwd_lit (kwd_name)) 31 | (str_lit) 32 | (kwd_lit (kwd_name)) 33 | (str_lit) 34 | (kwd_lit (kwd_name)) 35 | (ns_map_lit 36 | (kwd_lit (kwd_name)) 37 | (kwd_lit (kwd_name)) 38 | (str_lit)))) 39 | 40 | ================================================================================ 41 | Autoresolving Namespace Map 42 | ================================================================================ 43 | 44 | #::{} 45 | 46 | -------------------------------------------------------------------------------- 47 | 48 | (source 49 | (ns_map_lit 50 | (auto_res_mark))) 51 | 52 | ================================================================================ 53 | Namespace Map that Autoresolves with Alias 54 | ================================================================================ 55 | 56 | #::s{:x 1 :y 2} 57 | 58 | -------------------------------------------------------------------------------- 59 | 60 | (source 61 | (ns_map_lit 62 | (kwd_lit (kwd_name)) 63 | (kwd_lit (kwd_name)) 64 | (num_lit) 65 | (kwd_lit (kwd_name)) 66 | (num_lit))) 67 | -------------------------------------------------------------------------------- /test/corpus/num_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Integer 3 | ================================================================================ 4 | 5 | 1 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (num_lit)) 11 | 12 | ================================================================================ 13 | Negative Integer 14 | ================================================================================ 15 | 16 | -2 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (num_lit)) 22 | 23 | ================================================================================ 24 | BigInt Integer 25 | ================================================================================ 26 | 27 | 11N 28 | 29 | -------------------------------------------------------------------------------- 30 | 31 | (source 32 | (num_lit)) 33 | 34 | ================================================================================ 35 | BigDecimal Integer 36 | ================================================================================ 37 | 38 | 99M 39 | 40 | -------------------------------------------------------------------------------- 41 | 42 | (source 43 | (num_lit)) 44 | 45 | ================================================================================ 46 | Hex 47 | ================================================================================ 48 | 49 | 0xaB 50 | 51 | -------------------------------------------------------------------------------- 52 | 53 | (source 54 | (num_lit)) 55 | 56 | ================================================================================ 57 | Negative Hex 58 | ================================================================================ 59 | 60 | -0xFF 61 | 62 | -------------------------------------------------------------------------------- 63 | 64 | (source 65 | (num_lit)) 66 | 67 | ================================================================================ 68 | Shouting Hex 69 | ================================================================================ 70 | 71 | 0XA 72 | 73 | -------------------------------------------------------------------------------- 74 | 75 | (source 76 | (num_lit)) 77 | 78 | ================================================================================ 79 | BigInt Hex 80 | ================================================================================ 81 | 82 | 0XeN 83 | 84 | -------------------------------------------------------------------------------- 85 | 86 | (source 87 | (num_lit)) 88 | 89 | ================================================================================ 90 | Octal 91 | ================================================================================ 92 | 93 | 013 94 | 95 | -------------------------------------------------------------------------------- 96 | 97 | (source 98 | (num_lit)) 99 | 100 | ================================================================================ 101 | Negative Octal 102 | ================================================================================ 103 | 104 | -027 105 | 106 | -------------------------------------------------------------------------------- 107 | 108 | (source 109 | (num_lit)) 110 | 111 | ================================================================================ 112 | BigInt Octal 113 | ================================================================================ 114 | 115 | 0377N 116 | 117 | -------------------------------------------------------------------------------- 118 | 119 | (source 120 | (num_lit)) 121 | 122 | ================================================================================ 123 | Radix 124 | ================================================================================ 125 | 126 | 2r0101010001 127 | 128 | -------------------------------------------------------------------------------- 129 | 130 | (source 131 | (num_lit)) 132 | 133 | ================================================================================ 134 | Negative Radix 135 | ================================================================================ 136 | 137 | -10r256 138 | 139 | -------------------------------------------------------------------------------- 140 | 141 | (source 142 | (num_lit)) 143 | 144 | ================================================================================ 145 | Shouting Radix 146 | ================================================================================ 147 | 148 | 36RBREATHESL0WLY 149 | 150 | -------------------------------------------------------------------------------- 151 | 152 | (source 153 | (num_lit)) 154 | 155 | ================================================================================ 156 | Ratio 157 | ================================================================================ 158 | 159 | 22/7 160 | 161 | -------------------------------------------------------------------------------- 162 | 163 | (source 164 | (num_lit)) 165 | 166 | ================================================================================ 167 | Negative Ratio 168 | ================================================================================ 169 | 170 | -1/2 171 | 172 | -------------------------------------------------------------------------------- 173 | 174 | (source 175 | (num_lit)) 176 | 177 | ================================================================================ 178 | Double 179 | ================================================================================ 180 | 181 | 1.0 182 | 183 | -------------------------------------------------------------------------------- 184 | 185 | (source 186 | (num_lit)) 187 | 188 | ================================================================================ 189 | Negative Double 190 | ================================================================================ 191 | 192 | -2.71828 193 | 194 | -------------------------------------------------------------------------------- 195 | 196 | (source 197 | (num_lit)) 198 | 199 | ================================================================================ 200 | Double with Exponent 201 | ================================================================================ 202 | 203 | 3e8 204 | 205 | -------------------------------------------------------------------------------- 206 | 207 | (source 208 | (num_lit)) 209 | 210 | ================================================================================ 211 | Shouting Double with Exponent 212 | ================================================================================ 213 | 214 | 1E9 215 | 216 | -------------------------------------------------------------------------------- 217 | 218 | (source 219 | (num_lit)) 220 | 221 | ================================================================================ 222 | Double with Negative Exponent 223 | ================================================================================ 224 | 225 | 2e-1 226 | 227 | -------------------------------------------------------------------------------- 228 | 229 | (source 230 | (num_lit)) 231 | 232 | ================================================================================ 233 | BigDecimal Double with Exponent 234 | ================================================================================ 235 | 236 | 3e1415926535M 237 | 238 | -------------------------------------------------------------------------------- 239 | 240 | (source 241 | (num_lit)) 242 | -------------------------------------------------------------------------------- /test/corpus/old_meta.lit: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Symbol Metadata 3 | ================================================================================ 4 | 5 | #^String [] 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (vec_lit 11 | (old_meta_lit 12 | (sym_lit (sym_name))))) 13 | 14 | ================================================================================ 15 | Keyword Metadata 16 | ================================================================================ 17 | 18 | #^:private {} 19 | 20 | -------------------------------------------------------------------------------- 21 | 22 | (source 23 | (map_lit 24 | (old_meta_lit 25 | (kwd_lit (kwd_name))))) 26 | 27 | ================================================================================ 28 | String Metadata 29 | ================================================================================ 30 | 31 | #^"gnarly" {} 32 | 33 | -------------------------------------------------------------------------------- 34 | 35 | (source 36 | (map_lit 37 | (old_meta_lit 38 | (str_lit)))) 39 | 40 | ================================================================================ 41 | Map Metadata 42 | ================================================================================ 43 | 44 | #^{:x 0 :y 1} #{} 45 | 46 | -------------------------------------------------------------------------------- 47 | 48 | (source 49 | (set_lit 50 | (old_meta_lit 51 | (map_lit 52 | (kwd_lit (kwd_name)) 53 | (num_lit) 54 | (kwd_lit (kwd_name)) 55 | (num_lit))))) 56 | 57 | ================================================================================ 58 | Reader Conditional Metadata 59 | ================================================================================ 60 | 61 | #^#?(:clj "vanilla" :cljr "strawberry" :cljs "chocolate") [] 62 | 63 | -------------------------------------------------------------------------------- 64 | 65 | (source 66 | (vec_lit 67 | (old_meta_lit 68 | (read_cond_lit 69 | (kwd_lit (kwd_name)) 70 | (str_lit) 71 | (kwd_lit (kwd_name)) 72 | (str_lit) 73 | (kwd_lit (kwd_name)) 74 | (str_lit))))) 75 | 76 | ================================================================================ 77 | Multiple Bits of Metadata 78 | ================================================================================ 79 | 80 | #^:wake #^:sit #^:sleep #{} 81 | 82 | -------------------------------------------------------------------------------- 83 | 84 | (source 85 | (set_lit 86 | (old_meta_lit 87 | (kwd_lit (kwd_name))) 88 | (old_meta_lit 89 | (kwd_lit (kwd_name))) 90 | (old_meta_lit 91 | (kwd_lit (kwd_name))))) 92 | -------------------------------------------------------------------------------- /test/corpus/quoting_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Quoted Symbol 3 | ================================================================================ 4 | 5 | 'a-sym 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (quoting_lit 11 | (sym_lit (sym_name)))) 12 | 13 | ================================================================================ 14 | Quoted List 15 | ================================================================================ 16 | 17 | '(1 2 3) 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | (source 22 | (quoting_lit 23 | (list_lit 24 | (num_lit) 25 | (num_lit) 26 | (num_lit)))) 27 | -------------------------------------------------------------------------------- /test/corpus/read_cond_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Platform Reader Conditional 3 | ================================================================================ 4 | 5 | #?(:clj :clj 6 | :cljr :cljr 7 | :cljs :cljs) 8 | 9 | -------------------------------------------------------------------------------- 10 | 11 | (source 12 | (read_cond_lit 13 | (kwd_lit (kwd_name)) 14 | (kwd_lit (kwd_name)) 15 | (kwd_lit (kwd_name)) 16 | (kwd_lit (kwd_name)) 17 | (kwd_lit (kwd_name)) 18 | (kwd_lit (kwd_name)))) 19 | -------------------------------------------------------------------------------- /test/corpus/regex_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple Regular Expression 3 | ================================================================================ 4 | 5 | #"." 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (regex_lit)) 11 | 12 | ================================================================================ 13 | Hex Digits Regular Expression 14 | ================================================================================ 15 | 16 | #"[0-9a-fA-F]+" 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (regex_lit)) 22 | -------------------------------------------------------------------------------- /test/corpus/set_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty Set 3 | ================================================================================ 4 | 5 | #{} 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (set_lit)) 11 | 12 | ================================================================================ 13 | Simple Set 14 | ================================================================================ 15 | 16 | #{:i :j :k} 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (set_lit 22 | (kwd_lit (kwd_name)) 23 | (kwd_lit (kwd_name)) 24 | (kwd_lit (kwd_name)))) 25 | 26 | ================================================================================ 27 | Nested Sets 28 | ================================================================================ 29 | 30 | #{#{1} #{#{0} 2}} 31 | 32 | -------------------------------------------------------------------------------- 33 | 34 | (source 35 | (set_lit 36 | (set_lit 37 | (num_lit)) 38 | (set_lit 39 | (set_lit 40 | (num_lit)) 41 | (num_lit)))) 42 | -------------------------------------------------------------------------------- /test/corpus/splicing_read_cond_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Splicing Reader Conditional 3 | ================================================================================ 4 | 5 | (list '* 6 | #?@(:clj [x y] :cljr [i j] :cljs [a b])) 7 | 8 | -------------------------------------------------------------------------------- 9 | 10 | (source 11 | (list_lit 12 | (sym_lit (sym_name)) 13 | (quoting_lit 14 | (sym_lit (sym_name))) 15 | (splicing_read_cond_lit 16 | (kwd_lit (kwd_name)) 17 | (vec_lit 18 | (sym_lit (sym_name)) 19 | (sym_lit (sym_name))) 20 | (kwd_lit (kwd_name)) 21 | (vec_lit 22 | (sym_lit (sym_name)) 23 | (sym_lit (sym_name))) 24 | (kwd_lit (kwd_name)) 25 | (vec_lit 26 | (sym_lit (sym_name)) 27 | (sym_lit (sym_name)))))) 28 | -------------------------------------------------------------------------------- /test/corpus/str_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple String 3 | ================================================================================ 4 | 5 | "hello there" 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (str_lit)) 11 | 12 | ================================================================================ 13 | String with Escapes 14 | ================================================================================ 15 | 16 | "first line\nsecond\tline" 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (str_lit)) 22 | 23 | ================================================================================ 24 | Multiline String 25 | ================================================================================ 26 | 27 | "this is the first line 28 | and what is this one?" 29 | 30 | -------------------------------------------------------------------------------- 31 | 32 | (source 33 | (str_lit)) 34 | -------------------------------------------------------------------------------- /test/corpus/sym_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Simple Symbol 3 | ================================================================================ 4 | 5 | def 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (sym_lit (sym_name))) 11 | 12 | ================================================================================ 13 | Symbol with Prefix 14 | ================================================================================ 15 | 16 | clojure.string/blank? 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (sym_lit 22 | (sym_ns) 23 | (sym_name))) 24 | 25 | ================================================================================ 26 | Division Symbol 27 | ================================================================================ 28 | 29 | / 30 | 31 | -------------------------------------------------------------------------------- 32 | 33 | (source 34 | (sym_lit 35 | (sym_name))) 36 | 37 | ================================================================================ 38 | Namespaced Division Symbol 39 | ================================================================================ 40 | 41 | clojure.core// 42 | 43 | -------------------------------------------------------------------------------- 44 | 45 | (source 46 | (sym_lit 47 | (sym_ns) 48 | (sym_name))) 49 | 50 | ================================================================================ 51 | Division Symbol followed by delimiter 52 | ================================================================================ 53 | 54 | (+ - * /) 55 | 56 | -------------------------------------------------------------------------------- 57 | 58 | (source 59 | (list_lit 60 | (sym_lit (sym_name)) 61 | (sym_lit (sym_name)) 62 | (sym_lit (sym_name)) 63 | (sym_lit (sym_name)))) 64 | -------------------------------------------------------------------------------- /test/corpus/sym_val_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Inf 3 | ================================================================================ 4 | 5 | ##Inf 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (sym_val_lit 11 | (sym_lit 12 | (sym_name)))) 13 | 14 | ================================================================================ 15 | -Inf 16 | ================================================================================ 17 | 18 | ##-Inf 19 | 20 | -------------------------------------------------------------------------------- 21 | 22 | (source 23 | (sym_val_lit 24 | (sym_lit 25 | (sym_name)))) 26 | 27 | ================================================================================ 28 | NaN 29 | ================================================================================ 30 | 31 | ##NaN 32 | 33 | -------------------------------------------------------------------------------- 34 | 35 | (source 36 | (sym_val_lit 37 | (sym_lit 38 | (sym_name)))) 39 | 40 | ================================================================================ 41 | Symbolic Value Literal with Evaling Literal 42 | ================================================================================ 43 | 44 | ###=(identity NaN) 45 | 46 | -------------------------------------------------------------------------------- 47 | 48 | (source 49 | (sym_val_lit 50 | (evaling_lit 51 | (list_lit 52 | (sym_lit 53 | (sym_name)) 54 | (sym_lit 55 | (sym_name)))))) 56 | -------------------------------------------------------------------------------- /test/corpus/syn_quoting_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Syntax Quoted Symbol 3 | ================================================================================ 4 | 5 | `a-sym 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (syn_quoting_lit 11 | (sym_lit (sym_name)))) 12 | 13 | ================================================================================ 14 | Syntax Quoted List 15 | ================================================================================ 16 | 17 | `(+ ~a 1) 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | (source 22 | (syn_quoting_lit 23 | (list_lit 24 | (sym_lit (sym_name)) 25 | (unquoting_lit 26 | (sym_lit (sym_name))) 27 | (num_lit)))) 28 | -------------------------------------------------------------------------------- /test/corpus/tagged_or_ctor_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Tagged Literal 3 | ================================================================================ 4 | 5 | #uuid "00000000-0000-0000-0000-000000000000" 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (tagged_or_ctor_lit 11 | (sym_lit (sym_name)) 12 | (str_lit))) 13 | 14 | ================================================================================ 15 | Constructor 16 | ================================================================================ 17 | 18 | #user.Fun [1 2] 19 | 20 | -------------------------------------------------------------------------------- 21 | 22 | (source 23 | (tagged_or_ctor_lit 24 | (sym_lit (sym_name)) 25 | (vec_lit 26 | (num_lit) 27 | (num_lit)))) 28 | 29 | ================================================================================ 30 | Constructor Alternate 31 | ================================================================================ 32 | 33 | #user.Fun {:a 1 :b 2} 34 | 35 | -------------------------------------------------------------------------------- 36 | 37 | (source 38 | (tagged_or_ctor_lit 39 | (sym_lit (sym_name)) 40 | (map_lit 41 | (kwd_lit (kwd_name)) 42 | (num_lit) 43 | (kwd_lit (kwd_name)) 44 | (num_lit)))) 45 | -------------------------------------------------------------------------------- /test/corpus/unquote_splicing_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Unquote Splicing into List 3 | ================================================================================ 4 | 5 | `(+ ~@(list 2 3)) 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (syn_quoting_lit 11 | (list_lit 12 | (sym_lit (sym_name)) 13 | (unquote_splicing_lit 14 | (list_lit 15 | (sym_lit (sym_name)) 16 | (num_lit) 17 | (num_lit)))))) 18 | 19 | ================================================================================ 20 | Unquote Splicing into Vector 21 | ================================================================================ 22 | 23 | `[:a ~@(list :b :c)] 24 | 25 | -------------------------------------------------------------------------------- 26 | 27 | (source 28 | (syn_quoting_lit 29 | (vec_lit 30 | (kwd_lit (kwd_name)) 31 | (unquote_splicing_lit 32 | (list_lit 33 | (sym_lit (sym_name)) 34 | (kwd_lit (kwd_name)) 35 | (kwd_lit (kwd_name))))))) 36 | 37 | ================================================================================ 38 | Unquote Splicing into Set 39 | ================================================================================ 40 | 41 | `#{:i ~@(list :j :k)} 42 | 43 | -------------------------------------------------------------------------------- 44 | 45 | (source 46 | (syn_quoting_lit 47 | (set_lit 48 | (kwd_lit (kwd_name)) 49 | (unquote_splicing_lit 50 | (list_lit 51 | (sym_lit (sym_name)) 52 | (kwd_lit (kwd_name)) 53 | (kwd_lit (kwd_name))))))) 54 | 55 | ================================================================================ 56 | Unquote Splicing into Map 57 | ================================================================================ 58 | 59 | `{~@(list :a 1) ~@(list :b 2)} 60 | 61 | -------------------------------------------------------------------------------- 62 | 63 | (source 64 | (syn_quoting_lit 65 | (map_lit 66 | (unquote_splicing_lit 67 | (list_lit 68 | (sym_lit (sym_name)) 69 | (kwd_lit (kwd_name)) 70 | (num_lit))) 71 | (unquote_splicing_lit 72 | (list_lit 73 | (sym_lit (sym_name)) 74 | (kwd_lit (kwd_name)) 75 | (num_lit)))))) 76 | -------------------------------------------------------------------------------- /test/corpus/unquoting_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Unquoting Symbol 3 | ================================================================================ 4 | 5 | `~a 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (syn_quoting_lit 11 | (unquoting_lit 12 | (sym_lit (sym_name))))) 13 | 14 | ================================================================================ 15 | Unquoting List 16 | ================================================================================ 17 | 18 | `(dec ~(+ 1 a)) 19 | 20 | -------------------------------------------------------------------------------- 21 | 22 | (source 23 | (syn_quoting_lit 24 | (list_lit 25 | (sym_lit (sym_name)) 26 | (unquoting_lit 27 | (list_lit 28 | (sym_lit (sym_name)) 29 | (num_lit) 30 | (sym_lit (sym_name))))))) 31 | -------------------------------------------------------------------------------- /test/corpus/var_quoting_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Var Quoting a Symbol 3 | ================================================================================ 4 | 5 | #'my-sym 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (var_quoting_lit 11 | (sym_lit (sym_name)))) 12 | 13 | ================================================================================ 14 | Var Quoting with Reader Conditional 15 | ================================================================================ 16 | 17 | #'#?(:clj my-sym :cljr your-sym :cljs their-sym) 18 | 19 | -------------------------------------------------------------------------------- 20 | 21 | (source 22 | (var_quoting_lit 23 | (read_cond_lit 24 | (kwd_lit (kwd_name)) 25 | (sym_lit (sym_name)) 26 | (kwd_lit (kwd_name)) 27 | (sym_lit (sym_name)) 28 | (kwd_lit (kwd_name)) 29 | (sym_lit (sym_name))))) 30 | -------------------------------------------------------------------------------- /test/corpus/vec_lit.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | Empty Vector 3 | ================================================================================ 4 | 5 | [] 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (source 10 | (vec_lit)) 11 | 12 | ================================================================================ 13 | Vector with Numbers 14 | ================================================================================ 15 | 16 | [1 1 2 3 5 8] 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (source 21 | (vec_lit 22 | (num_lit) 23 | (num_lit) 24 | (num_lit) 25 | (num_lit) 26 | (num_lit) 27 | (num_lit))) 28 | 29 | ================================================================================ 30 | Vector with Different Types 31 | ================================================================================ 32 | 33 | [:a 1 'fun {:x 1 :y 2} #{}] 34 | 35 | -------------------------------------------------------------------------------- 36 | 37 | (source 38 | (vec_lit 39 | (kwd_lit (kwd_name)) 40 | (num_lit) 41 | (quoting_lit 42 | (sym_lit (sym_name))) 43 | (map_lit 44 | (kwd_lit (kwd_name)) 45 | (num_lit) 46 | (kwd_lit (kwd_name)) 47 | (num_lit)) 48 | (set_lit))) 49 | --------------------------------------------------------------------------------