Skip to main content

tree-sitter-al

A tree-sitter parser for the AL programming language used in Microsoft Dynamics 365 Business Central.

PyPI crates.io npm

Parser Status

Validated against 15,358 production AL files from the Business Central codebase:

Metric Value
Success rate 100% (15,358 / 15,358 files)
Tests 1,451
parser.c size ~28 MB
grammar.js ~3,930 lines
Named keywords 82 (queryable via highlights/tags)
Scanner tokens 8 (stateful, depth-tracking)
Query files 6 (highlights, locals, tags, indents, folds, textobjects)

What's new in 3.0.0

Breaking parse-tree change for editor textobjects and code navigation. Every scoped construct now exposes its content as a single node via a body field (e.g. (page_declaration body: (declaration_body …)), (code_block (begin_keyword) body: (statement_block …) (end_keyword))), instead of a flat list of direct children. This powers Helix / nvim-treesitter textobjects (@class.inside, @function.inside, @parameter) via the new queries/textobjects.scm, plus a parameters field on procedures/triggers/events.

Tree-walkers and structural queries must descend through the body field — see CHANGELOG.md for the full migration guide.

Installation

Rust

cargo add tree-sitter-al
use tree_sitter::Parser;

let mut parser = Parser::new();
let language = tree_sitter_al::LANGUAGE;
parser.set_language(&language.into()).expect("Error loading AL grammar");
let tree = parser.parse("codeunit 50100 MyCodeunit { }", None).unwrap();
println!("{}", tree.root_node().to_sexp());

Query constants are also available:

use tree_sitter_al::{HIGHLIGHTS_QUERY, TAGS_QUERY, LOCALS_QUERY, FOLDS_QUERY, INDENTS_QUERY, TEXTOBJECTS_QUERY};

Python (tree-sitter 0.24+)

pip install tree-sitter-al
import tree_sitter
import tree_sitter_al

lang = tree_sitter.Language(tree_sitter_al.language())
parser = tree_sitter.Parser(lang)
tree = parser.parse(b'codeunit 50100 MyCodeunit { }')
print(tree.root_node.sexp())

Node.js

npm install tree-sitter-al

Pre-built binaries

Download from GitHub Releases:

File Platform Use case
tree-sitter-al.wasm All web-tree-sitter
tree-sitter-al.so Linux x86_64 ast-grep, native bindings
tree-sitter-al.dll Windows x86_64 ast-grep, native bindings
tree-sitter-al.dylib macOS ARM64 ast-grep, native bindings

V2 Architecture

The grammar was rewritten from scratch in March 2026, achieving a major reduction in parser size while improving correctness.

Before / After

