Skip to main content

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.

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,437
parser.c size ~25 MB
grammar.js ~3,750 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 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 ~10,800
grammar.js 8,500 lines ~3,750 lines
Tests 1,225 1,437
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/#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,437 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

tree_sitter_al-2.5.2.tar.gz (1.2 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-2.5.2-cp312-abi3-win_amd64.whl (430.2 kB view details)

Uploaded CPython 3.12+Windows x86-64

tree_sitter_al-2.5.2-cp312-abi3-win32.whl (423.1 kB view details)

Uploaded CPython 3.12+Windows x86

tree_sitter_al-2.5.2-cp312-abi3-musllinux_1_2_x86_64.whl (486.4 kB view details)

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

tree_sitter_al-2.5.2-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (489.7 kB view details)

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

tree_sitter_al-2.5.2-cp312-abi3-macosx_11_0_arm64.whl (467.9 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tree_sitter_al-2.5.2.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tree_sitter_al-2.5.2.tar.gz
Algorithm Hash digest
SHA256 24b3d62f4a7b562fa935b241c27e55ae5bf3ad4be4fa5d42e1ad03d8f85c8b97
MD5 3869dba5859a1e5020b6bd0e7f513814
BLAKE2b-256 da3c1386f10cea833ae83f50f8624cc4a171f6e104ae222fd483e73a9682ec92

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.5.2-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 8c1e47b1e07cab9562ac79eb6aa4f8f8e92c44217e2e52928bf48ce1b334a13d
MD5 8aa951c1f31c7574f230c66d12b1205e
BLAKE2b-256 810186317dc2ff9d4012c2651c7dad911f18d800b1274e738d1a329492453385

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: tree_sitter_al-2.5.2-cp312-abi3-win32.whl
  • Upload date:
  • Size: 423.1 kB
  • Tags: CPython 3.12+, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tree_sitter_al-2.5.2-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 0d2ccac8436068115daeffcef4fd4bfc4246e947e88a88bd5838c152c20f1992
MD5 4955b5ee9f3c0878b22d7fedf298a63a
BLAKE2b-256 0afd4738edf7fc9754b0afb155d03548eef4adb0815076f8a12f460a72404ea3

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.5.2-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 9972d8b79ec86f61724df555ab4daea7d8209fba53dcbd35388bb5d1bec6c3e6
MD5 6c2102fc1b45abf4c205bba569a05c20
BLAKE2b-256 8de4e3ff49dc48f27151f1cf993f92ae310ef2eb54c73626b8de99eb45bab226

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-2.5.2-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-2.5.2-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-2.5.2-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 6d2de292cbad5f60dc08314eed5bb8c931d70b3ae55d597da634bac7759620dd
MD5 2a4a2294ca5525f9942fe33838cfe849
BLAKE2b-256 7cdac7006aa02cb53b59c9c2c661a22b6d9c4dea01c601ba5540f1852de4e01c

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.5.2-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0795bb21514d459a93d0a6c88c2977442b7f76d3a68bf346577e2b7b2375ccef
MD5 fe12dd779273196968774dfbd72fde7c
BLAKE2b-256 2d39d9990aef0fa3306d439586a3a0d886024df9dbd7349075b213ac56f7bb6e

See more details on using hashes here.

Provenance

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