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.2.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.2.0-cp312-abi3-win_amd64.whl (416.4 kB view details)

Uploaded CPython 3.12+Windows x86-64

tree_sitter_al-3.2.0-cp312-abi3-win32.whl (416.5 kB view details)

Uploaded CPython 3.12+Windows x86

tree_sitter_al-3.2.0-cp312-abi3-musllinux_1_2_x86_64.whl (499.4 kB view details)

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

tree_sitter_al-3.2.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (502.6 kB view details)

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

tree_sitter_al-3.2.0-cp312-abi3-macosx_11_0_arm64.whl (478.5 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tree_sitter_al-3.2.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.2.0.tar.gz
Algorithm Hash digest
SHA256 d417b109b49fc3ee59269f6ee41ce761fe8e1d7e1e1bcfabf44684a3992a2b7a
MD5 5005b402daa51d006d7598118d53c637
BLAKE2b-256 a96f7e9b2a1db1f67b175297f2f245a0820c887595103fe6a45b9d589d3e445f

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.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.2.0-cp312-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.2.0-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4d54b9e65614ae993f04a4ccf25779e056268e79bf866179666f911b8452bdbe
MD5 177331f60d918c604fc2369a4d2503aa
BLAKE2b-256 6049b02d4083de66e8bd8e131ec499633de10d7a70602a4e551f1a9d6526a7a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.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.2.0-cp312-abi3-win32.whl.

File metadata

  • Download URL: tree_sitter_al-3.2.0-cp312-abi3-win32.whl
  • Upload date:
  • Size: 416.5 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.2.0-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 da0af8a939f5cd12af6936e8bf059d1b80bb05fd6f9e648fffa6813947c7f7cd
MD5 1afb8844e787a1952c3d81111a45e97b
BLAKE2b-256 8c3f7a208d5fffe8777deb6e2c93f239d2b5df8587355a02391f5d9034d82cb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.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.2.0-cp312-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.2.0-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8b3768596ebe9d5e419d5436bccc8da36fe0edc34f25aa9585a99891811cc971
MD5 1ebc88eda6043e52d096ff1460cded53
BLAKE2b-256 883a8a942110aff1efe313b52a4ab011229395c7911fb11983921fc808efb66a

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.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.2.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.2.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 ce3f3c164840d2ae47843678686d8a2ac3ff1322c3e8254001a09291972f3fdd
MD5 600f1f8c5865d1547d43cbe5e2e16d05
BLAKE2b-256 6cb522fca29101bb323dcd3c26077fd1735e1fb1f074e49e82df67b45245a0f8

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.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.2.0-cp312-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_al-3.2.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6584fee8e0483e03a6716f5e6da031d556a4cb16719ba575149c2f855d64cbaa
MD5 e5db7cb684ea7a30ab3bd1e8efc2ea53
BLAKE2b-256 54ef733487681ab959a8027814d42c8fb67e827b659cf66b5b38c3592b4298b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.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