@backbencher/brain 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/EMBEDDINGS.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +415 -2
  5. package/bin/bb +13 -0
  6. package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
  7. package/dist/brain-index-health-Q5APTJQL.js +17 -0
  8. package/dist/brain-relationship-enrichment-MYR2AM4F.js +558 -0
  9. package/dist/brain.sql-EIM4WS4D.js +29 -0
  10. package/dist/chunk-22V37YTK.js +1758 -0
  11. package/dist/chunk-2BSKD7O3.js +40 -0
  12. package/dist/chunk-2DE27DVC.js +1314 -0
  13. package/dist/chunk-2RRBMNBQ.js +322 -0
  14. package/dist/chunk-2WXYNLBA.js +29 -0
  15. package/dist/chunk-3CTFIJJB.js +17 -0
  16. package/dist/chunk-3ZTOHHSW.js +2104 -0
  17. package/dist/chunk-4H22TLOT.js +543 -0
  18. package/dist/chunk-5BVAH26D.js +340 -0
  19. package/dist/chunk-62DHLYW6.js +3427 -0
  20. package/dist/chunk-7AN7U5IZ.js +371 -0
  21. package/dist/chunk-7DRPNVIN.js +782 -0
  22. package/dist/chunk-7MBYT777.js +174 -0
  23. package/dist/chunk-AHDWGM7Q.js +236 -0
  24. package/dist/chunk-B5GEAAYF.js +818 -0
  25. package/dist/chunk-BEIZZ73B.js +1479 -0
  26. package/dist/chunk-BQ3OVQ3P.js +125 -0
  27. package/dist/chunk-D2Q4Y47A.js +53 -0
  28. package/dist/chunk-DIYAGQJL.js +34 -0
  29. package/dist/chunk-DWKXZ6IF.js +336 -0
  30. package/dist/chunk-DYM4FQEE.js +90 -0
  31. package/dist/chunk-ENW4BTBA.js +930 -0
  32. package/dist/chunk-EWMWK7WN.js +75 -0
  33. package/dist/chunk-EY5ZZUUA.js +626 -0
  34. package/dist/chunk-GBI7V7KY.js +69 -0
  35. package/dist/chunk-GEFFO6O2.js +152 -0
  36. package/dist/chunk-HJEWO5EV.js +247 -0
  37. package/dist/chunk-HQSPJDHI.js +613 -0
  38. package/dist/chunk-KAET47ZL.js +125 -0
  39. package/dist/chunk-KCDECRJY.js +440 -0
  40. package/dist/chunk-L5TDYKYK.js +76 -0
  41. package/dist/chunk-MLKGABMK.js +9 -0
  42. package/dist/chunk-NO3U3FJQ.js +201 -0
  43. package/dist/chunk-OWISBAOF.js +61 -0
  44. package/dist/chunk-QKTRECYS.js +1119 -0
  45. package/dist/chunk-QLK6ED4Q.js +235 -0
  46. package/dist/chunk-R2GW4F6R.js +19 -0
  47. package/dist/chunk-RCMTFSEF.js +87 -0
  48. package/dist/chunk-RM3PY6TG.js +376 -0
  49. package/dist/chunk-ROMM6KMC.js +433 -0
  50. package/dist/chunk-SGGCSHAX.js +12050 -0
  51. package/dist/chunk-SK6YVHFZ.js +211 -0
  52. package/dist/chunk-SM7RFQRO.js +214 -0
  53. package/dist/chunk-UGR4QIGS.js +67 -0
  54. package/dist/chunk-UQNQZXHY.js +711 -0
  55. package/dist/chunk-UUNHHX4M.js +13 -0
  56. package/dist/chunk-VL52PL2T.js +71 -0
  57. package/dist/chunk-WIG36E67.js +196 -0
  58. package/dist/chunk-XHK3WWGB.js +7436 -0
  59. package/dist/chunk-XTQM2IP3.js +2863 -0
  60. package/dist/chunk-ZE2LG76D.js +1296 -0
  61. package/dist/chunk-ZETTGPAW.js +6950 -0
  62. package/dist/cli/index.js +37 -0
  63. package/dist/config-HZAAYDP3.js +10 -0
  64. package/dist/content-search-7XIP555Q.js +593 -0
  65. package/dist/database-76RP44JG.js +9 -0
  66. package/dist/doctor-ANGETYMN.js +395 -0
  67. package/dist/edit-engine-CG72LDZD.js +51 -0
  68. package/dist/engine-BKEOGN7N.js +11 -0
  69. package/dist/engine-VIW6NSKO.js +18 -0
  70. package/dist/fingerprint-OBLIMZLP.js +33 -0
  71. package/dist/framework-intelligence-3LORTPOX.js +860 -0
  72. package/dist/freshness-3K6VU5OT.js +174 -0
  73. package/dist/graph-engine-HBSQNPTB.js +21 -0
  74. package/dist/graph_request-Q6NKB6N2.js +350 -0
  75. package/dist/impact_request-LYP672WE.js +68 -0
  76. package/dist/index-space-IUUN5WYV.js +15 -0
  77. package/dist/index-status-7OVGYSGW.js +34 -0
  78. package/dist/index.js +159 -0
  79. package/dist/instance-FO6QZRLH.js +19 -0
  80. package/dist/language-detection-DFCAU5DZ.js +11 -0
  81. package/dist/lsp/server.js +4301 -0
  82. package/dist/mcp/server.js +132 -0
  83. package/dist/onboard-DIQZV2NW.js +161 -0
  84. package/dist/override-companion-pass-XR7MHTP7.js +117 -0
  85. package/dist/parallel-indexer-FK2XKZXY.js +88 -0
  86. package/dist/pool-worker.js +1153 -0
  87. package/dist/project-health-6XPENVAA.js +94 -0
  88. package/dist/project-index-5SDPHITE.js +57 -0
  89. package/dist/project-registry-ZJ3DVUGO.js +355 -0
  90. package/dist/real-bash-analyzer-EJAU5LW5.js +2201 -0
  91. package/dist/real-c-analyzer-HBD3FNNH.js +5942 -0
  92. package/dist/real-clean-analyzer-4EEZLPV5.js +3470 -0
  93. package/dist/real-clojure-analyzer-Q55EBOO2.js +2818 -0
  94. package/dist/real-cpp-analyzer-IVVOD25R.js +4101 -0
  95. package/dist/real-csharp-analyzer-ZBNLNJZJ.js +3298 -0
  96. package/dist/real-css-analyzer-6XRQLUN7.js +15 -0
  97. package/dist/real-dart-analyzer-OLR72EFW.js +3944 -0
  98. package/dist/real-elixir-analyzer-MQWGAH2I.js +2192 -0
  99. package/dist/real-erlang-analyzer-7BVPQEHO.js +1731 -0
  100. package/dist/real-fsharp-analyzer-C2UPFNOA.js +2390 -0
  101. package/dist/real-go-analyzer-UKGI43YS.js +4126 -0
  102. package/dist/real-graphql-analyzer-VE2EEFII.js +1442 -0
  103. package/dist/real-groovy-analyzer-W26VACFW.js +2285 -0
  104. package/dist/real-haskell-analyzer-5CVVAJRX.js +2533 -0
  105. package/dist/real-hcl-analyzer-5ZT4U43N.js +725 -0
  106. package/dist/real-html-analyzer-JWNX3C6I.js +1759 -0
  107. package/dist/real-java-analyzer-GU42VBGQ.js +4677 -0
  108. package/dist/real-javascript-analyzer-QA4QOJ6W.js +14 -0
  109. package/dist/real-json-analyzer-MPA6PRXL.js +1640 -0
  110. package/dist/real-julia-analyzer-22CWYQMN.js +2085 -0
  111. package/dist/real-kotlin-analyzer-QDZJLXXU.js +3956 -0
  112. package/dist/real-lua-analyzer-G7NHLYKS.js +1957 -0
  113. package/dist/real-makefile-analyzer-OCY3GT5N.js +920 -0
  114. package/dist/real-markdown-analyzer-TEJK2JXJ.js +1215 -0
  115. package/dist/real-matlab-analyzer-Q5SWLN7Z.js +480 -0
  116. package/dist/real-nim-analyzer-YLXSK563.js +3603 -0
  117. package/dist/real-objective-c-analyzer-D23ACC2R.js +1518 -0
  118. package/dist/real-perl-analyzer-WWTRHYDT.js +1865 -0
  119. package/dist/real-php-analyzer-JNKJHTCL.js +9368 -0
  120. package/dist/real-powershell-analyzer-XRSNQERV.js +2915 -0
  121. package/dist/real-protobuf-analyzer-3OKUCZ7T.js +867 -0
  122. package/dist/real-python-analyzer-VXAFWI72.js +4880 -0
  123. package/dist/real-r-analyzer-ZGAIDVI4.js +2596 -0
  124. package/dist/real-ruby-analyzer-X2KTLVBH.js +2429 -0
  125. package/dist/real-rust-analyzer-OFFHPL2A.js +3359 -0
  126. package/dist/real-scala-analyzer-TSTW27J6.js +3293 -0
  127. package/dist/real-scss-analyzer-AVWYPSOQ.js +1515 -0
  128. package/dist/real-solidity-analyzer-UCI2KWUB.js +2608 -0
  129. package/dist/real-sql-analyzer-F77ZMQXR.js +3840 -0
  130. package/dist/real-svelte-analyzer-SF7NRUO5.js +2532 -0
  131. package/dist/real-swift-analyzer-MN5QT3QN.js +2311 -0
  132. package/dist/real-toml-analyzer-66L7BDCQ.js +929 -0
  133. package/dist/real-typescript-analyzer-6KEMVDWQ.js +14 -0
  134. package/dist/real-vb-analyzer-VICVPOP7.js +3145 -0
  135. package/dist/real-vba-analyzer-HXLTTHKM.js +466 -0
  136. package/dist/real-vue-analyzer-QXR56CFV.js +2680 -0
  137. package/dist/real-xml-analyzer-YL465ZJW.js +2405 -0
  138. package/dist/real-yaml-analyzer-SUBCBNSI.js +3528 -0
  139. package/dist/real-zig-analyzer-HIQLZMGY.js +2430 -0
  140. package/dist/regex-search-NJKHMZNO.js +239 -0
  141. package/dist/rules-ACHPB7QU.js +152 -0
  142. package/dist/scoped-path-MJYWJZQX.js +11 -0
  143. package/dist/setup-show-NT5ZHYNE.js +15 -0
  144. package/dist/setup-wizard-G5YYR5T6.js +24 -0
  145. package/dist/symbol-search-GZJIM2J2.js +16 -0
  146. package/dist/taint-KXUHHPIE.js +202 -0
  147. package/dist/taint-analyzer-N7YLZU3N.js +163 -0
  148. package/dist/tool-handlers-OJDC35DI.js +72 -0
  149. package/dist/tool-registry-BPEJNSZG.js +17 -0
  150. package/dist/tool-validation-Q57YMMBX.js +32 -0
  151. package/dist/type-inference-QMT2RMLV.js +13 -0
  152. package/dist/vector-binary-LMY4QGAN.js +19 -0
  153. package/dist/version-ABP2TUL2.js +9 -0
  154. package/dist/wasm-NMWO3WXY.js +16 -0
  155. package/docs/EMBEDDINGS.md +132 -0
  156. package/docs/README.md +178 -0
  157. package/docs/data/m10-baseline.json +602 -0
  158. package/docs/data/m10-benchmark-baseline.json +57 -0
  159. package/docs/data/m10-benchmark-last-run.json +127 -0
  160. package/docs/data/m10-final-audit.json +215 -0
  161. package/docs/data/m12-final-audit.json +138 -0
  162. package/docs/data/m12-surface-matrix.json +50 -0
  163. package/docs/data/public-tools.json +1902 -0
  164. package/docs/indexing/DEAD-ASSETS.md +88 -0
  165. package/docs/indexing/INDEXER-REVIEW.md +634 -0
  166. package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
  167. package/docs/indexing/README.md +427 -0
  168. package/docs/indexing/discovery-matrix.md +41 -0
  169. package/docs/indexing/embeddings.md +325 -0
  170. package/docs/indexing/environment-variables.md +77 -0
  171. package/docs/indexing/performance.md +323 -0
  172. package/docs/indexing/resume.md +345 -0
  173. package/docs/indexing/troubleshooting.md +391 -0
  174. package/docs/man/bb.1 +190 -0
  175. package/docs/tools/bb_analyze.md +147 -0
  176. package/docs/tools/bb_annotate.md +110 -0
  177. package/docs/tools/bb_annotations.md +106 -0
  178. package/docs/tools/bb_ask.md +101 -0
  179. package/docs/tools/bb_cross_language.md +103 -0
  180. package/docs/tools/bb_doc.md +169 -0
  181. package/docs/tools/bb_edit.md +185 -0
  182. package/docs/tools/bb_graph.md +169 -0
  183. package/docs/tools/bb_health.md +156 -0
  184. package/docs/tools/bb_impact.md +117 -0
  185. package/docs/tools/bb_index.md +108 -0
  186. package/docs/tools/bb_migrate.md +135 -0
  187. package/docs/tools/bb_patterns.md +140 -0
  188. package/docs/tools/bb_search.md +150 -0
  189. package/docs/tools/bb_security.md +100 -0
  190. package/docs/tools/bb_visualize.md +184 -0
  191. package/grammars/README.md +57 -0
  192. package/grammars/THIRD-PARTY-NOTICES.md +50 -0
  193. package/grammars/tree-sitter-c/LICENSE +21 -0
  194. package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
  195. package/grammars/tree-sitter-cpp/LICENSE +21 -0
  196. package/grammars/tree-sitter-csharp/LICENSE +21 -0
  197. package/grammars/tree-sitter-css/LICENSE +21 -0
  198. package/grammars/tree-sitter-css/README.md +21 -0
  199. package/grammars/tree-sitter-dart/LICENSE +20 -0
  200. package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
  201. package/grammars/tree-sitter-dart-upstream/README.md +18 -0
  202. package/grammars/tree-sitter-elixir/LICENSE +176 -0
  203. package/grammars/tree-sitter-elixir/README.md +11 -0
  204. package/grammars/tree-sitter-fsharp/LICENSE +21 -0
  205. package/grammars/tree-sitter-fsharp/README.md +45 -0
  206. package/grammars/tree-sitter-graphql/LICENSE +21 -0
  207. package/grammars/tree-sitter-graphql/README.md +106 -0
  208. package/grammars/tree-sitter-groovy/LICENSE +21 -0
  209. package/grammars/tree-sitter-groovy/README.md +4 -0
  210. package/grammars/tree-sitter-haskell/LICENSE +21 -0
  211. package/grammars/tree-sitter-haskell/README.md +394 -0
  212. package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
  213. package/grammars/tree-sitter-hcl/LICENSE +201 -0
  214. package/grammars/tree-sitter-hcl/README.md +39 -0
  215. package/grammars/tree-sitter-html/LICENSE +21 -0
  216. package/grammars/tree-sitter-html/README.md +21 -0
  217. package/grammars/tree-sitter-julia/LICENSE +21 -0
  218. package/grammars/tree-sitter-julia/README.md +24 -0
  219. package/grammars/tree-sitter-kotlin/LICENSE +9 -0
  220. package/grammars/tree-sitter-lua/LICENSE.md +21 -0
  221. package/grammars/tree-sitter-lua/README.md +29 -0
  222. package/grammars/tree-sitter-make/LICENSE +21 -0
  223. package/grammars/tree-sitter-matlab/LICENSE +19 -0
  224. package/grammars/tree-sitter-matlab/README.md +99 -0
  225. package/grammars/tree-sitter-nim/LICENSE +373 -0
  226. package/grammars/tree-sitter-nim/README.md +46 -0
  227. package/grammars/tree-sitter-objc/LICENSE +21 -0
  228. package/grammars/tree-sitter-objc/README.md +20 -0
  229. package/grammars/tree-sitter-perl/LICENSE +7 -0
  230. package/grammars/tree-sitter-perl/README.md +100 -0
  231. package/grammars/tree-sitter-powershell/LICENSE +21 -0
  232. package/grammars/tree-sitter-powershell/README.md +7 -0
  233. package/grammars/tree-sitter-proto/LICENSE +21 -0
  234. package/grammars/tree-sitter-proto/README.md +105 -0
  235. package/grammars/tree-sitter-r/LICENSE +9 -0
  236. package/grammars/tree-sitter-r/README.md +66 -0
  237. package/grammars/tree-sitter-ruby/LICENSE +22 -0
  238. package/grammars/tree-sitter-scss/LICENSE +21 -0
  239. package/grammars/tree-sitter-scss/README.md +17 -0
  240. package/grammars/tree-sitter-solidity/LICENSE +7 -0
  241. package/grammars/tree-sitter-sql/LICENSE +21 -0
  242. package/grammars/tree-sitter-typescript/LICENSE +21 -0
  243. package/grammars/tree-sitter-vba/LICENSE +21 -0
  244. package/grammars/tree-sitter-vba/README.md +738 -0
  245. package/grammars/tree-sitter-vbnet/LICENSE +21 -0
  246. package/grammars/tree-sitter-vbnet/README.md +322 -0
  247. package/grammars/tree-sitter-xml/LICENSE +19 -0
  248. package/grammars/tree-sitter-yaml/LICENSE +20 -0
  249. package/grammars/tree-sitter-yaml/README.md +21 -0
  250. package/package.json +184 -4
  251. package/wasm/dart.wasm +0 -0
  252. package/wasm/tree-sitter-bash.wasm +0 -0
  253. package/wasm/tree-sitter-c.wasm +0 -0
  254. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  255. package/wasm/tree-sitter-clean.wasm +0 -0
  256. package/wasm/tree-sitter-clojure.wasm +0 -0
  257. package/wasm/tree-sitter-core_schema.wasm +0 -0
  258. package/wasm/tree-sitter-cpp.wasm +0 -0
  259. package/wasm/tree-sitter-css.wasm +0 -0
  260. package/wasm/tree-sitter-dart.wasm +0 -0
  261. package/wasm/tree-sitter-elisp.wasm +0 -0
  262. package/wasm/tree-sitter-elixir.wasm +0 -0
  263. package/wasm/tree-sitter-elm.wasm +0 -0
  264. package/wasm/tree-sitter-embedded_template.wasm +0 -0
  265. package/wasm/tree-sitter-erlang.wasm +0 -0
  266. package/wasm/tree-sitter-fsharp.wasm +0 -0
  267. package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
  268. package/wasm/tree-sitter-go.wasm +0 -0
  269. package/wasm/tree-sitter-graphql.wasm +0 -0
  270. package/wasm/tree-sitter-groovy.wasm +0 -0
  271. package/wasm/tree-sitter-haskell.wasm +0 -0
  272. package/wasm/tree-sitter-hcl.wasm +0 -0
  273. package/wasm/tree-sitter-html.wasm +0 -0
  274. package/wasm/tree-sitter-java.wasm +0 -0
  275. package/wasm/tree-sitter-javascript.wasm +0 -0
  276. package/wasm/tree-sitter-json.wasm +0 -0
  277. package/wasm/tree-sitter-json_schema.wasm +0 -0
  278. package/wasm/tree-sitter-julia.wasm +0 -0
  279. package/wasm/tree-sitter-kotlin.wasm +0 -0
  280. package/wasm/tree-sitter-lua.wasm +0 -0
  281. package/wasm/tree-sitter-make.wasm +0 -0
  282. package/wasm/tree-sitter-markdown.wasm +0 -0
  283. package/wasm/tree-sitter-markdown_inline.wasm +0 -0
  284. package/wasm/tree-sitter-matlab.wasm +0 -0
  285. package/wasm/tree-sitter-nim.wasm +0 -0
  286. package/wasm/tree-sitter-objc.wasm +0 -0
  287. package/wasm/tree-sitter-ocaml.wasm +0 -0
  288. package/wasm/tree-sitter-perl.wasm +0 -0
  289. package/wasm/tree-sitter-php.wasm +0 -0
  290. package/wasm/tree-sitter-php_only.wasm +0 -0
  291. package/wasm/tree-sitter-powershell.wasm +0 -0
  292. package/wasm/tree-sitter-protobuf.wasm +0 -0
  293. package/wasm/tree-sitter-python.wasm +0 -0
  294. package/wasm/tree-sitter-ql.wasm +0 -0
  295. package/wasm/tree-sitter-r.wasm +0 -0
  296. package/wasm/tree-sitter-rescript.wasm +0 -0
  297. package/wasm/tree-sitter-ruby.wasm +0 -0
  298. package/wasm/tree-sitter-rust.wasm +0 -0
  299. package/wasm/tree-sitter-scala.wasm +0 -0
  300. package/wasm/tree-sitter-scss.wasm +0 -0
  301. package/wasm/tree-sitter-solidity.wasm +0 -0
  302. package/wasm/tree-sitter-sql.wasm +0 -0
  303. package/wasm/tree-sitter-svelte.wasm +0 -0
  304. package/wasm/tree-sitter-swift.wasm +0 -0
  305. package/wasm/tree-sitter-systemrdl.wasm +0 -0
  306. package/wasm/tree-sitter-terraform.wasm +0 -0
  307. package/wasm/tree-sitter-tlaplus.wasm +0 -0
  308. package/wasm/tree-sitter-toml.wasm +0 -0
  309. package/wasm/tree-sitter-tsx.wasm +0 -0
  310. package/wasm/tree-sitter-typescript.wasm +0 -0
  311. package/wasm/tree-sitter-vba.wasm +0 -0
  312. package/wasm/tree-sitter-vbnet.wasm +0 -0
  313. package/wasm/tree-sitter-vue.wasm +0 -0
  314. package/wasm/tree-sitter-xml.wasm +0 -0
  315. package/wasm/tree-sitter-yaml.wasm +0 -0
  316. package/wasm/tree-sitter-zig.wasm +0 -0
  317. package/wasm/tree-sitter.wasm +0 -0
  318. package/wasm/tsx.wasm +0 -0
  319. package/wasm/typescript.wasm +0 -0
