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

Uploaded CPython 3.12+Windows x86-64

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

Uploaded CPython 3.12+Windows x86

tree_sitter_al-3.2.1-cp312-abi3-musllinux_1_2_x86_64.whl (499.8 kB view details)

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

tree_sitter_al-3.2.1-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (503.1 kB view details)

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

tree_sitter_al-3.2.1-cp312-abi3-macosx_11_0_arm64.whl (478.6 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tree_sitter_al-3.2.1.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.1.tar.gz
Algorithm Hash digest
SHA256 6de439fdbaa3ce4befff28e42429a5e2d7eb938fe74bb331179da2a0f9bb7bef
MD5 36d66c26e3355ba7c301f5b915d05789
BLAKE2b-256 6f4eb734718455847b64ea6125a2fa5e38dd3b27bd22ed34de58671f9f8a6b74

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-3.2.1-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 d513bf7b13499c872237032851e03326404fda07910461bde3f08d45040557e3
MD5 ab53fbe2ec9975fbf2655675f3154d60
BLAKE2b-256 cf559d971132171dd6c850bf835cb64c7fabbfffe6aa95342108eb436e2cb3bf

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: tree_sitter_al-3.2.1-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.1-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 73ee8966e6968bdedd44d13015903619baf46629ef4f639edd81ca44b95a3a07
MD5 05ad40b3c6dcaf6477372772344a8779
BLAKE2b-256 03c7cd81c89ea30afa460aee447f1b0741fe66e6f5260409e54ca5c406a283a3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-3.2.1-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cb806b40b8cb8ac5a5fb85cc5eddcd04d1e046d5f3d5c654af6573a40764e62e
MD5 7c94ddce121a97c1cbf104381361c419
BLAKE2b-256 fb0b4c2f15488f6173f7bd3c30300d97b857f0cd4706c01d002ee10100ead4cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.2.1-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.1-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.1-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 30b10e9452316d7f2d6ffd8ffa270b19f4c4dd3c8d2e9e995aa7097d4fb10a39
MD5 207192c5aac877e732714ba9da814dc7
BLAKE2b-256 74ad2dac873ebf9a2100edb5c461c7ef0d4ab5624eba6d96a35d52022069d781

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-3.2.1-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d4c43e778648192c374c6069ae8ec7366d22bc12a947c43564ca5d89df2525d9
MD5 886bc6849f831637231fbc0c5d8e2278
BLAKE2b-256 af99663391bdf17b211f1b03dc40195dda7862216193bfcae29a03531789528e

See more details on using hashes here.

Provenance

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