tree-sitter-sas
A tree-sitter grammar for the SAS programming language.
Node bindings
Available on npm as tree-sitter-sas.
npm install tree-sitter-sas
Prebuilt native binaries ship for linux-x64, darwin-x64, and darwin-arm64 — no compile step required.
Rust bindings
Available on crates.io as tree-sitter-sas.
[dependencies]
tree-sitter-sas = "0.3"
Python bindings
Available on PyPI as tree-sitter-sas.
pip install tree-sitter-sas
Go bindings
import "github.com/ix-infrastructure/tree-sitter-sas/bindings/go"
Swift bindings
Add to Package.swift:
.package(url: "https://github.com/ix-infrastructure/tree-sitter-sas", from: "0.3.1")
Architecture
flowchart LR
subgraph source ["Grammar source"]
G["grammar.js\n(tree-sitter DSL)"]
SC["src/scanner.c\n(external scanner)"]
end
GEN(["tree-sitter generate"])
subgraph generated ["Generated parser"]
PC["src/parser.c"]
NT["src/node-types.json"]
end
subgraph queries ["Queries"]
HL["queries/highlights.scm\n(syntax highlighting)"]
TG["queries/tags.scm\n(symbol index)"]
end
subgraph bindings ["Language bindings"]
N["Node · npm"]
R["Rust · crates.io"]
PY["Python · PyPI"]
GO["Go"]
SW["Swift"]
end
G & SC --> GEN --> PC & NT
NT -.-> HL & TG
PC --> N & R & PY & GO & SW
grammar.js defines the language using the tree-sitter DSL. src/scanner.c is an external lexer that
disambiguates %-prefixed macro keywords (%let, %macro, %mend, %include) from user-defined macro
calls — it emits a keyword token only when the keyword is not immediately followed by an identifier
character, so %letput and %macroFoo correctly fall through to macro_call_statement instead.
Running tree-sitter generate produces the LR parser (src/parser.c) and the node type schema
(src/node-types.json).
Language coverage
| Construct | Node type |
|---|---|
DATA step |
data_step |
PROC step |
proc_step |
%MACRO / %MEND definition |
macro_definition |
%name(args) call statement |
macro_call_statement |
%name(args) inline call |
macro_call |
%LET var = value |
macro_variable_assignment |
&var, &&var, &var. references |
macro_variable_ref |
%INCLUDE 'path' |
include_statement |
LIBNAME libref ... |
libname_statement |
OPTIONS ... |
options_statement |
/* ... */ block comments |
block_comment |
* ... ; line comments |
line_comment |
%* ... ; macro comments |
percent_comment |
| Everything else | generic_statement (flat fallback) |
Statements not matched by a specific rule are absorbed by generic_statement, which preserves the source
text without losing parse continuity. The tree is always complete — unknown or proc-specific syntax never
breaks the parse.
Known deviations
generic_statement as a catch-all
SAS has hundreds of proc-specific statements (MODEL, CLASS, OUTPUT inside PROC REG, etc.) that
would require individual rules to represent structurally. This grammar uses generic_statement as a flat
fallback for any semicolon-terminated statement not matched by a more specific rule. The tradeoff: internal
proc statement structure is not captured in the tree, but the tree is always well-formed and the
surrounding program structure is always intact.
Macro keyword disambiguation via external scanner
%KEYWORD tokens share a prefix with user-defined macro calls. The external scanner in src/scanner.c
resolves the ambiguity: it emits a structured keyword token only when the keyword is not immediately
followed by [A-Za-z0-9_]. This means %letput is a macro call, not a %let statement — matching
SAS's own behavior.
Bare % in non-macro contexts
A literal % can appear in non-macro positions (e.g. width=20% in ODS style attributes). The external
scanner emits a _bare_pct token for these cases, which is absorbed into generic_statement content
without triggering a macro parse path.
References
Metadata
Release files for tree-sitter-sas 0.4.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| tree_sitter_sas-0.4.2.tar.gz | 86.2 kB | Without provenance | Details |
Built distributions (wheels)
Total release size: 584.9 kB
Release files / tree_sitter_sas-0.4.2.tar.gz
| Download URL | tree_sitter_sas-0.4.2.tar.gz |
|---|---|
| Size | 86.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0bf60b6434015b36a0105bbb8b78b2f46568566b5849a74bee3000d39f3926cb
|
|
BLAKE2b-256 checksum How to use checksums |
237b5644acdbef190098d022ca2feb747e0b9de8bd0aed974e0bfba1f11fd6ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-win_arm64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-win_arm64.whl |
|---|---|
| Size | 55.4 kB |
| Tags | CPython 3.10 Windows ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
d3d4676498418e4d622c244ad36b898d9aaf23ce4cf656ec266673af933642da
|
|
BLAKE2b-256 checksum How to use checksums |
3a931a638a8df76af05abb73ef6e2b22d35e898d3cb15ccbe446b8d125288887
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-win_amd64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 57.3 kB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
ca96574dfae47f5a94e2273e38ece25863fd48a4ae5a3d2c03ac2056935a2ce5
|
|
BLAKE2b-256 checksum How to use checksums |
dbe0fa793931bc57c6dccf10cd2ffdc2a96366d157a2f8cc612e7f0829370f3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 68.4 kB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
1be73663c7385e3e894f8b10ecdae636c1d77ea5e921b2d2aee32999c416914d
|
|
BLAKE2b-256 checksum How to use checksums |
b43b2295752b3ef6863ef0e1039748f0b8922527ba287017a4f55dcf1a7c30f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-musllinux_1_2_aarch64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 68.7 kB |
| Tags | CPython 3.10 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
0d6a4e7518a1465ed4f2e783ae0901f6e7b660c892379f9447466f94ab8011e2
|
|
BLAKE2b-256 checksum How to use checksums |
c073c6bfe22d61537015a90d3b2c13749ea8db0524ce1b94e4cb728c3a344179
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 69.3 kB |
| Tags | CPython 3.10 Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
074fd05168c7d8ec9e173d4d98ba9698a94b9a7d0a78b5896cb7d110a0d43158
|
|
BLAKE2b-256 checksum How to use checksums |
9623b9a577b563fb6f0cd5b6f280e83290190be8080a4ed580c20224325b1d31
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl |
|---|---|
| Size | 69.0 kB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
46931772298910d76cf1f3bc64bd49eaca6e6d954646ebfb6f6c02470975a308
|
|
BLAKE2b-256 checksum How to use checksums |
3b12f3508c424a57970717569962d7563db1fe8070f73670fc7fb016b7917dcc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 56.7 kB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
684197a93b0d3df37740b3186a150107abeffa5577173d6a0e04b9ee726549a0
|
|
BLAKE2b-256 checksum How to use checksums |
85fa6f91ae2c330c9266d11fe19a616a582ecfa6cceb57088d3d5cbe1f3b7c26
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / tree_sitter_sas-0.4.2-cp310-abi3-macosx_10_9_x86_64.whl
| Download URL | tree_sitter_sas-0.4.2-cp310-abi3-macosx_10_9_x86_64.whl |
|---|---|
| Size | 53.8 kB |
| Tags | CPython 3.10 abi3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
4bf2d35f18920a1eb2d7088b2a49462e75a496edb4b8b56696bc7e0399f52cd5
|
|
BLAKE2b-256 checksum How to use checksums |
23d892640ff898e0de9ed85b11ec0b8e1dc2913de9f61082a3cb95c0899a5613
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for tree-sitter-sas 0.4.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.