@@ -0,0 +1,738 @@
1
+ # tree-sitter-vba
2
+
3
+ [![npm version](https://img.shields.io/npm/v/tree-sitter-vba.svg)](https://www.npmjs.com/package/tree-sitter-vba)
4
+ [![npm downloads](https://img.shields.io/npm/dm/tree-sitter-vba.svg)](https://www.npmjs.com/package/tree-sitter-vba)
5
+ [![CI](https://github.com/harumiWeb/tree-sitter-vba/actions/workflows/ci.yml/badge.svg)](https://github.com/harumiWeb/tree-sitter-vba/actions/workflows/ci.yml)
6
+
7
+ Tree-sitter grammars for Visual Basic for Applications (VBA) and Visual Basic 6
8
+ (VB6), targeting exported Excel/VBA source files such as `.bas`, `.cls`, and
9
+ `.frm`, and VB6 project sources including `.frm` forms and `.ctl` user
10
+ controls. Two parsers, `vba` and `vb6`, are generated from one shared grammar
11
+ core.
12
+
13
+ [Try tree-sitter-vba online](https://harumiweb.github.io/tree-sitter-vba/)
14
+
15
+ The playground runs the `vba` parser through WebAssembly entirely in your
16
+ browser. Use it to test parser compatibility, inspect synchronized concrete
17
+ syntax trees, and see the official `highlights.scm` query in action; source
18
+ code is not uploaded or sent to a parsing service.
19
+
20
+ This grammar is designed as a parsing foundation for editor and tooling use
21
+ cases, including syntax highlighting, folding, tags, outline extraction, symbol
22
+ inspection, linting, formatting, and future LSP integrations.
23
+
24
+ ## Why another VBA grammar?
25
+
26
+ Several tree-sitter grammars exist for Visual Basic-family languages, but VBA has its own syntax and practical edge cases, especially in code exported from the VBE.
27
+
28
+ This project focuses on practical Excel/VBA source compatibility:
29
+
30
+ - `.bas`, `.cls`, and `.frm` files exported from the VBE
31
+ - real-world VBA fixtures
32
+ - UserForm metadata
33
+ - conditional compilation
34
+ - error handling
35
+ - Excel-style member access and procedure calls
36
+ - editor queries for highlights, folds, and tags
37
+ - permissive MIT licensing
38
+
39
+ VB6 shares its statement grammar with VBA, so the `vb6` parser reuses all of
40
+ the above and adds what is VB6's own: the `.frm`/`.ctl` form header and `.cls`
41
+ class header as the VB6 IDE writes them, and the constructs that predate VBA.
42
+
43
+ ## Status
44
+
45
+ This is a `v0.x` public release.
46
+
47
+ The grammar is already usable for syntax-aware tooling such as highlighting,
48
+ folding, tags, outline extraction, and initial symbol analysis. The current test
49
+ suite covers 261 focused VBA corpus cases, 45 VB6 corpus cases, generated
50
+ `Select Case` stress coverage through 500 clauses, and 481 checked-in VBA
51
+ example files without `ERROR` or `MISSING` recovery nodes. The `vb6` parser is
52
+ additionally measured against 1,436 real VB6 source files from 71 public
53
+ projects; see [Testing](#testing) for the numbers.
54
+
55
+ It is not yet a complete VBA grammar. Node names and tree shapes may still change before `v1.0.0`.
56
+
57
+ ## Two parsers from one grammar
58
+
59
+ The statement grammar is written once, in `common/define-grammar.js`, as a
60
+ function of the dialect. Each dialect directory holds a one-line entry point,
61
+ its generated parser, and its corpus tests:
62
+
63
+ ```text
64
+ common/define-grammar.js the whole grammar: defineGrammar("vba" | "vb6")
65
+ vba/grammar.js module.exports = require("../common/define-grammar")("vba")
66
+ vba/src/ generated vba parser; node-types.json is tracked, parser.c is generated
67
+ vba/test/corpus/ 261 VBA corpus cases
68
+ vb6/grammar.js module.exports = require("../common/define-grammar")("vb6")
69
+ vb6/src/scanner.c a four-token external scanner (see Design principles)
70
+ vb6/src/ generated vb6 parser
71
+ vb6/test/corpus/ 45 VB6 corpus cases
72
+ corpus/ provenance of the VB6 acceptance corpus; the source files are fetched, not vendored
73
+ examples/ 481 VBA example files
74
+ ```
75
+
76
+ Everything dialect-specific is an `isVB6` / `isVBA` branch inside the core;
77
+ `grep -n "isVB6\|isVBA" common/define-grammar.js` lists the complete delta.
78
+ This is the layout `tree-sitter-typescript` uses for TypeScript and TSX, and
79
+ the reason both grammars live in subdirectories: with more than one grammar in
80
+ `tree-sitter.json`, the CLI picks the grammar from the working directory.
81
+
82
+ Generated artifacts follow [ADR 0002](docs/adr/0002-generated-parser-artifacts.md):
83
+ `src/parser.c` and `src/grammar.json` are not tracked in either dialect
84
+ directory, `src/node-types.json` is, and `bindings/go/parser.c` is a tracked copy
85
+ of the `vba` parser.
86
+
87
+ ## Installation
88
+
89
+ ```bash
90
+ npm install tree-sitter tree-sitter-vba
91
+ ```
92
+
93
+ The npm package's native addon is the `vba` parser. The `vb6` parser ships as
94
+ generated C source (`vb6/src/parser.c` and `vb6/src/scanner.c`) for the
95
+ tree-sitter CLI and for direct embedding; Node.js and Go bindings for it are
96
+ not provided yet.
97
+
98
+ ## Usage
99
+
100
+ ```js
101
+ const Parser = require("tree-sitter");
102
+ const VBA = require("tree-sitter-vba");
103
+
104
+ const parser = new Parser();
105
+ parser.setLanguage(VBA);
106
+
107
+ const tree = parser.parse(`
108
+ Sub Hello()
109
+ Debug.Print "Hello"
110
+ End Sub
111
+ `);
112
+
113
+ console.log(tree.rootNode.toString());
114
+ ```
115
+
116
+ To parse VB6 from the command line, run the CLI inside the `vb6` directory,
117
+ which is how it selects the grammar:
118
+
119
+ ```bash
120
+ cd vb6 && tree-sitter parse /path/to/Form1.frm
121
+ ```
122
+
123
+ `scripts/run-tree-sitter.mjs --cwd vb6 parse <file>` does the same from the
124
+ repository root.
125
+
126
+ ## Go Usage
127
+
128
+ The Go binding is self-contained when installed through Go modules; its package
129
+ directory includes the generated C parser needed by cgo. It exposes the `vba`
130
+ parser.
131
+
132
+ ```go
133
+ package main
134
+
135
+ import (
136
+ "fmt"
137
+
138
+ tree_sitter "github.com/tree-sitter/go-tree-sitter"
139
+ tree_sitter_vba "github.com/harumiWeb/tree-sitter-vba/bindings/go"
140
+ )
141
+
142
+ func main() {
143
+ parser := tree_sitter.NewParser()
144
+ defer parser.Close()
145
+
146
+ parser.SetLanguage(tree_sitter.NewLanguage(tree_sitter_vba.Language()))
147
+
148
+ tree := parser.Parse([]byte("Sub Hello()\nEnd Sub\n"), nil)
149
+ defer tree.Close()
150
+
151
+ fmt.Println(tree.RootNode().ToSexp())
152
+ }
153
+ ```
154
+
155
+ Example output:
156
+
157
+ ```text
158
+ (source_file
159
+ (sub_declaration
160
+ name: (identifier)
161
+ (parameter_list)
162
+ body: (block
163
+ (call_statement
164
+ callee: (qualified_member_expression
165
+ receiver: (identifier)
166
+ operator: "."
167
+ member: (identifier))
168
+ arguments: (unparenthesized_argument_list
169
+ (string_literal))))))
170
+ ```
171
+
172
+ ## Node.js native build requirements
173
+
174
+ The npm package currently builds its native addon from source during
175
+ installation. Prebuilt native binaries may be added in a future release.
176
+
177
+ A supported Python installation, a C/C++ toolchain, and the platform
178
+ requirements documented by `node-gyp` are required.
179
+
180
+ On Windows, Visual Studio 2022 Build Tools with the **Desktop development with
181
+ C++** workload is recommended.
182
+
183
+ At minimum, Windows users typically need:
184
+
185
+ - Python 3.11 or later
186
+ - Visual Studio 2022 Build Tools
187
+ - MSVC C++ x64/x86 build tools
188
+ - Windows 10 SDK or Windows 11 SDK
189
+
190
+ If multiple Python installations are present, configure npm to use the intended
191
+ Python executable:
192
+
193
+ ```powershell
194
+ npm config set python "C:\Users\<you>\AppData\Local\Programs\Python\Python312\python.exe"
195
+ ```
196
+
197
+ For reliable native builds on Windows, run installation from:
198
+
199
+ ```text
200
+ x64 Native Tools Command Prompt for VS 2022
201
+ ```
202
+
203
+ ## Supported syntax
204
+
205
+ The grammar currently supports:
206
+
207
+ - apostrophe comments and `Rem` comments
208
+ - string, integer, floating-point, boolean, date, `Nothing`, `Null`, and `Empty`
209
+ literals
210
+ - decimal and hexadecimal literals with common VBA type characters, including
211
+ Currency (`@`) and LongLong (`^`), exponent notation such as `1E-3`, and
212
+ abbreviated decimal forms such as `.5` and `1.`
213
+ - identifiers with common VBA type-declaration characters, including `@` and
214
+ `^`; in declarations the Single character `!` (`Dim X!`, `Const Y! = 1`) is
215
+ a `bang_identifier` because it shares its token with the bang member operator
216
+ - identifiers, simple type clauses, dotted type names, and array type suffixes
217
+ - `Attribute` statements
218
+ - `Option Explicit`, `Option Private Module`, `Option Compare`, and `Option Base`
219
+ - `Implements` statements
220
+ - `Sub`, `Function`, and `Property Get/Let/Set` procedures
221
+ - `Event` declarations
222
+ - `RaiseEvent` statements
223
+ - `Dim`, `Static`, `WithEvents`, visibility-based variable declarations,
224
+ arrays, `ReDim`, `Erase`, and `Const`
225
+ - default type declaration statements such as `DefInt` and `DefStr`
226
+ - `Type` and `Enum` declarations
227
+ - external `Declare Function` and `Declare Sub` declarations, including
228
+ `PtrSafe`, `Lib`, and `Alias`
229
+ - simple assignments and `Set` assignments
230
+ - `Name oldPath As newPath` file rename statements
231
+ - calls, named arguments, omitted arguments anywhere in an unparenthesized
232
+ list, call-site `ByVal`, member access, bang member access, and leading-dot
233
+ member access
234
+ - `Debug.Print`, unparenthesized `Print` methods, and `? expr` Debug.Print
235
+ shorthand statements, including comma- and semicolon-separated output lists
236
+ with trailing output-position controls
237
+ - `New` expressions and `As New` declarations
238
+ - fixed-length string declarations
239
+ - `AddressOf` expressions
240
+ - common VBA operator precedence for arithmetic, concatenation, comparison, and
241
+ logical operators; `=`, `<>`, `<`, `<=`, `>`, `>=`, `Is`, and `Like`
242
+ comparisons are represented as `comparison_expression`
243
+ - comparison expressions in `Case` clauses, including object identity forms
244
+ such as `Case obj Is Nothing` and condition lists such as `Case x = 1, y = 2`
245
+ - block `If`, including colon-separated multi-statement single-line branches;
246
+ `Select Case`; and nested single-line `For`, `For Each`, `Do`, `While/Wend`,
247
+ and `With`
248
+ - `Next` counter lists such as `Next i` and `Next j, i`
249
+ - `On Error`, computed `On ... GoTo`/`GoSub`, `Resume`, `GoTo`, labels,
250
+ standalone `End`, and `Exit` statements
251
+ - common file I/O statements: `Open`, `Input #`, `Line Input #`, `Print #`,
252
+ `Write #`, `Close`, `Get #`, `Put #`, `Lock`, `Unlock`, `Seek`, and `Reset`,
253
+ including Print/Write output lists with trailing `;` or `,` and common
254
+ `Access ... Shared` locking clauses
255
+ - simple runtime statements: `Stop`, `Beep`, `Load`, and `Unload`
256
+ - Access report `Line` drawing calls that use coordinate ranges such as
257
+ `Me.Line (x, y)-(x2, y2)`
258
+ - `TypeOf ... Is ...` checks, including dotted type names such as `Access.Line`
259
+ - numeric line labels, numbered statements, and numbered control-flow delimiters
260
+ - conditional compilation with `#Const`, `#If`, `#ElseIf`, `#Else`, and
261
+ `#End If`, including statement branches inside procedures, members inside
262
+ `Type` and `Enum` declarations, and alternative procedure headers
263
+ - line continuations, including trailing whitespace, and colon-separated
264
+ statements and `Enum` members
265
+ - minimal `.frm` and `.cls` export metadata, including `VERSION`,
266
+ `Begin ... End`, `BeginProperty ... EndProperty`, GUID form blocks, and
267
+ `.frx` blob references
268
+ - initial `highlights.scm`, `folds.scm`, and `tags.scm` queries
269
+
270
+ ### VB6 additions
271
+
272
+ The `vb6` parser accepts everything above except the VBA7-only constructs
273
+ (`PtrSafe`, `LongPtr`, `LongLong`, `DefLngPtr`, `DefLngLng`: `PtrSafe` on a
274
+ `Declare` is an error, `LongPtr` and `LongLong` are ordinary user type names),
275
+ and adds:
276
+
277
+ - the `.frm`/`.ctl` header as the VB6 IDE writes it: `Object = "{GUID}#2.0#0"; "X.OCX"`
278
+ component references, nested `Begin Lib.Class Name ... End` blocks to any
279
+ depth, `BeginProperty` blocks with the OCX GUID and indexed names
280
+ (`BeginProperty ColumnHeader(1) {...}`), property values as strings, numbers,
281
+ negative numbers, hex literals, annotated booleans (`-1 'True`), `.frx`/`.ctx`
282
+ resource references with hexadecimal offsets and the `$` string prefix, menu
283
+ shortcuts (`^O`, `{F5}`, `+{DEL}`), indexed property-bag names
284
+ (`Tab(0).Control(1) = "txt(1)"`), and Single values written with a decimal
285
+ comma by IDEs on European locales (`FontSize = 8,25`); VB3-era
286
+ `Begin Form Form1` headers parse too
287
+ - the `.cls` header, `VERSION 1.0 CLASS` / `BEGIN ... END`, and two-valued
288
+ `Attribute VB_Ext_KEY = "A" ,"B"` lines written by Class Builder
289
+ - form and PictureBox graphics statements with coordinate pairs, bare or
290
+ `obj.`-qualified: `Line (x1, y1)-(x2, y2), color, BF`, `PSet (x, y), c`,
291
+ `Circle (x, y), r, , , , aspect`, and `Scale (0, 0)-(w, h)`, with any
292
+ trailing argument omitted
293
+ - a comment whose line ends in ` _` continuing onto the next line, which
294
+ compiled VB6 projects rely on
295
+ - multi-statement single-line loops, `For i = 1 To n: a = 1: b = 2: Next`
296
+ - calls whose first argument is an implicit member, `Foo .Bar, x`, read as a
297
+ call with two arguments rather than a chain `Foo.Bar` with an omitted
298
+ argument, through the external scanner described under Design principles
299
+ - constructs VBA also has but the base VBA grammar never accepted; most remain
300
+ `vb6` only so that the `vba` parser's trees and parse table stay within
301
+ the measured size and CST contract (see
302
+ [ADR 0005](docs/adr/0005-vba-parser-stays-the-base-grammar.md)).
303
+ Since v0.14.5, VBA also accepts `Let`, `On Local Error`, and `Global`;
304
+ the remaining `vb6`-only forms include `LSet`/`RSet`, `GoSub`/`Return`,
305
+ `Dim WithEvents`, `ReDim x(n) As T`, octal `&O` literals,
306
+ `AddressOf Module.Procedure`, `Name.Member` receivers, a comparison as the
307
+ left operand of another (`a = b <> 0`, `x Is Nothing = False`), a comparison
308
+ as the `Select Case` selector, `#If` around whole `Case` clauses, an empty
309
+ `Else` in a single-line `If`, `::` between inline
310
+ statements, a colon before a `For` body's line break, a `Type` member named
311
+ `End`, and the Single `!` suffix in expression positions (`total! = 0#`,
312
+ `rec.Percent! = 0#`)
313
+ - an indexed or property target on the left of `=` is an assignment; the base
314
+ lets `arr(i) = x` fall to a call of `arr` with the comparison `(i) = x` as
315
+ its argument when tree shape happens to prefer it
316
+
317
+ The VB6-only rules are gated by `isVB6` in the core and add these node types:
318
+ `frm_object_reference`, `frm_shortcut_value`, `frm_locale_number`,
319
+ `frm_property_index`, `frm_property_name`, `frm_blob_offset`, `line_statement`,
320
+ `pset_statement`, `circle_statement`, and `scale_statement`. The rest of the
321
+ additions in the list above are shared by both dialects; the `vba` tree shapes
322
+ pinned by the VBA corpus are unchanged.
323
+
324
+ ## Declaration node API
325
+
326
+ This release line is still pre-`1.0.0`, and declaration node shapes may change
327
+ when doing so makes syntactic metadata more directly available to downstream
328
+ tools.
329
+
330
+ Declaration consumers should prefer these structural nodes and fields over
331
+ source-text scanning:
332
+
333
+ - `property_get_declaration`, `property_let_declaration`, and
334
+ `property_set_declaration` distinguish property accessors directly.
335
+ - `declare_sub_statement` and `declare_function_statement` distinguish external
336
+ declaration kind directly.
337
+ - declaration headers expose stable fields such as `visibility`, `name`,
338
+ `parameters`, `type`, `library`, `alias`, `ptrsafe_modifier`, `body`, and
339
+ `end` where applicable. Procedure terminators are exposed through
340
+ `end_sub_statement`, `end_function_statement`, and `end_property_statement`
341
+ nodes.
342
+ - procedure declarations expose additional procedure modifiers through a
343
+ `modifiers` field, separate from `visibility`.
344
+ - variable, constant, type-member, and parameter declarations expose stable
345
+ `name`, `bounds`, `type`, `initializer`, `passing_mode`, `optional_modifier`,
346
+ `paramarray_modifier`, and `default_value` fields where syntactically valid.
347
+ - `with_events_modifier`, `static_modifier`, `byval_modifier`, `byref_modifier`,
348
+ `optional_modifier`, `paramarray_modifier`, and `ptrsafe_modifier` are
349
+ explicit modifier nodes.
350
+ - `implements_statement` exposes its target as `name`, and
351
+ `attribute_statement` exposes `name` and `value`.
352
+ - a name written with the Single type character is a `bang_identifier` whose
353
+ children are the `identifier` and the `!`; the other type characters stay
354
+ inside the `identifier` token. In `vba` the node occurs where a declaration
355
+ names something (`Dim`, `Const`, `ReDim`, `Type` members, parameters,
356
+ `Function` names); `vb6` also produces it in expression positions.
357
+
358
+ ## Expression node API
359
+
360
+ Member access and calls expose stable fields for analysis tools:
361
+
362
+ - `qualified_member_expression` uses `receiver`, `operator`, and `member`.
363
+ - `implicit_member_expression` uses `operator` and `member`; it has no
364
+ `receiver`, matching leading-dot and leading-bang VBA syntax.
365
+ - `call_expression` uses `function` and `arguments`, where `arguments` is an
366
+ `argument_list`.
367
+ - `call_statement` uses `callee` and, when arguments are present, `arguments`.
368
+ Parenthesized arguments use `argument_list`; statement-style arguments use
369
+ `unparenthesized_argument_list`. Unparenthesized `Print` methods are the
370
+ Print-family exception: their `arguments` field contains an `output_list`.
371
+ - `output_list` is shared by `Debug.Print`, `?`, `Print #`, `Write #`, and
372
+ unparenthesized `Print` methods. Output expressions use the `value` field;
373
+ `;` and `,` output-position controls use the `position` field containing a
374
+ `char_position` node. A position may follow the final output expression.
375
+ - in the `vb6` parser, `line_statement` and `scale_statement` use `start` and
376
+ `end` (each a `coordinate_pair` with `x` and `y`), `pset_statement` uses
377
+ `point`, `circle_statement` uses `center` and `radius`, the qualified forms
378
+ expose the receiver through `method`, and trailing graphics arguments use
379
+ `argument`.
380
+ - in the `vb6` parser, form header nodes expose `frm_property_statement` as
381
+ `name` and `value`, `frm_begin_block` as `type` and `name`,
382
+ `frm_begin_property_block` as `name`, `index`, and `guid`,
383
+ `frm_blob_reference` as `offset`, and `frm_object_reference` as `class` and
384
+ `file`.
385
+
386
+ ## Control-flow node API
387
+
388
+ - `for_statement` and `for_each_statement` expose optional terminator counters
389
+ through `next_variables: next_variable_list`; `next_variable` is no longer
390
+ emitted.
391
+ - `next_variable_list` always contains the ordered identifiers from `Next`,
392
+ whether there is one counter or several.
393
+ - A colon-separated single-line `If` branch with multiple statements is an
394
+ `inline_statement_sequence`; one-statement branches keep their direct child.
395
+ - `shared_next_for_body` represents an enclosing loop whose nested loop is
396
+ closed by the same `Next ...` counter list.
397
+ - In the `vb6` parser, `single_line_block` owns the colon after each of its
398
+ statements, so an inline loop may hold several statements before its `Next`,
399
+ `Loop`, or `End With`. The `vba` parser keeps its current shape.
400
+
401
+ ## Known limitations
402
+
403
+ This grammar parses VBA and VB6 syntax only.
404
+
405
+ It does not currently provide:
406
+
407
+ - type checking
408
+ - semantic analysis
409
+ - Excel Object Model or COM reference knowledge
410
+ - validation of identifier, member, type, procedure, workbook, or reference
411
+ existence
412
+ - validation of context-sensitive statement placement
413
+ - a formatter
414
+ - an LSP server
415
+ - complete coverage of every VBA expression edge case
416
+ - semantic interpretation of `.frm` designer metadata
417
+
418
+ For example, invalid placement of `Exit For`, unresolved procedure calls, invalid
419
+ Excel object members, or missing workbook references are intentionally left to
420
+ downstream tools.
421
+
422
+ General expression-level `=` comparison is still context-limited to avoid
423
+ ambiguity with assignment.
424
+
425
+ For the `vb6` parser:
426
+
427
+ - Input must be UTF-8 (or UTF-16 through the C API). VB6 source is stored in the
428
+ machine's code page, and bytes above 0x7F fed in raw never match the
429
+ identifier class, so identifiers such as `BtnAñadir` or a Big5 library name
430
+ in a `Begin` line are errors until the file is transcoded. Comments and
431
+ strings survive raw bytes; identifiers do not. Nine of the 1,436 corpus files
432
+ fail this way without transcoding.
433
+ - `Debug.Assert (a >= b And c <= d) Or e = 0`, a call statement whose single
434
+ unparenthesized argument is a parenthesized condition followed by `Or` and a
435
+ comparison, parses as `Debug.Assert(...) Or e` with an orphaned `= 0` and two
436
+ `MISSING` nodes. The same shape with plain identifiers inside the parentheses
437
+ parses correctly; the comparisons inside the parentheses tip a GLR fork. One
438
+ corpus file, one line.
439
+ - `.vbp` project files, `.dsr` designers, and `.pag` property pages are not
440
+ parsed; `.frx`/`.ctx` binaries are referenced, not read. VBA7 constructs are
441
+ rejected, and `#If VBA7` blocks are left to the conditional-compilation rules.
442
+ - There are no Node.js or Go bindings for the `vb6` parser yet; the npm addon,
443
+ the Go module, and the Wasm artifact are the `vba` parser.
444
+
445
+ ## Queries
446
+
447
+ This package includes initial Tree-sitter queries for:
448
+
449
+ ```text
450
+ queries/highlights.scm
451
+ queries/folds.scm
452
+ queries/tags.scm
453
+ ```
454
+
455
+ These queries are intended as a starting point for editor integrations and
456
+ tooling. They may evolve as the grammar stabilizes. Both grammars in
457
+ `tree-sitter.json` point at the same query files; the VB6-only node types are
458
+ not yet highlighted.
459
+
460
+ ## Development
461
+
462
+ Install dependencies:
463
+
464
+ ```bash
465
+ pnpm install
466
+ ```
467
+
468
+ Generate both parsers, or one of them:
469
+
470
+ ```bash
471
+ pnpm generate
472
+ pnpm generate:vba
473
+ pnpm generate:vb6
474
+ ```
475
+
476
+ After grammar changes, keep the Go module artifact in sync:
477
+
478
+ ```bash
479
+ cp vba/src/parser.c bindings/go/parser.c
480
+ pnpm check:go-parser
481
+ ```
482
+
483
+ Run corpus tests:
484
+
485
+ ```bash
486
+ pnpm test
487
+ ```
488
+
489
+ `pnpm test:corpus` runs the VBA corpus under the `vba` parser, the VB6 corpus
490
+ under the `vb6` parser, and then the VBA corpus under the `vb6` parser through
491
+ `scripts/test-shared-corpus.mjs`, which skips the cases whose expectations differ
492
+ between the dialects by design and prints the reason for each. `pnpm
493
+ test:corpus:vba` and `pnpm test:corpus:vb6` run one side.
494
+
495
+ The tree-sitter CLI selects the grammar from the working directory, so run it
496
+ inside `vba/` or `vb6/`; `scripts/run-tree-sitter.mjs --cwd vb6 <args>` does
497
+ that from the repository root.
498
+
499
+ Parse example files:
500
+
501
+ ```bash
502
+ pnpm parse:examples
503
+ ```
504
+
505
+ This recursively parses the checked-in VBA examples with the `vba` parser and
506
+ fails if any parse tree contains an `ERROR` or `MISSING` node.
507
+
508
+ Parse the VB6 acceptance corpus:
509
+
510
+ ```bash
511
+ node scripts/fetch-corpus.mjs
512
+ pnpm parse:corpus -- --transcode
513
+ ```
514
+
515
+ See [Testing](#testing) for what the corpus is and how it is measured.
516
+
517
+ Run queries against the example files:
518
+
519
+ ```bash
520
+ pnpm query:examples
521
+ ```
522
+
523
+ This validates that `highlights.scm`, `folds.scm`, and `tags.scm` can run
524
+ against the checked-in examples.
525
+
526
+ Run the coarse parser benchmark:
527
+
528
+ ```bash
529
+ pnpm bench
530
+ ```
531
+
532
+ This reports file counts, total bytes, parse time, node counts, and
533
+ `ERROR`/`MISSING` counts for the checked-in examples. It is intended to catch
534
+ large regressions, not to provide a strict microbenchmark.
535
+
536
+ Run the full local check:
537
+
538
+ ```bash
539
+ pnpm check
540
+ ```
541
+
542
+ Build and test the standalone browser parser (the `vba` parser):
543
+
544
+ ```bash
545
+ pnpm build:wasm
546
+ pnpm test:wasm
547
+ ```
548
+
549
+ Compare the native and browser parser targets on representative corpus and
550
+ exported-module fixtures:
551
+
552
+ ```bash
553
+ pnpm test:parity
554
+ ```
555
+
556
+ The parity suite checks root node types, `ERROR` / `MISSING` recovery, and
557
+ normalized syntax-tree structure. It uses the standalone Wasm parser through
558
+ `web-tree-sitter`; the browser consumer smoke test separately covers loading
559
+ and parsing in Chromium.
560
+
561
+ The complete browser artifact, release, versioning, and loading contract is
562
+ documented in [docs/specs/wasm-artifact.md](docs/specs/wasm-artifact.md).
563
+ In brief, versioned releases attach `tree-sitter-vba.wasm` and its SHA-256
564
+ checksum to the matching GitHub Release. The artifact is not committed or
565
+ included in the npm package. A browser consumer uses the matching
566
+ `web-tree-sitter@0.26.9` runtime:
567
+
568
+ ```js
569
+ import { Language, Parser } from "web-tree-sitter";
570
+
571
+ await Parser.init({ locateFile: () => "/assets/web-tree-sitter.wasm" });
572
+ const language = await Language.load("/assets/tree-sitter-vba.wasm");
573
+ const parser = new Parser();
574
+ parser.setLanguage(language);
575
+ const tree = parser.parse("Sub Hello()\nEnd Sub\n");
576
+ try {
577
+ if (!tree) throw new Error("Parser did not return a syntax tree");
578
+ console.log(tree.rootNode.toString());
579
+ } finally {
580
+ tree?.delete();
581
+ parser.delete();
582
+ }
583
+ ```
584
+
585
+ For a complete minimal static example, including local WebAssembly runtime
586
+ assets and `ERROR` / `MISSING` reporting, see
587
+ [examples/browser-consumer](examples/browser-consumer/README.md).
588
+
589
+ ## Testing
590
+
591
+ Tree-sitter grammar behavior is tested with corpus files under:
592
+
593
+ ```text
594
+ vba/test/corpus/
595
+ vb6/test/corpus/
596
+ ```
597
+
598
+ Community-reported production syntax regressions are kept permanently under
599
+ `vba/test/corpus/regressions/`; each fixture records whether it was already
600
+ supported or required a grammar change.
601
+
602
+ When changing `common/define-grammar.js`, always add or update focused corpus
603
+ tests in the dialect the change affects. Do not weaken existing expectations
604
+ just to make a grammar change pass. A shared change must leave the `vba` trees
605
+ unchanged; `scripts/test-shared-corpus.mjs` then runs the VBA corpus under the
606
+ `vb6` parser as well, so a `vb6` divergence shows up as a failure there and is
607
+ either fixed or recorded in the script's skip list with its reason. The 23
608
+ skips today are the VBA7 constructs, the `.frx` offset node
609
+ (`frm_blob_offset` in `vb6`, `number_literal` in `vba`), the pinned one-statement
610
+ inline-loop shape, four cases where the `vba` parser emits an opaque
611
+ `_ambiguous_call_statement` token that `vb6` parses with structure, and five
612
+ error-recovery shapes on deliberately invalid input.
613
+
614
+ A clean parse is not a stable tree. A bare call whose callee has been split
615
+ into its own `expression_statement` still has zero `ERROR` nodes, so neither
616
+ `pnpm parse:examples` nor the corpus can see that class of regression unless a
617
+ case pins the exact shape. `scripts/compare-cst.mjs` closes that gap for the
618
+ `vba` parser: it parses all 481 example files with a reference checkout and with
619
+ this checkout, strips positions, and lists every differing file by the node
620
+ types each hunk adds and removes. Point `--base` at a `main` worktree and name
621
+ the intended differences with `--allow`:
622
+
623
+ ```text
624
+ git worktree add /tmp/tree-sitter-vba-main main
625
+ node scripts/compare-cst.mjs --base /tmp/tree-sitter-vba-main --allow bang_identifier
626
+ ```
627
+
628
+ Run it before proposing any change to `common/define-grammar.js` that touches
629
+ calls, arguments, or precedence, and explain every remaining hunk in the pull
630
+ request.
631
+
632
+ The repository also includes real-world exported VBA examples. These examples
633
+ are parsed in CI to catch regressions against practical Excel/VBA code.
634
+
635
+ Broken or incomplete examples can be kept under:
636
+
637
+ ```text
638
+ examples/broken/
639
+ ```
640
+
641
+ These fixtures are intentionally excluded from `pnpm parse:examples`. Add
642
+ focused recovery expectations under `vba/test/corpus/recovery.txt` when the
643
+ surrounding tree shape should remain stable.
644
+
645
+ ### VB6 acceptance corpus
646
+
647
+ The `vb6` parser is measured against 1,436 real VB6 source files (647 `.frm`,
648
+ 382 `.bas`, 283 `.cls`, 124 `.ctl`) from 71 public GitHub projects, including
649
+ code from the late 1990s. The files are not vendored: `corpus/MANIFEST.md` pins
650
+ every project to a full commit SHA with its licence and file counts,
651
+ `corpus/FILES.tsv` lists every file, and `scripts/fetch-corpus.mjs` clones each
652
+ project at its pinned SHA and copies exactly those paths, so the set is
653
+ byte-identical to the one measured:
654
+
655
+ ```bash
656
+ node scripts/fetch-corpus.mjs # all 71 projects
657
+ node scripts/fetch-corpus.mjs --only <owner__repo>
658
+ pnpm parse:corpus -- --transcode
659
+ ```
660
+
661
+ Files are copied as raw bytes; most are Windows-1252 with CRLF and must not be
662
+ re-encoded, so the runner transcodes at read time per `corpus/ENCODINGS.json`
663
+ (180 files via Windows-1252, 56 via GBK, 22 via Big5). Keeping the source out of
664
+ the tree also means this repository redistributes nobody else's code; five of
665
+ the 71 projects are copyleft and are marked as such in the manifest.
666
+
667
+ Measured on 2026-09-25 with tree-sitter CLI 0.26.9:
668
+
669
+ | Check | Result |
670
+ | --- | --- |
671
+ | VB6 corpus, transcoded | 1,432 of 1,436 files parse with zero `ERROR` and zero `MISSING`. Three files carry syntax errors VB6 itself rejects and are listed with the defect in `corpus/EXCLUDED.json`; the runner reports them separately. One file keeps two `MISSING` nodes on the `Debug.Assert` shape described under Known limitations |
672
+ | VB6 corpus, raw bytes | nine further files fail on non-ASCII identifiers in legacy code pages |
673
+ | VBA corpus under `vba` | 261 of 261 cases; 481 of 481 example files without `ERROR` or `MISSING` |
674
+ | VB6 corpus cases under `vb6` | 45 of 45 |
675
+ | VBA corpus under `vb6` | 238 of 238 cases run, 23 skipped by design as listed above |
676
+ | Parse time | the largest corpus file, a 2.2 MB module, parses in about 410 ms (5.4 MB/s); a 500 KB `.frm` in 97 ms |
677
+
678
+ ## Design principles
679
+
680
+ This repository parses VBA and VB6 syntax only.
681
+
682
+ It does not validate whether identifiers, types, members, procedures, workbook
683
+ objects, or references are semantically valid. Those concerns belong in
684
+ downstream tools such as `xlflow`, `xlflow-lsp`, editor extensions, or other
685
+ analysis tools.
686
+
687
+ Node names should remain stable once introduced because downstream query files
688
+ and integrations may depend on them. However, because this is a `v0.x` release,
689
+ node names and tree shapes may still change before `v1.0.0`.
690
+
691
+ Over-acceptance is preferred to ambiguity: where a choice exists between
692
+ rejecting invalid code and keeping the tree unambiguous, the grammar keeps the
693
+ tree and leaves validation to downstream tools.
694
+
695
+ ### Why the `vb6` parser has an external scanner
696
+
697
+ VB6 reads whitespace before a member operator at statement level: `Foo .Bar, x`
698
+ is a call to `Foo` with two arguments, `Foo.Bar , x` a call to `Foo.Bar` with an
699
+ omitted first argument. A context-free grammar never sees the space. The `vba`
700
+ parser works around one shape with whole-line regex tokens
701
+ (`_ambiguous_call_statement`), which keep the tree free of errors but hide the
702
+ statement's structure, and `token.immediate(".")` cannot share a lexer state
703
+ with a regular `"."`. The scanner in [vb6/src/scanner.c](vb6/src/scanner.c)
704
+ emits `_dot_immediate` / `_dot_spaced` / `_bang_immediate` / `_bang_spaced`:
705
+ member chains use the immediate kind only, an implicit member may start with
706
+ either, a dot after a line continuation counts as immediate (`x("y") _`
707
+ followed by `.Add(...)` is a chain), and a dot followed by a digit is left to
708
+ the internal lexer (`.5`). It carries no state. The `vba` parser has no scanner.
709
+
710
+ ## Versioning
711
+
712
+ Recommended interpretation of the current release line:
713
+
714
+ - `0.1.x`: parser coverage fixes, query fixes, and non-breaking improvements
715
+ - `0.2.x`: expanded real-world VBA coverage; tree shapes may still evolve
716
+ - `0.x.0`: notable grammar expansion or tree-shape changes
717
+ - `1.0.0`: node names and tree shapes are considered stable for downstream use
718
+
719
+ ## Related projects
720
+
721
+ This grammar is intended to support practical VBA tooling, including the
722
+ [harumiWeb/xlflow](https://github.com/harumiWeb/xlflow) ecosystem for AI-assisted Excel/VBA development.
723
+
724
+ ## License
725
+
726
+ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
727
+
728
+ ### Third-party examples
729
+
730
+ The `examples/third_party` directory may contain third-party fixture files under
731
+ their original licenses. These files are provided for parser coverage only and
732
+ are not licensed under this repository's MIT license unless explicitly stated.
733
+ See [THIRD_PARTY_LICENSE.md](THIRD_PARTY_LICENSE.md) for the project inventory,
734
+ upstream sources, acknowledgements, and local license records.
735
+
736
+ The VB6 acceptance corpus is not part of this repository; `corpus/MANIFEST.md`
737
+ records the repository, commit, and licence of every project it is fetched
738
+ from.