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

Uploaded CPython 3.12+Windows x86-64

tree_sitter_al-2.5.1-cp312-abi3-win32.whl (421.3 kB view details)

Uploaded CPython 3.12+Windows x86

tree_sitter_al-2.5.1-cp312-abi3-musllinux_1_2_x86_64.whl (484.4 kB view details)

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

tree_sitter_al-2.5.1-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (487.6 kB view details)

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

tree_sitter_al-2.5.1-cp312-abi3-macosx_11_0_arm64.whl (466.0 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tree_sitter_al-2.5.1.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.1.tar.gz
Algorithm Hash digest
SHA256 b2ba568e764f91d3432ae344ed855e5c493fb1fbc2507a1841cf72556e628af4
MD5 d5fcf68b21c6029b1ecd8368af963348
BLAKE2b-256 a184f1107219b350f4a9ad126c57b92c1a2fdb1ea7306ad18d9365a7d8417cae

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.5.1-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 8e2c859e4c26c1e83d67e8a3f1ba889fe052016d5ac17aef38eb9fa6a0aec950
MD5 19163e04ddfd6ec085f8f0ea79d10f0e
BLAKE2b-256 fa72f3fee27b79b9a000305841a2b6beee5d7a77c2da3592ea9216cd85653085

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: tree_sitter_al-2.5.1-cp312-abi3-win32.whl
  • Upload date:
  • Size: 421.3 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.1-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 9b53b44fd2e777f991eb8eb890c27af1be30780d84fc5940b199e6f216b001d4
MD5 b61552ace52eb66259ff237d916ddd07
BLAKE2b-256 69b5a3ea0304979d9ed6e9f4dca444ceb0c3c05b395f296b4212847de0523572

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.5.1-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 44ae41563a60fb34e216fb6b320f48b84e5e30849f04470af1b2683de90c450e
MD5 64a7853799bc4ea38fe774039a0ddd72
BLAKE2b-256 b4709fa906a11e00e2a48c86af54d79e53d400c90c9641685fc0bda7e860fd66

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-2.5.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-2.5.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-2.5.1-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 67720ad36deae49b70f7eea91d39a5b82633d2d16dff6c4741a1151466f66782
MD5 1e246dd91a0850cf31b12e65d19089c3
BLAKE2b-256 0c1f3ebd5a96e26ae123384a85b3b99e1069849f614fc37b0493acf257e3dac7

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.5.1-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8f7745f6fddb2a6146a10a9d45c0e8bd39d48e765e46b25043376ebe724cc164
MD5 71aee2bb19e72b53e884c7d1315449cb
BLAKE2b-256 a96f10eade3e85d649fd76a16c991699ee825dad5e160f01caf8de620c426a77

See more details on using hashes here.

Provenance

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