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 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

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


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.3.8.tar.gz (35.5 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.3.8-cp310-abi3-win_arm64.whl (24.1 kB view details)

Uploaded CPython 3.10+Windows ARM64

tree_sitter_sas-0.3.8-cp310-abi3-win_amd64.whl (25.5 kB view details)

Uploaded CPython 3.10+Windows x86-64

tree_sitter_sas-0.3.8-cp310-abi3-musllinux_1_2_x86_64.whl (47.8 kB view details)

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

tree_sitter_sas-0.3.8-cp310-abi3-musllinux_1_2_aarch64.whl (48.7 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

tree_sitter_sas-0.3.8-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (51.1 kB view details)

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

tree_sitter_sas-0.3.8-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (49.2 kB view details)

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

tree_sitter_sas-0.3.8-cp310-abi3-macosx_11_0_arm64.whl (25.4 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

tree_sitter_sas-0.3.8-cp310-abi3-macosx_10_9_x86_64.whl (25.0 kB view details)

Uploaded CPython 3.10+macOS 10.9+ x86-64

tree_sitter_sas-0.3.8-cp310-abi3-macosx_10_9_universal2.whl (41.8 kB view details)

Uploaded CPython 3.10+macOS 10.9+ universal2 (ARM64, x86-64)

File details

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

File metadata

  • Download URL: tree_sitter_sas-0.3.8.tar.gz
  • Upload date:
  • Size: 35.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.0

File hashes

Hashes for tree_sitter_sas-0.3.8.tar.gz
Algorithm Hash digest
SHA256 3933ce02140bc367c91bed11dcee81b33566bddf6ee20c6f04947f3b7dd3e35f
MD5 37fa13fbbb1d073fdfab4d4ffcf2e87f
BLAKE2b-256 11509c3b0f081c78425203f380dc7e4021c63a90da6f39d4e2a8302352918c64

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 bdf8f6f70dc92260dfd709f5adcd231eed4a18a93ebf336a01db97dd03e35a26
MD5 8798dc103ed3eeda1ba0fcc5e57e3d77
BLAKE2b-256 d32c94121d97422ccfdc6b95a8b91d287010015e9da3a03276a55a9caef17496

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2e7450f6bb66ec0a988892b2c7b2bd9c92bedcc74c251f4b93a31a545f5c6872
MD5 a9dd314a465b28edbd10de3758a613d3
BLAKE2b-256 8f488cbe871426f01a3dd1fb7635bd9c26f5b4fd72d38abda7cad5f66f2c1017

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 107ec40dce89a77ce979006292942a494afadab7eb5660fe39d89e8f22946718
MD5 6cbba31504c527ff4b1b66da97b0032f
BLAKE2b-256 5eb961de921ee96f43496337a5186e3533d2140fc09842702efe2130408192bb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 84c03dd2457817952f6a3051a21e2e4e8fdf6cf0faae55205433c081c700bdc1
MD5 1c3f88a7ae941284c63c4deac1857dcf
BLAKE2b-256 655310ef3af2b4427862fb1de870ea29c8bffeff201d26ae145951d55667fcc0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 57b78e98ad9e404b561046af5a52f8211cd66162d78bb541b2bc1ee56b3e2cdb
MD5 3170b3ede740f8e07edea4348e03d3a2
BLAKE2b-256 5d3be0f088a50bc78b2db758fb5d39a31439600cd5186249ac5b72561936fbb1

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.3.8-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.3.8-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 a3c4333652c17944cbf86c9f60c88be732cff9068606b3a7b1c1bc4ad6bf5b3b
MD5 01ac1a5d3e282e7f0aee0c92b48cc7fa
BLAKE2b-256 b047d27aab8e16c01e650cc334bcf13f51bd15f6bc5ee49fd8dda12e306b94eb

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4c4f542919ac18cc664eb3fb1d4ae88b1d2b157453e36c70043bcc4bcc6dd0fd
MD5 268207f628431a79e718d083c7d19020
BLAKE2b-256 9b90464248bbb8223056c5deee5ac483b2a7d7a89e7e4809897840c1ea53f899

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 a4d189cd40a36fb38a219ac851556e6cbe3ce9816afc697afd32bb478c36d547
MD5 b1f73050cf2ba987f2d1425eca70e45b
BLAKE2b-256 71618c35c6a57aad59289edcdaa2728656a500c3c3caf9cd8804f71c2017e401

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.3.8-cp310-abi3-macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for tree_sitter_sas-0.3.8-cp310-abi3-macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 3303a33cf4abefce964d9b94224707496452c495e1216f7a0726b6e58286d975
MD5 86211093b1c0b92dfa7a0a89272e368d
BLAKE2b-256 e19e8b87ad5473901892ac48f03de92c950097e13aeaf3e495936cf3f79f0760

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