Tree-sitter grammar for SurrealQL, built as a parallel implementation of the @surrealdb/lezer parser. The grammar mirrors lezer's node names, hierarchy, and token aliasing 1:1 so that the parsed trees can be compared structurally.
Targetting SurrealDB v3 and above. Branch
tree-sitter-parityrebuilds the grammar from scratch against the lezer reference; the previousmainretains the originaltree-sitter-surrealqlgrammar (Cellan Hall) for compatibility.
grammar.js— tree-sitter grammar (PascalCase rule names matching lezer)src/scanner.c— external scanner (object/block disambiguation + JS function bodies)test/corpus/— auto-generated test fixtures matching lezer's tree outputqueries/highlights.scm— highlight queries (regenerate when grammar nodes change)compare.ts— diff a SurrealQL file against the lezer parserrun-corpus.ts— run the lezer test corpus through both parsers and report mismatchesgen-corpus.ts— regeneratetest/corpus/*.txtfrom lezer's expected trees
353 / 355lezer corpus tests produce identical canonical trees (bun run run-corpus.ts).tree-sitter testsucceeds on353 / 355fixtures (the two failing tests are JavaScript function bodies whose internalBraceOpen/JavaScriptContent/BraceClosecannot be exposed without breaking the external scanner for invalid input — seeLEZER_ISSUES.md).
bun run gen # tree-sitter generate
bun run test # tree-sitter test (corpus fixtures)- PascalCase rule names mirror lezer node types exactly. Hidden rules use a leading underscore (analogous to lezer's lowercase "passthrough" rules).
- Token-as-node visibility (
Keyword,Operator,RangeOp,BraceOpen,Colon,Pipe,LookupRight,LookupLeft,LookupBoth,Any,Bool,None,Literal, etc.) is achieved withalias($._kw_x, $.Keyword)at every call site. The visible rules' bodies double as the underlying keyword regexes. - Inline named nodes from lezer (e.g.
Subscript,Filter,Legacy,Modern,Point,BulkInsert,EnforcedClause,DefaultAlways, …) are promoted to top-level rules with the same name. - The external scanner (
src/scanner.c) handles two cases:OBJECT_OPEN— mirrors lezer'sobjectTokento distinguish{key:value}(Object) from{stmt;}(Block) from{1,2}(Set).JS_FUNCTION_BODY— consumes the entirefunction() { … }body as a single token, replicating lezer's@skip {}behaviour without splitting the JS content into separate sub-tokens (which would cascade on invalid input during error recovery).
Building on the foundation of Cellan Hall's tree-sitter-surrealql. The current tree-sitter-parity branch reworks the grammar to match the lezer reference exactly; the original implementation is preserved on main.