├── .gitignore ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── binding.gyp ├── build.rs ├── build ├── Makefile ├── binding.Makefile └── config.gypi ├── grammar.js ├── index.js ├── package.json ├── src ├── big_fixture.in.sexp ├── big_fixture.out.sexp ├── binding.cc ├── ffi.rs ├── grammar.json ├── lib.rs ├── node-types.json ├── parser.c └── tree_sitter │ └── parser.h ├── test └── corpus │ └── s_expressions.txt ├── tree-sitter-sexp.wasm └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to tree-sitter-sexp 2 | 3 | First of all, thanks for taking the time to contribute! :heart::tada::+1: 4 | 5 | There's 3 commands to run: 6 | 7 | 1. `make` -- this will reformat, compile, and test everything. It's fast enough 8 | that you can run it often. 9 | 10 | 2. `make web` -- to build and run the local web ui 11 | 12 | 3. `make publish` -- to prepare everything for merging and update the playground 13 | 14 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tree-sitter-sexp" 3 | version = "0.1.0" 4 | authors = ["Leandro Ostera "] 5 | edition = "2018" 6 | 7 | [lib] 8 | name = "tree_sitter_sexp" 9 | crate-type = ["lib", "staticlib", "cdylib"] 10 | 11 | [dependencies] 12 | tree-sitter = "0.17" 13 | anyhow = "*" 14 | 15 | [build-dependencies] 16 | cc = "*" 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2020-present Abstract Machines Lab Sweden AB 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TREE_SITTER=tree-sitter 2 | 3 | all: fmt gen test build 4 | 5 | fmt: 6 | ./node_modules/.bin/prettier --write grammar.js 7 | 8 | .PHONY: test 9 | test: gen 10 | $(TREE_SITTER) test 11 | cargo test 12 | 13 | .PHONY: gen 14 | gen: 15 | $(TREE_SITTER) generate 16 | 17 | .PHONY: deps 18 | deps: 19 | yarn 20 | 21 | .PHONY: web 22 | web: wasm 23 | $(TREE_SITTER) web-ui 24 | 25 | .PHONY: wasm 26 | wasm: 27 | $(TREE_SITTER) build-wasm 28 | 29 | .PHONY: publish 30 | publish: all wasm 31 | cp ./tree-sitter-sexp.wasm ./docs 32 | 33 | .PHONY: build 34 | build: 35 | cargo build --release 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tree-sitter grammar for S-expressions (+ Rust bindings) 2 | 3 | ## Getting Started 4 | 5 | You can add this lib as a dependency: 6 | 7 | ```toml 8 | [dependencies] 9 | tree-sitter-sexp = { git = "https://github.com/AbstractMachinesLab/tree-sitter-sexp" } 10 | ``` 11 | 12 | And then you can parse strings with the `Sexp` struct like this: 13 | 14 | ```rust 15 | let sexprs = Sexp::of_str("(hello (world))")?; 16 | 17 | sexprs.to_string(); 18 | // (hello (world)) 19 | ``` 20 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "tree_sitter_sexp_binding", 5 | "include_dirs": [ 6 | "> $(depfile) 108 | # Add extra rules as in (2). 109 | # We remove slashes and replace spaces with new lines; 110 | # remove blank lines; 111 | # delete the first line and append a colon to the remaining lines. 112 | sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ 113 | grep -v '^$$' |\ 114 | sed -e 1d -e 's|$$|:|' \ 115 | >> $(depfile) 116 | rm $(depfile).raw 117 | endef 118 | 119 | # Command definitions: 120 | # - cmd_foo is the actual command to run; 121 | # - quiet_cmd_foo is the brief-output summary of the command. 122 | 123 | quiet_cmd_cc = CC($(TOOLSET)) $@ 124 | cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< 125 | 126 | quiet_cmd_cxx = CXX($(TOOLSET)) $@ 127 | cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< 128 | 129 | quiet_cmd_touch = TOUCH $@ 130 | cmd_touch = touch $@ 131 | 132 | quiet_cmd_copy = COPY $@ 133 | # send stderr to /dev/null to ignore messages when linking directories. 134 | cmd_copy = rm -rf "$@" && cp -af "$<" "$@" 135 | 136 | quiet_cmd_alink = AR($(TOOLSET)) $@ 137 | cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) 138 | 139 | quiet_cmd_alink_thin = AR($(TOOLSET)) $@ 140 | cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) 141 | 142 | # Due to circular dependencies between libraries :(, we wrap the 143 | # special "figure out circular dependencies" flags around the entire 144 | # input list during linking. 145 | quiet_cmd_link = LINK($(TOOLSET)) $@ 146 | cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) $(LIBS) -Wl,--end-group 147 | 148 | # We support two kinds of shared objects (.so): 149 | # 1) shared_library, which is just bundling together many dependent libraries 150 | # into a link line. 151 | # 2) loadable_module, which is generating a module intended for dlopen(). 152 | # 153 | # They differ only slightly: 154 | # In the former case, we want to package all dependent code into the .so. 155 | # In the latter case, we want to package just the API exposed by the 156 | # outermost module. 157 | # This means shared_library uses --whole-archive, while loadable_module doesn't. 158 | # (Note that --whole-archive is incompatible with the --start-group used in 159 | # normal linking.) 160 | 161 | # Other shared-object link notes: 162 | # - Set SONAME to the library filename so our binaries don't reference 163 | # the local, absolute paths used on the link command-line. 164 | quiet_cmd_solink = SOLINK($(TOOLSET)) $@ 165 | cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) 166 | 167 | quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ 168 | cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) 169 | 170 | 171 | # Define an escape_quotes function to escape single quotes. 172 | # This allows us to handle quotes properly as long as we always use 173 | # use single quotes and escape_quotes. 174 | escape_quotes = $(subst ','\'',$(1)) 175 | # This comment is here just to include a ' to unconfuse syntax highlighting. 176 | # Define an escape_vars function to escape '$' variable syntax. 177 | # This allows us to read/write command lines with shell variables (e.g. 178 | # $LD_LIBRARY_PATH), without triggering make substitution. 179 | escape_vars = $(subst $$,$$$$,$(1)) 180 | # Helper that expands to a shell command to echo a string exactly as it is in 181 | # make. This uses printf instead of echo because printf's behaviour with respect 182 | # to escape sequences is more portable than echo's across different shells 183 | # (e.g., dash, bash). 184 | exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' 185 | 186 | # Helper to compare the command we're about to run against the command 187 | # we logged the last time we ran the command. Produces an empty 188 | # string (false) when the commands match. 189 | # Tricky point: Make has no string-equality test function. 190 | # The kernel uses the following, but it seems like it would have false 191 | # positives, where one string reordered its arguments. 192 | # arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ 193 | # $(filter-out $(cmd_$@), $(cmd_$(1)))) 194 | # We instead substitute each for the empty string into the other, and 195 | # say they're equal if both substitutions produce the empty string. 196 | # .d files contain ? instead of spaces, take that into account. 197 | command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ 198 | $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) 199 | 200 | # Helper that is non-empty when a prerequisite changes. 201 | # Normally make does this implicitly, but we force rules to always run 202 | # so we can check their command lines. 203 | # $? -- new prerequisites 204 | # $| -- order-only dependencies 205 | prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) 206 | 207 | # Helper that executes all postbuilds until one fails. 208 | define do_postbuilds 209 | @E=0;\ 210 | for p in $(POSTBUILDS); do\ 211 | eval $$p;\ 212 | E=$$?;\ 213 | if [ $$E -ne 0 ]; then\ 214 | break;\ 215 | fi;\ 216 | done;\ 217 | if [ $$E -ne 0 ]; then\ 218 | rm -rf "$@";\ 219 | exit $$E;\ 220 | fi 221 | endef 222 | 223 | # do_cmd: run a command via the above cmd_foo names, if necessary. 224 | # Should always run for a given target to handle command-line changes. 225 | # Second argument, if non-zero, makes it do asm/C/C++ dependency munging. 226 | # Third argument, if non-zero, makes it do POSTBUILDS processing. 227 | # Note: We intentionally do NOT call dirx for depfile, since it contains ? for 228 | # spaces already and dirx strips the ? characters. 229 | define do_cmd 230 | $(if $(or $(command_changed),$(prereq_changed)), 231 | @$(call exact_echo, $($(quiet)cmd_$(1))) 232 | @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" 233 | $(if $(findstring flock,$(word 1,$(cmd_$1))), 234 | @$(cmd_$(1)) 235 | @echo " $(quiet_cmd_$(1)): Finished", 236 | @$(cmd_$(1)) 237 | ) 238 | @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) 239 | @$(if $(2),$(fixup_dep)) 240 | $(if $(and $(3), $(POSTBUILDS)), 241 | $(call do_postbuilds) 242 | ) 243 | ) 244 | endef 245 | 246 | # Declare the "all" target first so it is the default, 247 | # even though we don't have the deps yet. 248 | .PHONY: all 249 | all: 250 | 251 | # make looks for ways to re-generate included makefiles, but in our case, we 252 | # don't have a direct way. Explicitly telling make that it has nothing to do 253 | # for them makes it go faster. 254 | %.d: ; 255 | 256 | # Use FORCE_DO_CMD to force a target to run. Should be coupled with 257 | # do_cmd. 258 | .PHONY: FORCE_DO_CMD 259 | FORCE_DO_CMD: 260 | 261 | TOOLSET := target 262 | # Suffix rules, putting all outputs into $(obj). 263 | $(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD 264 | @$(call do_cmd,cc,1) 265 | $(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD 266 | @$(call do_cmd,cxx,1) 267 | $(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD 268 | @$(call do_cmd,cxx,1) 269 | $(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD 270 | @$(call do_cmd,cxx,1) 271 | $(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD 272 | @$(call do_cmd,cc,1) 273 | $(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD 274 | @$(call do_cmd,cc,1) 275 | 276 | # Try building from generated source, too. 277 | $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD 278 | @$(call do_cmd,cc,1) 279 | $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD 280 | @$(call do_cmd,cxx,1) 281 | $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD 282 | @$(call do_cmd,cxx,1) 283 | $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD 284 | @$(call do_cmd,cxx,1) 285 | $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD 286 | @$(call do_cmd,cc,1) 287 | $(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD 288 | @$(call do_cmd,cc,1) 289 | 290 | $(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD 291 | @$(call do_cmd,cc,1) 292 | $(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD 293 | @$(call do_cmd,cxx,1) 294 | $(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD 295 | @$(call do_cmd,cxx,1) 296 | $(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD 297 | @$(call do_cmd,cxx,1) 298 | $(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD 299 | @$(call do_cmd,cc,1) 300 | $(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD 301 | @$(call do_cmd,cc,1) 302 | 303 | 304 | ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ 305 | $(findstring $(join ^,$(prefix)),\ 306 | $(join ^,tree_sitter_sexp_binding.target.mk)))),) 307 | include tree_sitter_sexp_binding.target.mk 308 | endif 309 | 310 | quiet_cmd_regen_makefile = ACTION Regenerating $@ 311 | cmd_regen_makefile = cd $(srcdir); /home/ostera/.fnm/node-versions/v12.13.1/installation/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/home/ostera/.cache/node-gyp/12.13.1" "-Dnode_gyp_dir=/home/ostera/.fnm/node-versions/v12.13.1/installation/lib/node_modules/npm/node_modules/node-gyp" "-Dnode_lib_file=/home/ostera/.cache/node-gyp/12.13.1/<(target_arch)/node.lib" "-Dmodule_root_dir=/home/ostera/repos/github.com/AbstractMachinesLab/tree-sitter-sexp" "-Dnode_engine=v8" "--depth=." "-Goutput_dir=." "--generator-output=build" -I/home/ostera/repos/github.com/AbstractMachinesLab/tree-sitter-sexp/build/config.gypi -I/home/ostera/.fnm/node-versions/v12.13.1/installation/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/home/ostera/.cache/node-gyp/12.13.1/include/node/common.gypi "--toplevel-dir=." binding.gyp 312 | Makefile: $(srcdir)/binding.gyp $(srcdir)/build/config.gypi $(srcdir)/../../../../.cache/node-gyp/12.13.1/include/node/common.gypi $(srcdir)/../../../../.fnm/node-versions/v12.13.1/installation/lib/node_modules/npm/node_modules/node-gyp/addon.gypi 313 | $(call do_cmd,regen_makefile) 314 | 315 | # "all" is a concatenation of the "all" targets from all the included 316 | # sub-makefiles. This is just here to clarify. 317 | all: 318 | 319 | # Add in dependency-tracking rules. $(all_deps) is the list of every single 320 | # target in our tree. Only consider the ones with .d (dependency) info: 321 | d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) 322 | ifneq ($(d_files),) 323 | include $(d_files) 324 | endif 325 | -------------------------------------------------------------------------------- /build/binding.Makefile: -------------------------------------------------------------------------------- 1 | # This file is generated by gyp; do not edit. 2 | 3 | export builddir_name ?= ./build/. 4 | .PHONY: all 5 | all: 6 | $(MAKE) tree_sitter_sexp_binding 7 | -------------------------------------------------------------------------------- /build/config.gypi: -------------------------------------------------------------------------------- 1 | # Do not edit. File was generated by node-gyp's "configure" step 2 | { 3 | "target_defaults": { 4 | "cflags": [], 5 | "default_configuration": "Release", 6 | "defines": [], 7 | "include_dirs": [], 8 | "libraries": [] 9 | }, 10 | "variables": { 11 | "asan": 0, 12 | "build_v8_with_gn": "false", 13 | "coverage": "false", 14 | "debug_nghttp2": "false", 15 | "enable_lto": "false", 16 | "enable_pgo_generate": "false", 17 | "enable_pgo_use": "false", 18 | "force_dynamic_crt": 0, 19 | "gas_version": "2.27", 20 | "host_arch": "x64", 21 | "icu_data_in": "../../deps/icu-small/source/data/in/icudt64l.dat", 22 | "icu_endianness": "l", 23 | "icu_gyp_path": "tools/icu/icu-generic.gyp", 24 | "icu_locales": "en,root", 25 | "icu_path": "deps/icu-small", 26 | "icu_small": "true", 27 | "icu_ver_major": "64", 28 | "is_debug": 0, 29 | "llvm_version": "0.0", 30 | "napi_build_version": "5", 31 | "node_byteorder": "little", 32 | "node_code_cache": "yes", 33 | "node_debug_lib": "false", 34 | "node_enable_d8": "false", 35 | "node_install_npm": "true", 36 | "node_module_version": 72, 37 | "node_no_browser_globals": "false", 38 | "node_prefix": "/", 39 | "node_release_urlbase": "https://nodejs.org/download/release/", 40 | "node_report": "true", 41 | "node_shared": "false", 42 | "node_shared_cares": "false", 43 | "node_shared_http_parser": "false", 44 | "node_shared_libuv": "false", 45 | "node_shared_nghttp2": "false", 46 | "node_shared_openssl": "false", 47 | "node_shared_zlib": "false", 48 | "node_tag": "", 49 | "node_target_type": "executable", 50 | "node_use_bundled_v8": "true", 51 | "node_use_dtrace": "false", 52 | "node_use_etw": "false", 53 | "node_use_large_pages": "false", 54 | "node_use_large_pages_script_lld": "false", 55 | "node_use_node_snapshot": "true", 56 | "node_use_openssl": "true", 57 | "node_use_v8_platform": "true", 58 | "node_with_ltcg": "false", 59 | "node_without_node_options": "false", 60 | "openssl_fips": "", 61 | "openssl_is_fips": "false", 62 | "shlib_suffix": "so.72", 63 | "target_arch": "x64", 64 | "v8_enable_gdbjit": 0, 65 | "v8_enable_i18n_support": 1, 66 | "v8_enable_inspector": 1, 67 | "v8_no_strict_aliasing": 1, 68 | "v8_optimized_debug": 1, 69 | "v8_promise_internal_field_count": 1, 70 | "v8_random_seed": 0, 71 | "v8_trace_maps": 0, 72 | "v8_use_siphash": 1, 73 | "v8_use_snapshot": 1, 74 | "want_separate_host_toolset": 0, 75 | "nodedir": "/home/ostera/.cache/node-gyp/12.13.1", 76 | "standalone_static_library": 1, 77 | "version_commit_hooks": "true", 78 | "user_agent": "yarn/1.21.1 npm/? node/v12.13.1 linux x64", 79 | "npmScopes": "{\"kci\":{\"npmAlwaysAuth\":true,\"npmAuthToken\":\"bGVhbmRyby5vc3RlcmE6NzlWakpNVUtkbDVuQngxeA==\",\"npmRegistryServer\":\"https://npm.kci.rocks/repository/npmprivate\"}}", 80 | "bin_links": "true", 81 | "init_version": "1.0.0", 82 | "init_license": "MIT", 83 | "version_tag_prefix": "v", 84 | "npmRegistryServer": "https://npm.kci.rocks/repository/npmgroup", 85 | "registry": "https://registry.yarnpkg.com", 86 | "ignore_scripts": "", 87 | "version_git_message": "v%s", 88 | "version_git_tag": "true", 89 | "version_git_sign": "", 90 | "strict_ssl": "true", 91 | "save_prefix": "^", 92 | "ignore_optional": "" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /grammar.js: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////// 2 | // 3 | // Tokens 4 | // 5 | /////////////////////////////////////////////////////////////////////////////// 6 | const PARENS_LEFT = "("; 7 | const PARENS_RIGHT = ")"; 8 | 9 | /////////////////////////////////////////////////////////////////////////////// 10 | // 11 | // Precedences 12 | // 13 | /////////////////////////////////////////////////////////////////////////////// 14 | const PREC = {}; 15 | 16 | /////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // Combinators 19 | // 20 | /////////////////////////////////////////////////////////////////////////////// 21 | const delim = (open, x, close) => seq(open, x, close); 22 | 23 | /////////////////////////////////////////////////////////////////////////////// 24 | // 25 | // Grammar 26 | // 27 | /////////////////////////////////////////////////////////////////////////////// 28 | module.exports = grammar({ 29 | name: "sexp", 30 | 31 | rules: { 32 | sexp: ($) => $._sexp, 33 | 34 | _sexp: ($) => choice($.atom, $.list), 35 | 36 | atom: ($) => /[_@a-zA-Z0-9\xC0-\xD6\xD8-\xDE\xDF-\xF6\xF8-\xFF:-]+/, 37 | list: ($) => delim(PARENS_LEFT, repeat($._sexp), PARENS_RIGHT), 38 | }, 39 | }); 40 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | try { 2 | module.exports = require("./build/Release/tree_sitter_sexp_binding"); 3 | } catch (error) { 4 | try { 5 | module.exports = require("./build/Debug/tree_sitter_sexp_binding"); 6 | } catch (_) { 7 | throw error 8 | } 9 | } 10 | 11 | try { 12 | module.exports.nodeTypeInfo = require("./src/node-types.json"); 13 | } catch (_) {} 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tree-parser-sexp", 3 | "version": "0.0.0", 4 | "description": "Tree Parser support for S-expressions", 5 | "author": "Leandro Ostera ", 6 | "license": "Apache-2.0", 7 | "dependencies": { 8 | "nan": "^2.14.1", 9 | "prettier": "^2.2.1", 10 | "tree-sitter-cli": "^0.17.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/big_fixture.in.sexp: -------------------------------------------------------------------------------- 1 | 2 | (source_file (module_name (atom (unquoted_atom))) (module_export (atom (unquoted_atom)) (integer)) (module_export (atom (unquoted_atom)) (integer)) (module_export (atom (unquoted_atom)) (integer)) (function_declaration (function_clause (atom (unquoted_atom)) (lambda_clause (pattern (variable)) (pattern (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (case (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))) (expression (variable)))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (tuple (expression (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))) (expression (variable)))))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (atom (unquoted_atom)))))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))))) (function_declaration (function_clause (atom (unquoted_atom)) (lambda_clause (pattern (variable)) (pattern (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (case (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (tuple (expression (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (atom (unquoted_atom)))))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))))) (function_declaration (function_clause (atom (unquoted_atom)) (lambda_clause (expression (term (list (expression (function_call (computed_function_name (expression (term (atom (unquoted_atom))))) (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list)))))))))))))) (expression (term (list (expression (function_call (computed_function_name (expression (term (atom (unquoted_atom))))) (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list)))))))))))))) (expression (term (list))))))))))))) 3 | -------------------------------------------------------------------------------- /src/big_fixture.out.sexp: -------------------------------------------------------------------------------- 1 | (source_file 2 | (module_name (atom (unquoted_atom))) 3 | (module_export (atom (unquoted_atom)) (integer)) 4 | (module_export (atom (unquoted_atom)) (integer)) 5 | (module_export (atom (unquoted_atom)) (integer)) 6 | (function_declaration 7 | (function_clause 8 | (atom (unquoted_atom)) 9 | (lambda_clause 10 | (pattern (variable)) 11 | (pattern (variable)) 12 | (expression 13 | (function_call 14 | (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) 15 | (expression 16 | (lambda 17 | (lambda_clause 18 | (pattern (variable)) 19 | (pattern (variable)) 20 | (expression 21 | (case 22 | (expression (variable)) 23 | (case_clause 24 | (pattern (term (atom (unquoted_atom)))) 25 | (expression 26 | (function_call 27 | (qualified_function_name 28 | (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) 29 | (expression 30 | (lambda 31 | (lambda_clause 32 | (pattern (variable)) 33 | (pattern (variable)) 34 | (expression 35 | (case 36 | (expression (variable)) 37 | (case_clause 38 | (pattern (term (atom (unquoted_atom)))) 39 | (expression 40 | (function_call 41 | (qualified_function_name 42 | (expression (term (atom (unquoted_atom)))) 43 | (atom (unquoted_atom))) 44 | (expression 45 | (lambda 46 | (lambda_clause 47 | (pattern (variable)) 48 | (pattern (variable)) 49 | (expression 50 | (case 51 | (expression (variable)) 52 | (case_clause 53 | (pattern (term (atom (unquoted_atom)))) 54 | (expression 55 | (case 56 | (expression 57 | (function_call 58 | (qualified_function_name 59 | (expression 60 | (term (atom (unquoted_atom)))) 61 | (atom (quoted_atom))) 62 | (expression (variable)) 63 | (expression 64 | (function_call 65 | (qualified_function_name 66 | (expression 67 | (term 68 | (atom (unquoted_atom)))) 69 | (atom (quoted_atom))) 70 | (expression 71 | (function_call 72 | (qualified_function_name 73 | (expression 74 | (term 75 | (atom (unquoted_atom)))) 76 | (atom 77 | (quoted_atom))) 78 | (expression (variable)) 79 | (expression (variable)))) 80 | (expression (variable)))))) 81 | (case_clause 82 | (pattern 83 | (term (atom (unquoted_atom)))) 84 | (expression 85 | (term 86 | (tuple 87 | (expression 88 | (term 89 | (atom (unquoted_atom)))) 90 | (expression 91 | (function_call 92 | (qualified_function_name 93 | (expression 94 | (term 95 | (atom (unquoted_atom)))) 96 | (atom 97 | (quoted_atom))) 98 | (expression 99 | (function_call 100 | (qualified_function_name 101 | (expression 102 | (term 103 | (atom 104 | (unquoted_atom)))) 105 | (atom 106 | (quoted_atom))) 107 | (expression 108 | (variable)) 109 | (expression (variable)))) 110 | (expression (variable)))))))) 111 | (case_clause 112 | (pattern 113 | (term (atom (unquoted_atom)))) 114 | (expression 115 | (term (atom (unquoted_atom)))))))) 116 | (case_clause 117 | (pattern (variable)) 118 | (expression (variable)))))))) 119 | (expression (term (atom (unquoted_atom)))) 120 | (expression (variable))))) 121 | (case_clause (pattern (variable)) (expression (variable)))))))) 122 | (expression (term (atom (unquoted_atom)))) 123 | (expression (variable))))) 124 | (case_clause (pattern (variable)) (expression (variable)))))))) 125 | (expression (term (atom (unquoted_atom)))) 126 | (expression (variable))))))) 127 | (function_declaration 128 | (function_clause 129 | (atom (unquoted_atom)) 130 | (lambda_clause 131 | (pattern (variable)) 132 | (pattern (variable)) 133 | (expression 134 | (function_call 135 | (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) 136 | (expression 137 | (lambda 138 | (lambda_clause 139 | (pattern (variable)) 140 | (pattern (variable)) 141 | (expression 142 | (case 143 | (expression (variable)) 144 | (case_clause 145 | (pattern (term (atom (unquoted_atom)))) 146 | (expression 147 | (function_call 148 | (qualified_function_name 149 | (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) 150 | (expression 151 | (lambda 152 | (lambda_clause 153 | (pattern (variable)) 154 | (pattern (variable)) 155 | (expression 156 | (case 157 | (expression (variable)) 158 | (case_clause 159 | (pattern (term (atom (unquoted_atom)))) 160 | (expression 161 | (case 162 | (expression 163 | (function_call 164 | (qualified_function_name 165 | (expression (term (atom (unquoted_atom)))) 166 | (atom (quoted_atom))) 167 | (expression (variable)) 168 | (expression 169 | (function_call 170 | (qualified_function_name 171 | (expression 172 | (term (atom (unquoted_atom)))) 173 | (atom (quoted_atom))) 174 | (expression (variable)) 175 | (expression (variable)))))) 176 | (case_clause 177 | (pattern (term (atom (unquoted_atom)))) 178 | (expression 179 | (term 180 | (tuple 181 | (expression (term (atom (unquoted_atom)))) 182 | (expression 183 | (function_call 184 | (qualified_function_name 185 | (expression 186 | (term (atom (unquoted_atom)))) 187 | (atom (quoted_atom))) 188 | (expression (variable)) 189 | (expression (variable)))))))) 190 | (case_clause 191 | (pattern (term (atom (unquoted_atom)))) 192 | (expression (term (atom (unquoted_atom)))))))) 193 | (case_clause (pattern (variable)) (expression (variable)))))))) 194 | (expression (term (atom (unquoted_atom)))) 195 | (expression (variable))))) 196 | (case_clause (pattern (variable)) (expression (variable)))))))) 197 | (expression (term (atom (unquoted_atom)))) 198 | (expression (variable))))))) 199 | (function_declaration 200 | (function_clause 201 | (atom (unquoted_atom)) 202 | (lambda_clause 203 | (expression 204 | (term 205 | (list 206 | (expression 207 | (function_call 208 | (computed_function_name (expression (term (atom (unquoted_atom))))) 209 | (expression (term (integer))) 210 | (expression 211 | (term 212 | (list 213 | (expression (term (integer))) 214 | (expression 215 | (term 216 | (list (expression (term (integer))) 217 | (expression 218 | (term (list (expression (term (integer))) (expression (term (list)))))))))))))) 219 | (expression 220 | (term 221 | (list 222 | (expression 223 | (function_call 224 | (computed_function_name (expression (term (atom (unquoted_atom))))) 225 | (expression (term (integer))) 226 | (expression 227 | (term 228 | (list 229 | (expression (term (integer))) 230 | (expression 231 | (term 232 | (list 233 | (expression (term (integer))) 234 | (expression 235 | (term 236 | (list (expression (term (integer))) (expression (term (list)))))))))))))) 237 | (expression (term (list))))))))))))) 238 | -------------------------------------------------------------------------------- /src/binding.cc: -------------------------------------------------------------------------------- 1 | #include "tree_sitter/parser.h" 2 | #include 3 | #include "nan.h" 4 | 5 | using namespace v8; 6 | 7 | extern "C" TSLanguage * tree_sitter_sexp(); 8 | 9 | namespace { 10 | 11 | NAN_METHOD(New) {} 12 | 13 | void Init(Local exports, Local module) { 14 | Local tpl = Nan::New(New); 15 | tpl->SetClassName(Nan::New("Language").ToLocalChecked()); 16 | tpl->InstanceTemplate()->SetInternalFieldCount(1); 17 | 18 | Local constructor = Nan::GetFunction(tpl).ToLocalChecked(); 19 | Local instance = constructor->NewInstance(Nan::GetCurrentContext()).ToLocalChecked(); 20 | Nan::SetInternalFieldPointer(instance, 0, tree_sitter_sexp()); 21 | 22 | Nan::Set(instance, Nan::New("name").ToLocalChecked(), Nan::New("sexp").ToLocalChecked()); 23 | Nan::Set(module, Nan::New("exports").ToLocalChecked(), instance); 24 | } 25 | 26 | NODE_MODULE(tree_sitter_sexp_binding, Init) 27 | 28 | } // namespace 29 | -------------------------------------------------------------------------------- /src/ffi.rs: -------------------------------------------------------------------------------- 1 | use tree_sitter::{Language, Parser}; 2 | 3 | extern "C" { 4 | fn tree_sitter_sexp() -> Language; 5 | } 6 | 7 | pub fn parser() -> Parser { 8 | let language = unsafe { tree_sitter_sexp() }; 9 | let mut parser = Parser::new(); 10 | parser.set_language(language).unwrap(); 11 | parser 12 | } 13 | -------------------------------------------------------------------------------- /src/grammar.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sexp", 3 | "rules": { 4 | "sexp": { 5 | "type": "SYMBOL", 6 | "name": "_sexp" 7 | }, 8 | "_sexp": { 9 | "type": "CHOICE", 10 | "members": [ 11 | { 12 | "type": "SYMBOL", 13 | "name": "atom" 14 | }, 15 | { 16 | "type": "SYMBOL", 17 | "name": "list" 18 | } 19 | ] 20 | }, 21 | "atom": { 22 | "type": "PATTERN", 23 | "value": "[_@a-zA-Z0-9\\xC0-\\xD6\\xD8-\\xDE\\xDF-\\xF6\\xF8-\\xFF:-]+" 24 | }, 25 | "list": { 26 | "type": "SEQ", 27 | "members": [ 28 | { 29 | "type": "STRING", 30 | "value": "(" 31 | }, 32 | { 33 | "type": "REPEAT", 34 | "content": { 35 | "type": "SYMBOL", 36 | "name": "_sexp" 37 | } 38 | }, 39 | { 40 | "type": "STRING", 41 | "value": ")" 42 | } 43 | ] 44 | } 45 | }, 46 | "extras": [ 47 | { 48 | "type": "PATTERN", 49 | "value": "\\s" 50 | } 51 | ], 52 | "conflicts": [], 53 | "externals": [], 54 | "inline": [], 55 | "supertypes": [] 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{anyhow, Context, Error}; 2 | use std::fmt; 3 | 4 | mod ffi; 5 | 6 | #[derive(Clone, Debug)] 7 | pub enum Sexp { 8 | Atom(String), 9 | List(Vec), 10 | Nil, 11 | } 12 | 13 | impl Sexp { 14 | pub fn of_str(input: &str) -> Result { 15 | let mut parser = ffi::parser(); 16 | let tree = parser 17 | .parse(input, None) 18 | .context("Could not parse anything")?; 19 | let root = tree.root_node(); 20 | 21 | let mut walker = root.walk(); 22 | walker.goto_first_child(); // we skip the top-level `sexp` node 23 | Sexp::build_tree(walker.node(), input.as_bytes()) 24 | } 25 | 26 | fn build_tree(root: tree_sitter::Node, bytes: &[u8]) -> Result { 27 | match root.kind() { 28 | "atom" => { 29 | let text = root.utf8_text(&bytes)?.to_string(); 30 | Ok(Sexp::Atom(text)) 31 | } 32 | kind @ "list" | kind @ "ERROR" | kind @ "MISSING" => { 33 | let mut walker = root.walk(); 34 | walker.goto_first_child(); 35 | let mut children = match kind { 36 | "list" => vec![], 37 | _ => vec![Sexp::Atom(kind.to_string())], 38 | }; 39 | while walker.goto_next_sibling() { 40 | let child = walker.node(); 41 | children.push(Sexp::build_tree(child, bytes)?); 42 | } 43 | Ok(Sexp::List(children)) 44 | } 45 | ")" => Ok(Sexp::Nil), 46 | kind => Err(anyhow!("Unknown node kind {:?}", kind)), 47 | } 48 | } 49 | 50 | pub fn size(&self) -> u32 { 51 | match self { 52 | Sexp::Nil => 0, 53 | Sexp::Atom(s) => s.len() as u32, 54 | Sexp::List(parts) => { 55 | let mut s = 0; 56 | for p in parts { 57 | s += p.size(); 58 | } 59 | s 60 | } 61 | } 62 | } 63 | } 64 | 65 | #[derive(Debug)] 66 | pub struct PrettyPrinter { 67 | max_width: u32, 68 | current_width: u32, 69 | indent_size: u32, 70 | current_depth: u32, 71 | } 72 | 73 | impl PrettyPrinter { 74 | pub fn new() -> PrettyPrinter { 75 | PrettyPrinter { 76 | current_depth: 0, 77 | max_width: 150, 78 | current_width: 0, 79 | indent_size: 1, 80 | } 81 | } 82 | 83 | fn padding(&self) -> u32 { 84 | if self.current_depth == 0 { 85 | 0 86 | } else { 87 | (self.current_depth - 1) * self.indent_size 88 | } 89 | } 90 | 91 | pub fn pp(&mut self, sexp: &Sexp, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 92 | match sexp { 93 | Sexp::Atom(atom) => { 94 | self.current_width += atom.len() as u32; 95 | write!(fmt, "{}", atom) 96 | } 97 | Sexp::Nil => { 98 | self.current_depth -= 1; 99 | Ok(()) 100 | } 101 | Sexp::List(parts) if parts.len() > 0 => { 102 | self.current_depth += 1; 103 | let next_term_width = self.current_width + self.padding() + sexp.size(); 104 | let term_overflows = next_term_width > self.max_width / 2; 105 | 106 | if term_overflows && self.current_depth > 1 { 107 | self.current_width = self.padding(); 108 | } 109 | 110 | write!(fmt, "(")?; 111 | self.pp(&parts[0], fmt)?; 112 | 113 | for p in parts[1..].iter() { 114 | match p { 115 | Sexp::Nil => { 116 | self.pp(&p, fmt)?; 117 | } 118 | _ => { 119 | let part_size = next_term_width + self.padding() + p.size(); 120 | let part_will_overflow = part_size > self.max_width; 121 | if part_will_overflow { 122 | write!(fmt, "\n")?; 123 | for _ in 0..(self.padding() + self.indent_size) { 124 | write!(fmt, " ")? 125 | } 126 | self.pp(&p, fmt)?; 127 | } else { 128 | write!(fmt, " ")?; 129 | self.pp(&p, fmt)?; 130 | } 131 | } 132 | } 133 | } 134 | write!(fmt, ")")?; 135 | 136 | Ok(()) 137 | } 138 | Sexp::List(_) => write!(fmt, "()"), 139 | } 140 | } 141 | } 142 | 143 | impl fmt::Display for Sexp { 144 | fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { 145 | PrettyPrinter::new().pp(self, fmt) 146 | } 147 | } 148 | 149 | #[cfg(test)] 150 | mod tests { 151 | use super::*; 152 | 153 | #[test] 154 | fn test_error_sexpr() { 155 | assert_eq!(Sexp::of_str(&"(sexp (").is_err(), true,); 156 | } 157 | 158 | #[test] 159 | fn test_single_sexpr() { 160 | assert_eq!( 161 | Sexp::of_str(&"source_file").unwrap().to_string(), 162 | r#"source_file"#.trim().to_string() 163 | ); 164 | } 165 | 166 | #[test] 167 | fn test_sibling_sexpr() { 168 | assert_eq!( 169 | Sexp::of_str(&"(source file)").unwrap().to_string(), 170 | r#"(source file)"#.trim().to_string() 171 | ); 172 | assert_eq!( 173 | Sexp::of_str(&"(source file tree)").unwrap().to_string(), 174 | r#"(source file tree)"#.trim().to_string() 175 | ); 176 | } 177 | 178 | #[test] 179 | fn test_nested_sexpr() { 180 | assert_eq!( 181 | Sexp::of_str(&"(source (file))").unwrap().to_string(), 182 | r#"(source (file))"#.trim().to_string() 183 | ); 184 | } 185 | 186 | #[test] 187 | fn test_nested_sibling_sexpr() { 188 | assert_eq!( 189 | Sexp::of_str(&"(source (file tree))").unwrap().to_string(), 190 | r#"(source (file tree))"#.trim().to_string() 191 | ); 192 | } 193 | 194 | #[test] 195 | fn test_field_sexpr() { 196 | assert_eq!( 197 | Sexp::of_str(&"(source file: test)").unwrap().to_string(), 198 | r#"(source file: test)"#.trim().to_string() 199 | ); 200 | } 201 | 202 | #[test] 203 | fn test_real_life_sexpr() { 204 | let sexp = Sexp::of_str(include_str!("./big_fixture.in.sexp")).unwrap(); 205 | println!("{}", sexp); 206 | assert_eq!( 207 | sexp.to_string(), 208 | include_str!("./big_fixture.out.sexp").trim().to_string() 209 | ); 210 | } 211 | 212 | #[test] 213 | fn test_pretty_printing_sexpr() { 214 | let sexp = Sexp::of_str( 215 | &" 216 | 217 | 218 | 219 | (source_file 220 | (expression 221 | (function_call 222 | (qualified_function_name 223 | (expression 224 | (term 225 | (atom 226 | (unquoted_atom)))) 227 | (atom 228 | (unquoted_atom))) 229 | (expression 230 | (term 231 | (integer))) 232 | (expression 233 | (function_call 234 | (qualified_function_name 235 | (expression 236 | (term 237 | (atom 238 | (unquoted_atom)))) 239 | (atom 240 | (unquoted_atom))) 241 | (expression 242 | (term 243 | (integer))) 244 | (expression 245 | (term 246 | (integer))) 247 | (expression 248 | (term 249 | (integer)))))))) 250 | 251 | ", 252 | ) 253 | .unwrap(); 254 | println!("{}", sexp); 255 | assert_eq!( 256 | sexp.to_string(), 257 | r#"(source_file 258 | (expression 259 | (function_call 260 | (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) 261 | (expression (term (integer))) 262 | (expression 263 | (function_call 264 | (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) 265 | (expression (term (integer))) 266 | (expression (term (integer))) 267 | (expression (term (integer))))))))"# 268 | .to_string() 269 | ); 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /src/node-types.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "list", 4 | "named": true, 5 | "fields": {}, 6 | "children": { 7 | "multiple": true, 8 | "required": false, 9 | "types": [ 10 | { 11 | "type": "atom", 12 | "named": true 13 | }, 14 | { 15 | "type": "list", 16 | "named": true 17 | } 18 | ] 19 | } 20 | }, 21 | { 22 | "type": "sexp", 23 | "named": true, 24 | "fields": {}, 25 | "children": { 26 | "multiple": false, 27 | "required": true, 28 | "types": [ 29 | { 30 | "type": "atom", 31 | "named": true 32 | }, 33 | { 34 | "type": "list", 35 | "named": true 36 | } 37 | ] 38 | } 39 | }, 40 | { 41 | "type": "(", 42 | "named": false 43 | }, 44 | { 45 | "type": ")", 46 | "named": false 47 | }, 48 | { 49 | "type": "atom", 50 | "named": true 51 | } 52 | ] -------------------------------------------------------------------------------- /src/parser.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #if defined(__GNUC__) || defined(__clang__) 4 | #pragma GCC diagnostic push 5 | #pragma GCC diagnostic ignored "-Wmissing-field-initializers" 6 | #endif 7 | 8 | #define LANGUAGE_VERSION 12 9 | #define STATE_COUNT 9 10 | #define LARGE_STATE_COUNT 5 11 | #define SYMBOL_COUNT 8 12 | #define ALIAS_COUNT 0 13 | #define TOKEN_COUNT 4 14 | #define EXTERNAL_TOKEN_COUNT 0 15 | #define FIELD_COUNT 0 16 | #define MAX_ALIAS_SEQUENCE_LENGTH 3 17 | 18 | enum { 19 | sym_atom = 1, 20 | anon_sym_LPAREN = 2, 21 | anon_sym_RPAREN = 3, 22 | sym_sexp = 4, 23 | sym__sexp = 5, 24 | sym_list = 6, 25 | aux_sym_list_repeat1 = 7, 26 | }; 27 | 28 | static const char *ts_symbol_names[] = { 29 | [ts_builtin_sym_end] = "end", 30 | [sym_atom] = "atom", 31 | [anon_sym_LPAREN] = "(", 32 | [anon_sym_RPAREN] = ")", 33 | [sym_sexp] = "sexp", 34 | [sym__sexp] = "_sexp", 35 | [sym_list] = "list", 36 | [aux_sym_list_repeat1] = "list_repeat1", 37 | }; 38 | 39 | static TSSymbol ts_symbol_map[] = { 40 | [ts_builtin_sym_end] = ts_builtin_sym_end, 41 | [sym_atom] = sym_atom, 42 | [anon_sym_LPAREN] = anon_sym_LPAREN, 43 | [anon_sym_RPAREN] = anon_sym_RPAREN, 44 | [sym_sexp] = sym_sexp, 45 | [sym__sexp] = sym__sexp, 46 | [sym_list] = sym_list, 47 | [aux_sym_list_repeat1] = aux_sym_list_repeat1, 48 | }; 49 | 50 | static const TSSymbolMetadata ts_symbol_metadata[] = { 51 | [ts_builtin_sym_end] = { 52 | .visible = false, 53 | .named = true, 54 | }, 55 | [sym_atom] = { 56 | .visible = true, 57 | .named = true, 58 | }, 59 | [anon_sym_LPAREN] = { 60 | .visible = true, 61 | .named = false, 62 | }, 63 | [anon_sym_RPAREN] = { 64 | .visible = true, 65 | .named = false, 66 | }, 67 | [sym_sexp] = { 68 | .visible = true, 69 | .named = true, 70 | }, 71 | [sym__sexp] = { 72 | .visible = false, 73 | .named = true, 74 | }, 75 | [sym_list] = { 76 | .visible = true, 77 | .named = true, 78 | }, 79 | [aux_sym_list_repeat1] = { 80 | .visible = false, 81 | .named = false, 82 | }, 83 | }; 84 | 85 | static TSSymbol ts_alias_sequences[1][MAX_ALIAS_SEQUENCE_LENGTH] = { 86 | [0] = {0}, 87 | }; 88 | 89 | static uint16_t ts_non_terminal_alias_map[] = { 90 | 0, 91 | }; 92 | 93 | static bool ts_lex(TSLexer *lexer, TSStateId state) { 94 | START_LEXER(); 95 | eof = lexer->eof(lexer); 96 | switch (state) { 97 | case 0: 98 | if (eof) ADVANCE(1); 99 | if (lookahead == '(') ADVANCE(3); 100 | if (lookahead == ')') ADVANCE(4); 101 | if (lookahead == '\t' || 102 | lookahead == '\n' || 103 | lookahead == '\r' || 104 | lookahead == ' ') SKIP(0) 105 | if (lookahead == '-' || 106 | ('0' <= lookahead && lookahead <= ':') || 107 | ('@' <= lookahead && lookahead <= 'Z') || 108 | lookahead == '_' || 109 | ('a' <= lookahead && lookahead <= 'z') || 110 | (192 <= lookahead && lookahead <= 214) || 111 | (216 <= lookahead && lookahead <= 246) || 112 | (248 <= lookahead && lookahead <= 255)) ADVANCE(2); 113 | END_STATE(); 114 | case 1: 115 | ACCEPT_TOKEN(ts_builtin_sym_end); 116 | END_STATE(); 117 | case 2: 118 | ACCEPT_TOKEN(sym_atom); 119 | if (lookahead == '-' || 120 | ('0' <= lookahead && lookahead <= ':') || 121 | ('@' <= lookahead && lookahead <= 'Z') || 122 | lookahead == '_' || 123 | ('a' <= lookahead && lookahead <= 'z') || 124 | (192 <= lookahead && lookahead <= 214) || 125 | (216 <= lookahead && lookahead <= 246) || 126 | (248 <= lookahead && lookahead <= 255)) ADVANCE(2); 127 | END_STATE(); 128 | case 3: 129 | ACCEPT_TOKEN(anon_sym_LPAREN); 130 | END_STATE(); 131 | case 4: 132 | ACCEPT_TOKEN(anon_sym_RPAREN); 133 | END_STATE(); 134 | default: 135 | return false; 136 | } 137 | } 138 | 139 | static TSLexMode ts_lex_modes[STATE_COUNT] = { 140 | [0] = {.lex_state = 0}, 141 | [1] = {.lex_state = 0}, 142 | [2] = {.lex_state = 0}, 143 | [3] = {.lex_state = 0}, 144 | [4] = {.lex_state = 0}, 145 | [5] = {.lex_state = 0}, 146 | [6] = {.lex_state = 0}, 147 | [7] = {.lex_state = 0}, 148 | [8] = {.lex_state = 0}, 149 | }; 150 | 151 | static uint16_t ts_parse_table[LARGE_STATE_COUNT][SYMBOL_COUNT] = { 152 | [0] = { 153 | [ts_builtin_sym_end] = ACTIONS(1), 154 | [sym_atom] = ACTIONS(1), 155 | [anon_sym_LPAREN] = ACTIONS(1), 156 | [anon_sym_RPAREN] = ACTIONS(1), 157 | }, 158 | [1] = { 159 | [sym_sexp] = STATE(7), 160 | [sym__sexp] = STATE(8), 161 | [sym_list] = STATE(8), 162 | [sym_atom] = ACTIONS(3), 163 | [anon_sym_LPAREN] = ACTIONS(5), 164 | }, 165 | [2] = { 166 | [sym__sexp] = STATE(3), 167 | [sym_list] = STATE(3), 168 | [aux_sym_list_repeat1] = STATE(3), 169 | [sym_atom] = ACTIONS(7), 170 | [anon_sym_LPAREN] = ACTIONS(5), 171 | [anon_sym_RPAREN] = ACTIONS(9), 172 | }, 173 | [3] = { 174 | [sym__sexp] = STATE(4), 175 | [sym_list] = STATE(4), 176 | [aux_sym_list_repeat1] = STATE(4), 177 | [sym_atom] = ACTIONS(11), 178 | [anon_sym_LPAREN] = ACTIONS(5), 179 | [anon_sym_RPAREN] = ACTIONS(13), 180 | }, 181 | [4] = { 182 | [sym__sexp] = STATE(4), 183 | [sym_list] = STATE(4), 184 | [aux_sym_list_repeat1] = STATE(4), 185 | [sym_atom] = ACTIONS(15), 186 | [anon_sym_LPAREN] = ACTIONS(18), 187 | [anon_sym_RPAREN] = ACTIONS(21), 188 | }, 189 | }; 190 | 191 | static uint16_t ts_small_parse_table[] = { 192 | [0] = 1, 193 | ACTIONS(23), 4, 194 | ts_builtin_sym_end, 195 | sym_atom, 196 | anon_sym_LPAREN, 197 | anon_sym_RPAREN, 198 | [7] = 1, 199 | ACTIONS(25), 4, 200 | ts_builtin_sym_end, 201 | sym_atom, 202 | anon_sym_LPAREN, 203 | anon_sym_RPAREN, 204 | [14] = 1, 205 | ACTIONS(27), 1, 206 | ts_builtin_sym_end, 207 | [18] = 1, 208 | ACTIONS(29), 1, 209 | ts_builtin_sym_end, 210 | }; 211 | 212 | static uint32_t ts_small_parse_table_map[] = { 213 | [SMALL_STATE(5)] = 0, 214 | [SMALL_STATE(6)] = 7, 215 | [SMALL_STATE(7)] = 14, 216 | [SMALL_STATE(8)] = 18, 217 | }; 218 | 219 | static TSParseActionEntry ts_parse_actions[] = { 220 | [0] = {.entry = {.count = 0, .reusable = false}}, 221 | [1] = {.entry = {.count = 1, .reusable = false}}, RECOVER(), 222 | [3] = {.entry = {.count = 1, .reusable = true}}, SHIFT(8), 223 | [5] = {.entry = {.count = 1, .reusable = true}}, SHIFT(2), 224 | [7] = {.entry = {.count = 1, .reusable = true}}, SHIFT(3), 225 | [9] = {.entry = {.count = 1, .reusable = true}}, SHIFT(5), 226 | [11] = {.entry = {.count = 1, .reusable = true}}, SHIFT(4), 227 | [13] = {.entry = {.count = 1, .reusable = true}}, SHIFT(6), 228 | [15] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_list_repeat1, 2), SHIFT_REPEAT(4), 229 | [18] = {.entry = {.count = 2, .reusable = true}}, REDUCE(aux_sym_list_repeat1, 2), SHIFT_REPEAT(2), 230 | [21] = {.entry = {.count = 1, .reusable = true}}, REDUCE(aux_sym_list_repeat1, 2), 231 | [23] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_list, 2), 232 | [25] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_list, 3), 233 | [27] = {.entry = {.count = 1, .reusable = true}}, ACCEPT_INPUT(), 234 | [29] = {.entry = {.count = 1, .reusable = true}}, REDUCE(sym_sexp, 1), 235 | }; 236 | 237 | #ifdef __cplusplus 238 | extern "C" { 239 | #endif 240 | #ifdef _WIN32 241 | #define extern __declspec(dllexport) 242 | #endif 243 | 244 | extern const TSLanguage *tree_sitter_sexp(void) { 245 | static TSLanguage language = { 246 | .version = LANGUAGE_VERSION, 247 | .symbol_count = SYMBOL_COUNT, 248 | .alias_count = ALIAS_COUNT, 249 | .token_count = TOKEN_COUNT, 250 | .external_token_count = EXTERNAL_TOKEN_COUNT, 251 | .symbol_names = ts_symbol_names, 252 | .symbol_metadata = ts_symbol_metadata, 253 | .parse_table = (const uint16_t *)ts_parse_table, 254 | .parse_actions = ts_parse_actions, 255 | .lex_modes = ts_lex_modes, 256 | .alias_sequences = (const TSSymbol *)ts_alias_sequences, 257 | .max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH, 258 | .lex_fn = ts_lex, 259 | .field_count = FIELD_COUNT, 260 | .large_state_count = LARGE_STATE_COUNT, 261 | .small_parse_table = (const uint16_t *)ts_small_parse_table, 262 | .small_parse_table_map = (const uint32_t *)ts_small_parse_table_map, 263 | .public_symbol_map = ts_symbol_map, 264 | .alias_map = ts_non_terminal_alias_map, 265 | .state_count = STATE_COUNT, 266 | }; 267 | return &language; 268 | } 269 | #ifdef __cplusplus 270 | } 271 | #endif 272 | -------------------------------------------------------------------------------- /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 TSSymbol; 18 | typedef uint16_t TSFieldId; 19 | typedef struct TSLanguage TSLanguage; 20 | #endif 21 | 22 | typedef struct { 23 | TSFieldId field_id; 24 | uint8_t child_index; 25 | bool inherited; 26 | } TSFieldMapEntry; 27 | 28 | typedef struct { 29 | uint16_t index; 30 | uint16_t length; 31 | } TSFieldMapSlice; 32 | 33 | typedef uint16_t TSStateId; 34 | 35 | typedef struct { 36 | bool visible : 1; 37 | bool named : 1; 38 | bool supertype: 1; 39 | } TSSymbolMetadata; 40 | 41 | typedef struct TSLexer TSLexer; 42 | 43 | struct TSLexer { 44 | int32_t lookahead; 45 | TSSymbol result_symbol; 46 | void (*advance)(TSLexer *, bool); 47 | void (*mark_end)(TSLexer *); 48 | uint32_t (*get_column)(TSLexer *); 49 | bool (*is_at_included_range_start)(const TSLexer *); 50 | bool (*eof)(const TSLexer *); 51 | }; 52 | 53 | typedef enum { 54 | TSParseActionTypeShift, 55 | TSParseActionTypeReduce, 56 | TSParseActionTypeAccept, 57 | TSParseActionTypeRecover, 58 | } TSParseActionType; 59 | 60 | typedef struct { 61 | union { 62 | struct { 63 | TSStateId state; 64 | bool extra : 1; 65 | bool repetition : 1; 66 | } shift; 67 | struct { 68 | TSSymbol symbol; 69 | int16_t dynamic_precedence; 70 | uint8_t child_count; 71 | uint8_t production_id; 72 | } reduce; 73 | } params; 74 | TSParseActionType type : 4; 75 | } TSParseAction; 76 | 77 | typedef struct { 78 | uint16_t lex_state; 79 | uint16_t external_lex_state; 80 | } TSLexMode; 81 | 82 | typedef union { 83 | TSParseAction action; 84 | struct { 85 | uint8_t count; 86 | bool reusable : 1; 87 | } entry; 88 | } TSParseActionEntry; 89 | 90 | struct TSLanguage { 91 | uint32_t version; 92 | uint32_t symbol_count; 93 | uint32_t alias_count; 94 | uint32_t token_count; 95 | uint32_t external_token_count; 96 | const char **symbol_names; 97 | const TSSymbolMetadata *symbol_metadata; 98 | const uint16_t *parse_table; 99 | const TSParseActionEntry *parse_actions; 100 | const TSLexMode *lex_modes; 101 | const TSSymbol *alias_sequences; 102 | uint16_t max_alias_sequence_length; 103 | bool (*lex_fn)(TSLexer *, TSStateId); 104 | bool (*keyword_lex_fn)(TSLexer *, TSStateId); 105 | TSSymbol keyword_capture_token; 106 | struct { 107 | const bool *states; 108 | const TSSymbol *symbol_map; 109 | void *(*create)(void); 110 | void (*destroy)(void *); 111 | bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist); 112 | unsigned (*serialize)(void *, char *); 113 | void (*deserialize)(void *, const char *, unsigned); 114 | } external_scanner; 115 | uint32_t field_count; 116 | const TSFieldMapSlice *field_map_slices; 117 | const TSFieldMapEntry *field_map_entries; 118 | const char **field_names; 119 | uint32_t large_state_count; 120 | const uint16_t *small_parse_table; 121 | const uint32_t *small_parse_table_map; 122 | const TSSymbol *public_symbol_map; 123 | const uint16_t *alias_map; 124 | uint32_t state_count; 125 | }; 126 | 127 | /* 128 | * Lexer Macros 129 | */ 130 | 131 | #define START_LEXER() \ 132 | bool result = false; \ 133 | bool skip = false; \ 134 | bool eof = false; \ 135 | int32_t lookahead; \ 136 | goto start; \ 137 | next_state: \ 138 | lexer->advance(lexer, skip); \ 139 | start: \ 140 | skip = false; \ 141 | lookahead = lexer->lookahead; 142 | 143 | #define ADVANCE(state_value) \ 144 | { \ 145 | state = state_value; \ 146 | goto next_state; \ 147 | } 148 | 149 | #define SKIP(state_value) \ 150 | { \ 151 | skip = true; \ 152 | state = state_value; \ 153 | goto next_state; \ 154 | } 155 | 156 | #define ACCEPT_TOKEN(symbol_value) \ 157 | result = true; \ 158 | lexer->result_symbol = symbol_value; \ 159 | lexer->mark_end(lexer); 160 | 161 | #define END_STATE() return result; 162 | 163 | /* 164 | * Parse Table Macros 165 | */ 166 | 167 | #define SMALL_STATE(id) id - LARGE_STATE_COUNT 168 | 169 | #define STATE(id) id 170 | 171 | #define ACTIONS(id) id 172 | 173 | #define SHIFT(state_value) \ 174 | { \ 175 | { \ 176 | .params = { \ 177 | .shift = { \ 178 | .state = state_value \ 179 | } \ 180 | }, \ 181 | .type = TSParseActionTypeShift \ 182 | } \ 183 | } 184 | 185 | #define SHIFT_REPEAT(state_value) \ 186 | { \ 187 | { \ 188 | .params = { \ 189 | .shift = { \ 190 | .state = state_value, \ 191 | .repetition = true \ 192 | } \ 193 | }, \ 194 | .type = TSParseActionTypeShift \ 195 | } \ 196 | } 197 | 198 | #define RECOVER() \ 199 | { \ 200 | { .type = TSParseActionTypeRecover } \ 201 | } 202 | 203 | #define SHIFT_EXTRA() \ 204 | { \ 205 | { \ 206 | .params = { \ 207 | .shift = { \ 208 | .extra = true \ 209 | } \ 210 | }, \ 211 | .type = TSParseActionTypeShift \ 212 | } \ 213 | } 214 | 215 | #define REDUCE(symbol_val, child_count_val, ...) \ 216 | { \ 217 | { \ 218 | .params = { \ 219 | .reduce = { \ 220 | .symbol = symbol_val, \ 221 | .child_count = child_count_val, \ 222 | __VA_ARGS__ \ 223 | }, \ 224 | }, \ 225 | .type = TSParseActionTypeReduce \ 226 | } \ 227 | } 228 | 229 | #define ACCEPT_INPUT() \ 230 | { \ 231 | { .type = TSParseActionTypeAccept } \ 232 | } 233 | 234 | #ifdef __cplusplus 235 | } 236 | #endif 237 | 238 | #endif // TREE_SITTER_PARSER_H_ 239 | -------------------------------------------------------------------------------- /test/corpus/s_expressions.txt: -------------------------------------------------------------------------------- 1 | ================================================================================ 2 | atom 3 | ================================================================================ 4 | 5 | hello 6 | 7 | -------------------------------------------------------------------------------- 8 | 9 | (sexp 10 | (atom)) 11 | 12 | ================================================================================ 13 | empty 14 | ================================================================================ 15 | 16 | () 17 | 18 | -------------------------------------------------------------------------------- 19 | 20 | (sexp 21 | (list)) 22 | 23 | ================================================================================ 24 | ERROR 25 | ================================================================================ 26 | 27 | (ERROR ) what) 28 | 29 | -------------------------------------------------------------------------------- 30 | 31 | (sexp (list (atom)) (ERROR (atom))) 32 | 33 | ================================================================================ 34 | MISSING 35 | ================================================================================ 36 | 37 | (MISSING 38 | 39 | -------------------------------------------------------------------------------- 40 | 41 | (sexp (list (atom) (MISSING ")"))) 42 | 43 | ================================================================================ 44 | single line 45 | ================================================================================ 46 | 47 | (source_file) 48 | 49 | -------------------------------------------------------------------------------- 50 | 51 | (sexp 52 | (list 53 | (atom))) 54 | 55 | ================================================================================ 56 | multiple parts 57 | ================================================================================ 58 | 59 | (source file as s_expression) 60 | 61 | -------------------------------------------------------------------------------- 62 | 63 | (sexp 64 | (list 65 | (atom) 66 | (atom) 67 | (atom) 68 | (atom))) 69 | 70 | ================================================================================ 71 | nested s-expressions 72 | ================================================================================ 73 | 74 | (source (file (as) (s_expression))) 75 | 76 | -------------------------------------------------------------------------------- 77 | 78 | (sexp 79 | (list 80 | (atom) 81 | (list 82 | (atom) 83 | (list 84 | (atom)) 85 | (list 86 | (atom))))) 87 | 88 | ================================================================================ 89 | field-like atoms 90 | ================================================================================ 91 | 92 | (source file: as (s_expression)) 93 | 94 | -------------------------------------------------------------------------------- 95 | 96 | (sexp 97 | (list 98 | (atom) 99 | (atom) 100 | (atom) 101 | (list 102 | (atom)))) 103 | 104 | ================================================================================ 105 | real-life example 106 | ================================================================================ 107 | 108 | (source_file (module_name (atom (unquoted_atom))) (module_export (atom (unquoted_atom)) (integer)) (module_export (atom (unquoted_atom)) (integer)) (module_export (atom (unquoted_atom)) (integer)) (function_declaration (function_clause (atom (unquoted_atom)) (lambda_clause (pattern (variable)) (pattern (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (case (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))) (expression (variable)))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (tuple (expression (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))) (expression (variable)))))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (atom (unquoted_atom)))))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))))) (function_declaration (function_clause (atom (unquoted_atom)) (lambda_clause (pattern (variable)) (pattern (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (unquoted_atom))) (expression (lambda (lambda_clause (pattern (variable)) (pattern (variable)) (expression (case (expression (variable)) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (case (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (tuple (expression (term (atom (unquoted_atom)))) (expression (function_call (qualified_function_name (expression (term (atom (unquoted_atom)))) (atom (quoted_atom))) (expression (variable)) (expression (variable)))))))) (case_clause (pattern (term (atom (unquoted_atom)))) (expression (term (atom (unquoted_atom)))))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))) (case_clause (pattern (variable)) (expression (variable)))))))) (expression (term (atom (unquoted_atom)))) (expression (variable))))))) (function_declaration (function_clause (atom (unquoted_atom)) (lambda_clause (expression (term (list (expression (function_call (computed_function_name (expression (term (atom (unquoted_atom))))) (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list)))))))))))))) (expression (term (list (expression (function_call (computed_function_name (expression (term (atom (unquoted_atom))))) (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list (expression (term (integer))) (expression (term (list)))))))))))))) (expression (term (list))))))))))))) 109 | 110 | 111 | -------------------------------------------------------------------------------- 112 | 113 | (sexp 114 | (list 115 | (atom) 116 | (list 117 | (atom) 118 | (list 119 | (atom) 120 | (list 121 | (atom)))) 122 | (list 123 | (atom) 124 | (list 125 | (atom) 126 | (list 127 | (atom))) 128 | (list 129 | (atom))) 130 | (list 131 | (atom) 132 | (list 133 | (atom) 134 | (list 135 | (atom))) 136 | (list 137 | (atom))) 138 | (list 139 | (atom) 140 | (list 141 | (atom) 142 | (list 143 | (atom))) 144 | (list 145 | (atom))) 146 | (list 147 | (atom) 148 | (list 149 | (atom) 150 | (list 151 | (atom) 152 | (list 153 | (atom))) 154 | (list 155 | (atom) 156 | (list 157 | (atom) 158 | (list 159 | (atom))) 160 | (list 161 | (atom) 162 | (list 163 | (atom))) 164 | (list 165 | (atom) 166 | (list 167 | (atom) 168 | (list 169 | (atom) 170 | (list 171 | (atom) 172 | (list 173 | (atom) 174 | (list 175 | (atom) 176 | (list 177 | (atom))))) 178 | (list 179 | (atom) 180 | (list 181 | (atom)))) 182 | (list 183 | (atom) 184 | (list 185 | (atom) 186 | (list 187 | (atom) 188 | (list 189 | (atom) 190 | (list 191 | (atom))) 192 | (list 193 | (atom) 194 | (list 195 | (atom))) 196 | (list 197 | (atom) 198 | (list 199 | (atom) 200 | (list 201 | (atom) 202 | (list 203 | (atom))) 204 | (list 205 | (atom) 206 | (list 207 | (atom) 208 | (list 209 | (atom) 210 | (list 211 | (atom) 212 | (list 213 | (atom))))) 214 | (list 215 | (atom) 216 | (list 217 | (atom) 218 | (list 219 | (atom) 220 | (list 221 | (atom) 222 | (list 223 | (atom) 224 | (list 225 | (atom) 226 | (list 227 | (atom))))) 228 | (list 229 | (atom) 230 | (list 231 | (atom)))) 232 | (list 233 | (atom) 234 | (list 235 | (atom) 236 | (list 237 | (atom) 238 | (list 239 | (atom) 240 | (list 241 | (atom))) 242 | (list 243 | (atom) 244 | (list 245 | (atom))) 246 | (list 247 | (atom) 248 | (list 249 | (atom) 250 | (list 251 | (atom) 252 | (list 253 | (atom))) 254 | (list 255 | (atom) 256 | (list 257 | (atom) 258 | (list 259 | (atom) 260 | (list 261 | (atom) 262 | (list 263 | (atom))))) 264 | (list 265 | (atom) 266 | (list 267 | (atom) 268 | (list 269 | (atom) 270 | (list 271 | (atom) 272 | (list 273 | (atom) 274 | (list 275 | (atom) 276 | (list 277 | (atom))))) 278 | (list 279 | (atom) 280 | (list 281 | (atom)))) 282 | (list 283 | (atom) 284 | (list 285 | (atom) 286 | (list 287 | (atom) 288 | (list 289 | (atom) 290 | (list 291 | (atom))) 292 | (list 293 | (atom) 294 | (list 295 | (atom))) 296 | (list 297 | (atom) 298 | (list 299 | (atom) 300 | (list 301 | (atom) 302 | (list 303 | (atom))) 304 | (list 305 | (atom) 306 | (list 307 | (atom) 308 | (list 309 | (atom) 310 | (list 311 | (atom) 312 | (list 313 | (atom))))) 314 | (list 315 | (atom) 316 | (list 317 | (atom) 318 | (list 319 | (atom) 320 | (list 321 | (atom) 322 | (list 323 | (atom) 324 | (list 325 | (atom) 326 | (list 327 | (atom) 328 | (list 329 | (atom) 330 | (list 331 | (atom))))) 332 | (list 333 | (atom) 334 | (list 335 | (atom)))) 336 | (list 337 | (atom) 338 | (list 339 | (atom))) 340 | (list 341 | (atom) 342 | (list 343 | (atom) 344 | (list 345 | (atom) 346 | (list 347 | (atom) 348 | (list 349 | (atom) 350 | (list 351 | (atom) 352 | (list 353 | (atom))))) 354 | (list 355 | (atom) 356 | (list 357 | (atom)))) 358 | (list 359 | (atom) 360 | (list 361 | (atom) 362 | (list 363 | (atom) 364 | (list 365 | (atom) 366 | (list 367 | (atom) 368 | (list 369 | (atom) 370 | (list 371 | (atom))))) 372 | (list 373 | (atom) 374 | (list 375 | (atom)))) 376 | (list 377 | (atom) 378 | (list 379 | (atom))) 380 | (list 381 | (atom) 382 | (list 383 | (atom))))) 384 | (list 385 | (atom) 386 | (list 387 | (atom))))))) 388 | (list 389 | (atom) 390 | (list 391 | (atom) 392 | (list 393 | (atom) 394 | (list 395 | (atom) 396 | (list 397 | (atom))))) 398 | (list 399 | (atom) 400 | (list 401 | (atom) 402 | (list 403 | (atom) 404 | (list 405 | (atom) 406 | (list 407 | (atom) 408 | (list 409 | (atom) 410 | (list 411 | (atom))))) 412 | (list 413 | (atom) 414 | (list 415 | (atom) 416 | (list 417 | (atom) 418 | (list 419 | (atom) 420 | (list 421 | (atom) 422 | (list 423 | (atom) 424 | (list 425 | (atom))))) 426 | (list 427 | (atom) 428 | (list 429 | (atom)))) 430 | (list 431 | (atom) 432 | (list 433 | (atom) 434 | (list 435 | (atom) 436 | (list 437 | (atom) 438 | (list 439 | (atom) 440 | (list 441 | (atom) 442 | (list 443 | (atom))))) 444 | (list 445 | (atom) 446 | (list 447 | (atom)))) 448 | (list 449 | (atom) 450 | (list 451 | (atom))) 452 | (list 453 | (atom) 454 | (list 455 | (atom))))) 456 | (list 457 | (atom) 458 | (list 459 | (atom))))))))) 460 | (list 461 | (atom) 462 | (list 463 | (atom) 464 | (list 465 | (atom) 466 | (list 467 | (atom) 468 | (list 469 | (atom))))) 470 | (list 471 | (atom) 472 | (list 473 | (atom) 474 | (list 475 | (atom) 476 | (list 477 | (atom))))))))) 478 | (list 479 | (atom) 480 | (list 481 | (atom) 482 | (list 483 | (atom))) 484 | (list 485 | (atom) 486 | (list 487 | (atom))))))))) 488 | (list 489 | (atom) 490 | (list 491 | (atom) 492 | (list 493 | (atom) 494 | (list 495 | (atom))))) 496 | (list 497 | (atom) 498 | (list 499 | (atom)))))) 500 | (list 501 | (atom) 502 | (list 503 | (atom) 504 | (list 505 | (atom))) 506 | (list 507 | (atom) 508 | (list 509 | (atom))))))))) 510 | (list 511 | (atom) 512 | (list 513 | (atom) 514 | (list 515 | (atom) 516 | (list 517 | (atom))))) 518 | (list 519 | (atom) 520 | (list 521 | (atom)))))) 522 | (list 523 | (atom) 524 | (list 525 | (atom) 526 | (list 527 | (atom))) 528 | (list 529 | (atom) 530 | (list 531 | (atom))))))))) 532 | (list 533 | (atom) 534 | (list 535 | (atom) 536 | (list 537 | (atom) 538 | (list 539 | (atom))))) 540 | (list 541 | (atom) 542 | (list 543 | (atom)))))))) 544 | (list 545 | (atom) 546 | (list 547 | (atom) 548 | (list 549 | (atom) 550 | (list 551 | (atom))) 552 | (list 553 | (atom) 554 | (list 555 | (atom) 556 | (list 557 | (atom))) 558 | (list 559 | (atom) 560 | (list 561 | (atom))) 562 | (list 563 | (atom) 564 | (list 565 | (atom) 566 | (list 567 | (atom) 568 | (list 569 | (atom) 570 | (list 571 | (atom) 572 | (list 573 | (atom) 574 | (list 575 | (atom))))) 576 | (list 577 | (atom) 578 | (list 579 | (atom)))) 580 | (list 581 | (atom) 582 | (list 583 | (atom) 584 | (list 585 | (atom) 586 | (list 587 | (atom) 588 | (list 589 | (atom))) 590 | (list 591 | (atom) 592 | (list 593 | (atom))) 594 | (list 595 | (atom) 596 | (list 597 | (atom) 598 | (list 599 | (atom) 600 | (list 601 | (atom))) 602 | (list 603 | (atom) 604 | (list 605 | (atom) 606 | (list 607 | (atom) 608 | (list 609 | (atom) 610 | (list 611 | (atom))))) 612 | (list 613 | (atom) 614 | (list 615 | (atom) 616 | (list 617 | (atom) 618 | (list 619 | (atom) 620 | (list 621 | (atom) 622 | (list 623 | (atom) 624 | (list 625 | (atom))))) 626 | (list 627 | (atom) 628 | (list 629 | (atom)))) 630 | (list 631 | (atom) 632 | (list 633 | (atom) 634 | (list 635 | (atom) 636 | (list 637 | (atom) 638 | (list 639 | (atom))) 640 | (list 641 | (atom) 642 | (list 643 | (atom))) 644 | (list 645 | (atom) 646 | (list 647 | (atom) 648 | (list 649 | (atom) 650 | (list 651 | (atom))) 652 | (list 653 | (atom) 654 | (list 655 | (atom) 656 | (list 657 | (atom) 658 | (list 659 | (atom) 660 | (list 661 | (atom))))) 662 | (list 663 | (atom) 664 | (list 665 | (atom) 666 | (list 667 | (atom) 668 | (list 669 | (atom) 670 | (list 671 | (atom) 672 | (list 673 | (atom) 674 | (list 675 | (atom) 676 | (list 677 | (atom) 678 | (list 679 | (atom))))) 680 | (list 681 | (atom) 682 | (list 683 | (atom)))) 684 | (list 685 | (atom) 686 | (list 687 | (atom))) 688 | (list 689 | (atom) 690 | (list 691 | (atom) 692 | (list 693 | (atom) 694 | (list 695 | (atom) 696 | (list 697 | (atom) 698 | (list 699 | (atom) 700 | (list 701 | (atom))))) 702 | (list 703 | (atom) 704 | (list 705 | (atom)))) 706 | (list 707 | (atom) 708 | (list 709 | (atom))) 710 | (list 711 | (atom) 712 | (list 713 | (atom))))))) 714 | (list 715 | (atom) 716 | (list 717 | (atom) 718 | (list 719 | (atom) 720 | (list 721 | (atom) 722 | (list 723 | (atom))))) 724 | (list 725 | (atom) 726 | (list 727 | (atom) 728 | (list 729 | (atom) 730 | (list 731 | (atom) 732 | (list 733 | (atom) 734 | (list 735 | (atom) 736 | (list 737 | (atom))))) 738 | (list 739 | (atom) 740 | (list 741 | (atom) 742 | (list 743 | (atom) 744 | (list 745 | (atom) 746 | (list 747 | (atom) 748 | (list 749 | (atom) 750 | (list 751 | (atom))))) 752 | (list 753 | (atom) 754 | (list 755 | (atom)))) 756 | (list 757 | (atom) 758 | (list 759 | (atom))) 760 | (list 761 | (atom) 762 | (list 763 | (atom))))))))) 764 | (list 765 | (atom) 766 | (list 767 | (atom) 768 | (list 769 | (atom) 770 | (list 771 | (atom) 772 | (list 773 | (atom))))) 774 | (list 775 | (atom) 776 | (list 777 | (atom) 778 | (list 779 | (atom) 780 | (list 781 | (atom))))))))) 782 | (list 783 | (atom) 784 | (list 785 | (atom) 786 | (list 787 | (atom))) 788 | (list 789 | (atom) 790 | (list 791 | (atom))))))))) 792 | (list 793 | (atom) 794 | (list 795 | (atom) 796 | (list 797 | (atom) 798 | (list 799 | (atom))))) 800 | (list 801 | (atom) 802 | (list 803 | (atom)))))) 804 | (list 805 | (atom) 806 | (list 807 | (atom) 808 | (list 809 | (atom))) 810 | (list 811 | (atom) 812 | (list 813 | (atom))))))))) 814 | (list 815 | (atom) 816 | (list 817 | (atom) 818 | (list 819 | (atom) 820 | (list 821 | (atom))))) 822 | (list 823 | (atom) 824 | (list 825 | (atom)))))))) 826 | (list 827 | (atom) 828 | (list 829 | (atom) 830 | (list 831 | (atom) 832 | (list 833 | (atom))) 834 | (list 835 | (atom) 836 | (list 837 | (atom) 838 | (list 839 | (atom) 840 | (list 841 | (atom) 842 | (list 843 | (atom) 844 | (list 845 | (atom) 846 | (list 847 | (atom) 848 | (list 849 | (atom) 850 | (list 851 | (atom) 852 | (list 853 | (atom) 854 | (list 855 | (atom)))))) 856 | (list 857 | (atom) 858 | (list 859 | (atom) 860 | (list 861 | (atom)))) 862 | (list 863 | (atom) 864 | (list 865 | (atom) 866 | (list 867 | (atom) 868 | (list 869 | (atom) 870 | (list 871 | (atom) 872 | (list 873 | (atom)))) 874 | (list 875 | (atom) 876 | (list 877 | (atom) 878 | (list 879 | (atom) 880 | (list 881 | (atom) 882 | (list 883 | (atom) 884 | (list 885 | (atom)))) 886 | (list 887 | (atom) 888 | (list 889 | (atom) 890 | (list 891 | (atom) 892 | (list 893 | (atom) 894 | (list 895 | (atom) 896 | (list 897 | (atom)))) 898 | (list 899 | (atom) 900 | (list 901 | (atom) 902 | (list 903 | (atom))))))))))))))) 904 | (list 905 | (atom) 906 | (list 907 | (atom) 908 | (list 909 | (atom) 910 | (list 911 | (atom) 912 | (list 913 | (atom) 914 | (list 915 | (atom) 916 | (list 917 | (atom) 918 | (list 919 | (atom) 920 | (list 921 | (atom) 922 | (list 923 | (atom)))))) 924 | (list 925 | (atom) 926 | (list 927 | (atom) 928 | (list 929 | (atom)))) 930 | (list 931 | (atom) 932 | (list 933 | (atom) 934 | (list 935 | (atom) 936 | (list 937 | (atom) 938 | (list 939 | (atom) 940 | (list 941 | (atom)))) 942 | (list 943 | (atom) 944 | (list 945 | (atom) 946 | (list 947 | (atom) 948 | (list 949 | (atom) 950 | (list 951 | (atom) 952 | (list 953 | (atom)))) 954 | (list 955 | (atom) 956 | (list 957 | (atom) 958 | (list 959 | (atom) 960 | (list 961 | (atom) 962 | (list 963 | (atom) 964 | (list 965 | (atom)))) 966 | (list 967 | (atom) 968 | (list 969 | (atom) 970 | (list 971 | (atom))))))))))))))) 972 | (list 973 | (atom) 974 | (list 975 | (atom) 976 | (list 977 | (atom))))))))))))))) 978 | -------------------------------------------------------------------------------- /tree-sitter-sexp.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AbstractMachinesLab/tree-sitter-sexp/b46b9f784b3e31bcbc0632f3294f1af6ba049241/tree-sitter-sexp.wasm -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | nan@^2.14.1: 6 | version "2.14.2" 7 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" 8 | integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== 9 | 10 | prettier@^2.2.1: 11 | version "2.2.1" 12 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" 13 | integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== 14 | 15 | tree-sitter-cli@^0.17.1: 16 | version "0.17.3" 17 | resolved "https://registry.yarnpkg.com/tree-sitter-cli/-/tree-sitter-cli-0.17.3.tgz#ea03ee93216b0cf3187503d8a4dbff15df4dfc0a" 18 | integrity sha512-AsQhjwRwWK5wtymwVc2H5E8/Q7yzMebSj7CQyeSg50k4h7m8HHwao1i/eKlh8aGTJ3IWbGjSwBAUZTSbzcSW6Q== 19 | --------------------------------------------------------------------------------