Metric V1 V2 (current)
parser.c 106 MB (can't push to GitHub) ~25 MB
Errors 14 0
Success rate 99.91% 100%
Symbols 2,249 ~814
States 29,126 ~12,600
grammar.js 8,500 lines ~3,930 lines
Tests 1,225 1,451
Keywords invisible in queries 82 named nodes
Query files 3 (partial) 6 (comprehensive)

Key design decisions

  • Stateful external scanner — 8 scanner tokens handle property disambiguation, depth tracking (#if/#endif nesting), named begin/end keywords at depth 0, and split-construct detection via lookahead.
  • Parse structure, don't validate — Accept any Name = Value ; as a property. Semantic validation belongs in linters/LSP servers, not the parser.
  • Generic preprocessor — One preproc_conditional rule + ~15 dedicated rules for genuinely complex split constructs (begin/end, var/begin, brace-close across #if/#else branches).
  • 82 named keyword nodes — All keywords including begin/end are named nodes, enabling proper syntax highlighting and code navigation queries.

See docs/v2-blog-post-notes.md for the full rewrite narrative.

Development

Prerequisites

  • Node.js (v16+)
  • tree-sitter CLI: npm install -g tree-sitter-cli

Building

tree-sitter generate    # Generate parser from grammar.js
tree-sitter test        # Run test suite

Validation

./validate-grammar.sh        # Quick: generation, tests, orphan/duplicate detection
./validate-grammar.sh --full # Full: includes production AL file parsing

For grammar refactors, the parse-tree diff harness proves a change is zero-behavior-change by re-parsing every production file and asserting byte-identical trees:

./tools/tree-harness.sh snapshot ./BC.History .snapshots/bc   # baseline
./tools/tree-harness.sh verify   ./BC.History .snapshots/bc   # verify after a change

Parsing AL files

tree-sitter parse path/to/file.al
tree-sitter parse path/to/file.al -d    # Debug output
tree-sitter parse path/to/file.al -q    # Quiet (errors only)

Key files

File Purpose
grammar.js Main grammar definition
src/scanner.c External scanner (8 tokens: property, depth tracking, named begin/end, split detection)
test/corpus/ Test suite (1,451 tests)
queries/ Syntax highlighting, code navigation, folding, indentation, textobjects

Contributing

See CLAUDE.md for detailed development guidelines including architecture, debugging, and conventions.


Author: Torben Leth (sshadows@sshadows.dk) License: MIT (see LICENSE)

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_al-3.3.0.tar.gz (1.3 MB view details)

Uploaded Source

Built Distributions

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

tree_sitter_al-3.3.0-cp312-abi3-win_amd64.whl (425.0 kB view details)

Uploaded CPython 3.12+Windows x86-64

tree_sitter_al-3.3.0-cp312-abi3-win32.whl (424.0 kB view details)

Uploaded CPython 3.12+Windows x86

tree_sitter_al-3.3.0-cp312-abi3-musllinux_1_2_x86_64.whl (508.1 kB view details)

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

tree_sitter_al-3.3.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (511.2 kB view details)

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

tree_sitter_al-3.3.0-cp312-abi3-macosx_11_0_arm64.whl (488.2 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

Details for the file tree_sitter_al-3.3.0.tar.gz.

File metadata

  • Download URL: tree_sitter_al-3.3.0.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tree_sitter_al-3.3.0.tar.gz
Algorithm Hash digest
SHA256 17093d4504a87e6ed6bbcfa850e4032da17f0f507e5ae932daec83aeb09a85b7
MD5 afa17e45d85701ff92281227025b7106
BLAKE2b-256 07bd01c23c10fbd09ec13d8e0143294ab9df054e5c332a52385686b5cff489ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.0.tar.gz:

Publisher: publish-pypi.yml on SShadowS/tree-sitter-al

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_al-3.3.0-cp312-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.3.0-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 e3f803e42dbeee692fcc2cbc8701b4e5b3d683ad419c0ec7f327e61f919278eb
MD5 4856f06262587d1e2df492108633814d
BLAKE2b-256 a6a5e3dd5220ad3a065050d3780f875da499b2acce2f344e9bcbf12337adf1ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.0-cp312-abi3-win_amd64.whl:

Publisher: publish-pypi.yml on SShadowS/tree-sitter-al

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_al-3.3.0-cp312-abi3-win32.whl.

File metadata

  • Download URL: tree_sitter_al-3.3.0-cp312-abi3-win32.whl
  • Upload date:
  • Size: 424.0 kB
  • Tags: CPython 3.12+, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tree_sitter_al-3.3.0-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 ea7c6f1ce156dcfc7b19a32e021da644d8b4db405f343793dea0df549623481d
MD5 02c70f0fd131bf4b57a93f8b48d93a84
BLAKE2b-256 8ddcf7724673c06885c8fa66daa0c3c594a4ff54954a745e2f34fc367d54ef32

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.0-cp312-abi3-win32.whl:

Publisher: publish-pypi.yml on SShadowS/tree-sitter-al

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_al-3.3.0-cp312-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.3.0-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ac11e4ccbe713d0183c11d8264acd264ea01e04f23e83932de3ad9c396d51a66
MD5 2271e84a3d14df457486e64ef05a4fe8
BLAKE2b-256 fba0a1b87198bebbeb2f2e327cd84fb1cf4a53644872d60c51118291263b3aca

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.0-cp312-abi3-musllinux_1_2_x86_64.whl:

Publisher: publish-pypi.yml on SShadowS/tree-sitter-al

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_al-3.3.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.3.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 6967b2520726717240c72623f6338e8fe864815509f5d62ba14e4cd5a370d30b
MD5 89589787a0d629115e591d7e0e2018b3
BLAKE2b-256 885d8afc67c3ed21593c263e5c0e52f3f238b97582339150af3ce312b42aa6bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl:

Publisher: publish-pypi.yml on SShadowS/tree-sitter-al

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tree_sitter_al-3.3.0-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.3.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fbaabd154f5746c0239dc12ff714f0ede1194ae35ac1722149090a557e694c50
MD5 107029fe721bc937a4e3eb652a9c820e
BLAKE2b-256 6d1bb464891ad891f6b2d17192e8adc8c7f025c4f8d1f4f14960f395bc040d6e

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.0-cp312-abi3-macosx_11_0_arm64.whl:

Publisher: publish-pypi.yml on SShadowS/tree-sitter-al

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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