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.1.tar.gz (77.4 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.1-cp310-abi3-win_arm64.whl (46.2 kB view details)

Uploaded CPython 3.10+Windows ARM64

tree_sitter_sas-0.4.1-cp310-abi3-win_amd64.whl (47.7 kB view details)

Uploaded CPython 3.10+Windows x86-64

tree_sitter_sas-0.4.1-cp310-abi3-musllinux_1_2_x86_64.whl (58.4 kB view details)

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

tree_sitter_sas-0.4.1-cp310-abi3-musllinux_1_2_aarch64.whl (58.7 kB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

tree_sitter_sas-0.4.1-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (59.7 kB view details)

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

tree_sitter_sas-0.4.1-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (58.9 kB view details)

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

tree_sitter_sas-0.4.1-cp310-abi3-macosx_11_0_arm64.whl (47.1 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

tree_sitter_sas-0.4.1-cp310-abi3-macosx_10_9_x86_64.whl (44.5 kB view details)

Uploaded CPython 3.10+macOS 10.9+ x86-64

File details

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

File metadata

  • Download URL: tree_sitter_sas-0.4.1.tar.gz
  • Upload date:
  • Size: 77.4 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.1.tar.gz
Algorithm Hash digest
SHA256 69b587dbb306991317275e0fb0192f4cc030e1f8e27edb00d8b3d7e9a225e68d
MD5 9424cdf27acf8623eda5e2ff35341979
BLAKE2b-256 008e0ce25c95e384bf6e84930bce914e1cbd027c501ff20291df964351ed8c0e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-win_arm64.whl
Algorithm Hash digest
SHA256 09ccf7b33d3f4bae181203aca7597f912f48b81a052f661000abb96d60c2358d
MD5 d0cdc8acd136a137a922edd530fc0d38
BLAKE2b-256 3896dd4277983941c0276b3c4415094c902b15e8be76ced946f1640983264fb2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 a966d3a0c682f845e150abc6f7be7386218b142aad994c0dd92e64214c98ca9e
MD5 1f192b9660825c44c483268c2e4515d8
BLAKE2b-256 11e69e2f1bb56c9164105049c869b00208219f7d65c2eb47b1276b718f5a3e78

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 18609fe15c5973ff72703437cc46f3e7d66b0bbca9d89a7d62831bf29168f303
MD5 5cbdea950f81c9e9c397bb207e6cc212
BLAKE2b-256 64b63d0e41fe77350c360569a21c08ed91c0fd66967e065e1a3252915c286225

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 40ddf7277bddb2234a209a79aa33fb382f8043c768d7b28b1a35d87318f1e5cc
MD5 70e577d69e01b09a0561dcd65844c2b9
BLAKE2b-256 6061431286076a008b432cac68212a80a6b52f4b341ab05905b6c4174a579f9a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c3eef994a2d4e4b678cd18fd9c3bbde53378802e1b638944c4ddf4d84b0b6e1d
MD5 f303e774094ffcf44d3a1c2049f8d3f9
BLAKE2b-256 5317c43802bc4796c5fb33fcb85f148e9cfbf6011218ef5d158cc00f4ebedf09

See more details on using hashes here.

File details

Details for the file tree_sitter_sas-0.4.1-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.1-cp310-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 a3afa2a6cb52c3bf51191d571abba6ccdfa148d7115c41f803834533f43a0785
MD5 104416cd8ee95712bfbe474915628de4
BLAKE2b-256 8f2387134a9344de383f12d834d47f18d9b59734938c00fbe5afe9ca9d08fd5d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 643732f36d20cd55a3c05a77b50149c316f81c10241c51fa985532ab296c38c3
MD5 4c353cb21e7212b0d55d61b1b2ac969d
BLAKE2b-256 10b05d327934084852a1ef886c3d0932afc50a14a25cb7cf103b802d196dc8b1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for tree_sitter_sas-0.4.1-cp310-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 16a47e6116087b29258a84b312fd89fc5b3d044816e1625ffebc12f1a3892b05
MD5 bbbd84f7cf7564435ccc77f9eeff46c0
BLAKE2b-256 9d2078577435f6f52cc03a4695175fa81373e0399dd91a30c5deddda142cf60d

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