AL for Business Central
Project description
tree-sitter-al
A tree-sitter parser for the AL programming language used in Microsoft Dynamics 365 Business Central.
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,404 |
| parser.c size | ~11 MB |
| grammar.js | ~3,100 lines |
| Named keywords | 82 (queryable via highlights/tags) |
| Scanner tokens | 8 (stateful, depth-tracking) |
| Query files | 5 (highlights, locals, tags, indents, folds) |
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};
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 10x reduction in parser size while improving correctness.
Before / After
| Metric | V1 | V2 |
|---|---|---|
| parser.c | 106 MB (can't push to GitHub) | 10.6 MB |
| Errors | 14 | 0 |
| Success rate | 99.91% | 100% |
| Symbols | 2,249 | ~740 |
| States | 29,126 | ~5,300 |
| grammar.js | 8,500 lines | ~3,100 lines |
| Tests | 1,225 | 1,404 |
| Keywords | invisible in queries | 82 named nodes |
| Query files | 3 (partial) | 5 (comprehensive) |
Key design decisions
- Stateful external scanner — 8 scanner tokens handle property disambiguation, depth tracking (
#if/#endifnesting), namedbegin/endkeywords 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_conditionalrule + ~15 dedicated rules for genuinely complex split constructs (begin/end, var/begin, brace-close across#if/#elsebranches). - 82 named keyword nodes — All keywords including
begin/endare 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
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,404 tests) |
queries/ |
Syntax highlighting, code navigation, folding, indentation |
Contributing
See CLAUDE.md for detailed development guidelines including architecture, debugging, and conventions.
Author: Torben Leth (sshadows@sshadows.dk) License: MIT (see LICENSE)
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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tree_sitter_al-2.4.0.tar.gz.
File metadata
- Download URL: tree_sitter_al-2.4.0.tar.gz
- Upload date:
- Size: 1.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5037acb5197ce9d6f97082e48ad0854a5b6ef8afbd374012bb58876bd31ae274
|
|
| MD5 |
2840a49fc698097693ce975884481ee3
|
|
| BLAKE2b-256 |
51ebcd79e3a355cf4c8dc537e07c25582afbe2da2b0e45402b001fe320900cbb
|
Provenance
The following attestation bundles were made for tree_sitter_al-2.4.0.tar.gz:
Publisher:
publish-pypi.yml on SShadowS/tree-sitter-al
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tree_sitter_al-2.4.0.tar.gz -
Subject digest:
5037acb5197ce9d6f97082e48ad0854a5b6ef8afbd374012bb58876bd31ae274 - Sigstore transparency entry: 1206367480
- Sigstore integration time:
-
Permalink:
SShadowS/tree-sitter-al@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SShadowS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file tree_sitter_al-2.4.0-cp312-abi3-win_amd64.whl.
File metadata
- Download URL: tree_sitter_al-2.4.0-cp312-abi3-win_amd64.whl
- Upload date:
- Size: 414.9 kB
- Tags: CPython 3.12+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
275426c3af9c8acb640983537d173b1e966517f0c91dbc9038f5eb73a99eb407
|
|
| MD5 |
1b0ba72d11d7219fc022ea55272a7572
|
|
| BLAKE2b-256 |
c024bc9905e15cd114f6a044a73f761affe2db447af61c1845f4cf630c28bbf1
|
Provenance
The following attestation bundles were made for tree_sitter_al-2.4.0-cp312-abi3-win_amd64.whl:
Publisher:
publish-pypi.yml on SShadowS/tree-sitter-al
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tree_sitter_al-2.4.0-cp312-abi3-win_amd64.whl -
Subject digest:
275426c3af9c8acb640983537d173b1e966517f0c91dbc9038f5eb73a99eb407 - Sigstore transparency entry: 1206367529
- Sigstore integration time:
-
Permalink:
SShadowS/tree-sitter-al@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SShadowS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file tree_sitter_al-2.4.0-cp312-abi3-win32.whl.
File metadata
- Download URL: tree_sitter_al-2.4.0-cp312-abi3-win32.whl
- Upload date:
- Size: 406.1 kB
- Tags: CPython 3.12+, Windows x86
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81d8bd9d532a78858bee71c1e0654e49c64d995cc5bb496b3b4ba11bcd9742ac
|
|
| MD5 |
2f481f2cece8bba94210f2159000704f
|
|
| BLAKE2b-256 |
ffb090b2c87e04e984a463e1aba39b1575438ab060eb8b562bbf8d261c8404cd
|
Provenance
The following attestation bundles were made for tree_sitter_al-2.4.0-cp312-abi3-win32.whl:
Publisher:
publish-pypi.yml on SShadowS/tree-sitter-al
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tree_sitter_al-2.4.0-cp312-abi3-win32.whl -
Subject digest:
81d8bd9d532a78858bee71c1e0654e49c64d995cc5bb496b3b4ba11bcd9742ac - Sigstore transparency entry: 1206367588
- Sigstore integration time:
-
Permalink:
SShadowS/tree-sitter-al@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SShadowS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file tree_sitter_al-2.4.0-cp312-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: tree_sitter_al-2.4.0-cp312-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 468.6 kB
- Tags: CPython 3.12+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f062902ccbb13ca4830c1a9cfd0fb8dbef680214edf89332a1a02621cb47022d
|
|
| MD5 |
67fe1867efbe822be97a117c8fc080ef
|
|
| BLAKE2b-256 |
cb7e046de6e033c1ccfab62453515157e0c793f9ee150fca653c5c730e8c75ca
|
Provenance
The following attestation bundles were made for tree_sitter_al-2.4.0-cp312-abi3-musllinux_1_2_x86_64.whl:
Publisher:
publish-pypi.yml on SShadowS/tree-sitter-al
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tree_sitter_al-2.4.0-cp312-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
f062902ccbb13ca4830c1a9cfd0fb8dbef680214edf89332a1a02621cb47022d - Sigstore transparency entry: 1206367567
- Sigstore integration time:
-
Permalink:
SShadowS/tree-sitter-al@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SShadowS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file tree_sitter_al-2.4.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl.
File metadata
- Download URL: tree_sitter_al-2.4.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
- Upload date:
- Size: 471.7 kB
- Tags: CPython 3.12+, manylinux: glibc 2.28+ x86-64, manylinux: glibc 2.5+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
293b645fb101c45db4258ba012a4d3e760e12f339b7fcf9d4d996cc5d955fbec
|
|
| MD5 |
686aa50fda3a4fde67495d933b790a2b
|
|
| BLAKE2b-256 |
f1f2c8c44319ffdf1e209a208f0dcc3888cfbbb59669ddb04bce7fab4361649f
|
Provenance
The following attestation bundles were made for tree_sitter_al-2.4.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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tree_sitter_al-2.4.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl -
Subject digest:
293b645fb101c45db4258ba012a4d3e760e12f339b7fcf9d4d996cc5d955fbec - Sigstore transparency entry: 1206367613
- Sigstore integration time:
-
Permalink:
SShadowS/tree-sitter-al@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SShadowS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file tree_sitter_al-2.4.0-cp312-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: tree_sitter_al-2.4.0-cp312-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 448.4 kB
- Tags: CPython 3.12+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
110b6a3e16df9d9ae0fd00ea37767cecb0dac0c970b9e286c230542723bb4cd2
|
|
| MD5 |
aaf438e68032a37cf9c43221bf532018
|
|
| BLAKE2b-256 |
282ff67fd3d2548e276d9639c48808af3621fa4dc45264ddd061c0501806ec12
|
Provenance
The following attestation bundles were made for tree_sitter_al-2.4.0-cp312-abi3-macosx_11_0_arm64.whl:
Publisher:
publish-pypi.yml on SShadowS/tree-sitter-al
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tree_sitter_al-2.4.0-cp312-abi3-macosx_11_0_arm64.whl -
Subject digest:
110b6a3e16df9d9ae0fd00ea37767cecb0dac0c970b9e286c230542723bb4cd2 - Sigstore transparency entry: 1206367504
- Sigstore integration time:
-
Permalink:
SShadowS/tree-sitter-al@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/SShadowS
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@4ffbe756b7319a400efe2145ee8ad00115825e70 -
Trigger Event:
workflow_dispatch
-
Statement type: