Skip to main content

SAS language grammar for tree-sitter

Project description

tree-sitter-sas

A tree-sitter grammar for the SAS programming language.

npm crates.io PyPI CI License: MIT

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tree_sitter_sas-0.4.0.tar.gz (77.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tree_sitter_sas-0.4.0-cp310-abi3-win_arm64.whl (45.7 kB view details)

Uploaded CPython 3.10+Windows ARM64

tree_sitter_sas-0.4.0-cp310-abi3-win_amd64.whl (47.3 kB view details)

Uploaded CPython 3.10+Windows x86-64

tree_sitter_sas-0.4.0-cp310-abi3-musllinux_1_2_x86_64.whl (58.0 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

tree_sitter_sas-0.4.0-cp310-abi3-musllinux_1_2_aarch64.whl (58.4 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

tree_sitter_sas-0.4.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (59.3 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

tree_sitter_sas-0.4.0-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (58.5 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64manylinux: glibc 2.5+ x86-64

tree_sitter_sas-0.4.0-cp310-abi3-macosx_11_0_arm64.whl (46.7 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

tree_sitter_sas-0.4.0-cp310-abi3-macosx_10_9_x86_64.whl (44.2 kB view details)

Uploaded CPython 3.10+macOS 10.9+ x86-64

File details

Details for the file tree_sitter_sas-0.4.0.tar.gz.

File metadata

  • Download URL: tree_sitter_sas-0.4.0.tar.gz
  • Upload date:
  • Size: 77.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tree_sitter_sas-0.4.0.tar.gz
Algorithm Hash digest
SHA256 4ee9ee3b55b102fbbd16b32bb3f5c53383062ee914e7cab276d8d9a392e17974
MD5 eddcdf2c7ae2c13573fc6a4fb21c84fd
BLAKE2b-256 2ecb977bf5af6fb4f4f48cd7246782792f99e58a11d5632782016d2ad2e6c02a

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-win_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 b79c96f0ec607872a6e8af00b98b1822d209ce18dca2df670d2cee1263df4b0e
MD5 c6aaade4ecad69c93738146770bde80c
BLAKE2b-256 1753ccdc9e00737292410c4bbf891a17cd080619debf524e8e36996de815cb16

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 502a84bd9d51f215b280b9544c0d09c0c03086cbbf8e30f26ab5e3c7882929a7
MD5 75ab58da82cc3fa15f243bbf155884b4
BLAKE2b-256 3dc84f9b867bc2297db30c7dae7a03cf0cd97f1f99e28dbb873ac8bf92f8d689

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 6ea2fd5585723f05c7f004fe6e8ce481161d4594eba138969eedb3112ea97981
MD5 f6479097d9057d00c6297d2b4877ad32
BLAKE2b-256 be9ee0621a4c6a36336fd76216fb34a82c231ccbb06588e2b0e4368940201d59

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 dd8a76a42f28134c0c9c25296a851ed6d73a77208d620d8ba514fe98307fcc8c
MD5 e6185f86fbe2ba816bb0a3952fe9349d
BLAKE2b-256 2d2a172ee9ef8789c90fd016631228495e3514e0d93f3fd3d7b04ecec9c214a8

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a08b0fa5a54c49e472ccef78aa083835707be1c13899f1e8592da36080919e6e
MD5 e3cc1f41fb7e2cbcc2bfd3fe62661920
BLAKE2b-256 511214b7cbaa084bc5c88b85d998c28e312bf2f4330445f1eb377603230b5c11

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 37a89135744e80c3a4ffd8ce262d6d7b47387548fde45797f53a8ea3d364bcf4
MD5 eb5da9cd35fa44e4fe1597b7b548a969
BLAKE2b-256 a91156f58d84ad0fc0162b232ebab35994e5c3b8537bb73dcd139b8226bc6004

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f7ec3984603b3530d7ac18a29ca54c08968d83973bd9b81ba1f22589fd4ee65e
MD5 fb866ef6d41131ddbc219d3edb7342d7
BLAKE2b-256 75f9431fea6f57e62c5802f59077e60a0ebff37628f7907212a746265ed590e9

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.0-cp310-abi3-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.0-cp310-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 67d84ce6d55b99b52a1367569bb13a60d0af15dbfb2aba7f1e2fda993baecef6
MD5 916075104d8289ce04fe8db9c4337c1e
BLAKE2b-256 a464ca0ffdd1421dfc399b75e3c30c61bc1c3e071c78a4e86128d0c8293e93b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page