SAS language grammar for tree-sitter
Project description
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
Coming soon — a crates.io release is planned. In the meantime, use the GitHub source directly:
[dependencies] tree-sitter-sas = { git = "https://github.com/ix-infrastructure/tree-sitter-sas" }
Python bindings
Coming soon — a PyPI release is planned. In the meantime, build from source:
pip install git+https://github.com/ix-infrastructure/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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tree_sitter_sas-0.3.9.tar.gz.
File metadata
- Download URL: tree_sitter_sas-0.3.9.tar.gz
- Upload date:
- Size: 35.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe57ebc29850625fc7c063922237ddbbaa3861d7f3b98cd48edf5aabed736481
|
|
| MD5 |
a1a3acfb1117ed1b827aaa744894ce1e
|
|
| BLAKE2b-256 |
390baa4ebfd8f0c7e2e02c195c79adbcd575dc780d52fef29db3bf328abcec61
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-win_arm64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-win_arm64.whl
- Upload date:
- Size: 24.1 kB
- Tags: CPython 3.10+, Windows ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8c9a099c50be64d6fbd05cc94cc14e03109016ff70517fe87aba7716fbdb82d8
|
|
| MD5 |
393f9871c822e8dcd437f391e2088cf3
|
|
| BLAKE2b-256 |
dd7ccf821535a3eb772f76a7140f78c42a0ab25f22de98480598edd063c0caff
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 25.4 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
774ac15e27973e10f56974fd7ed7f66beb272608fa98b94fc2d2d226af451a26
|
|
| MD5 |
37f51a1e23b36e014be681538b23c41e
|
|
| BLAKE2b-256 |
a705711899d723ec68cc46aae4664cb49515be51e48454da49aed663831c6b4c
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 47.8 kB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
178831f8874e3ad1083e6a9171ee47a166fb38c872cb0908e33598d911e7caf0
|
|
| MD5 |
2e8c42a8c85a7978701471a7cfc1b38e
|
|
| BLAKE2b-256 |
d249dd3104770b212ff60881ecd1a7c013af920473bfa276aa4873b6482fe190
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 48.8 kB
- Tags: CPython 3.10+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6905319c5cca70ab97346e4eae2bf716d20c6ddc63d72f021e080bd855ffd15
|
|
| MD5 |
e40f2f12a229ac3f5cbfef3daa284a65
|
|
| BLAKE2b-256 |
d678bc8ace35bc5e3007bafe85d2f57bb13fb0ec0c1e2601932995afa8fc3cdb
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 50.6 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbc2916c8358872fbf1a1c11c81a892f52f494e35c665da88923e94aef3c5250
|
|
| MD5 |
4875c9ee6236f7985f1474015aa298a5
|
|
| BLAKE2b-256 |
3a0a62fa4ef6aba140906c5f742c68dee456c30c3db413227d2889365789759e
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
- Upload date:
- Size: 48.7 kB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b24b591b6c4f358dc07af41b7be04d73a3d573bfb10e61349f0b07cea400b8fc
|
|
| MD5 |
081b2c7b8023085a9b1ad286eb5e19d0
|
|
| BLAKE2b-256 |
33ae7907b3f777852b5bfd0a733c71520530969211eb787ad1ecc7dad9e58835
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 25.2 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0e9c3fa45e9c2dcbfd8442bbbddfb44e57ff7cc74971785f714007000fc9828
|
|
| MD5 |
96a96269e7f783f13824176704d5145a
|
|
| BLAKE2b-256 |
8cba6cc54c31598179aedefc8f94390a343bbca0a63d22598669e55da8295db7
|
File details
Details for the file tree_sitter_sas-0.3.9-cp310-abi3-macosx_10_9_x86_64.whl.
File metadata
- Download URL: tree_sitter_sas-0.3.9-cp310-abi3-macosx_10_9_x86_64.whl
- Upload date:
- Size: 24.8 kB
- Tags: CPython 3.10+, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a942ca0cdaf9611db13cfd987593b1a1a14cc9a6b1102a444e6625739490206
|
|
| MD5 |
31b5915133924ad042652b54e0e17730
|
|
| BLAKE2b-256 |
1ab7ac8b04b3fed1cc43fa085e979a08edea01deae6b65ed47f1332c69e28043
|