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.6.0.tar.gz (1.4 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.6.0-cp312-abi3-win_amd64.whl (455.6 kB view details)

Uploaded CPython 3.12+Windows x86-64

tree_sitter_al-2.6.0-cp312-abi3-win32.whl (455.8 kB view details)

Uploaded CPython 3.12+Windows x86

tree_sitter_al-2.6.0-cp312-abi3-musllinux_1_2_x86_64.whl (538.3 kB view details)

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

tree_sitter_al-2.6.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (541.5 kB view details)

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

tree_sitter_al-2.6.0-cp312-abi3-macosx_11_0_arm64.whl (525.3 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tree_sitter_al-2.6.0.tar.gz
  • Upload date:
  • Size: 1.4 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.6.0.tar.gz
Algorithm Hash digest
SHA256 21355ac3ff4a4f439a4e1d5d949a2ad228ffbc497128d28b7bbcc903f2cfccc4
MD5 4524f8255d3361d2331dee4cfd00593a
BLAKE2b-256 de4850a7b0d2cb73b596177e316c83cd0e48d7fa95b442606804b71f9eb4b471

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.6.0-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 2c51749713eecd23ddb430397900c2a4a15242eec4a882cccbd579fce06591c4
MD5 efad8a7edd53da8c8ab031c3a543b2d7
BLAKE2b-256 5c3eb45e3e937f13c7d6dfbca453692497edc61843be693a06d08ae12e4ca5e1

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: tree_sitter_al-2.6.0-cp312-abi3-win32.whl
  • Upload date:
  • Size: 455.8 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.6.0-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 aa034066d8dcabcfacec7b5c5682e16dfe5ef5c6d1007f4a6aabd0c9860191a1
MD5 e17bfd63032233b2f19f47d4df31938c
BLAKE2b-256 ef97949a05d33695b8375e3199893476de8c1ab09ff7c73d2e883161a28e4500

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.6.0-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 7db5972fd0a406fc60f1031193fbc42ed70c81c6a429c7621d25935521c5b9a6
MD5 99b1067638b14bd0409708f0c5660009
BLAKE2b-256 ba22619ecc3c8be230cb6358bdcc444d457e7807d82273b9d714953216de67dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-2.6.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-2.6.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-2.6.0-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 cfdf551df1774e910ea98cb6ab6946044f96e2f23eb7c53ef83b8651637fa8c7
MD5 31f31262642cd68089cfcb57aa70305f
BLAKE2b-256 04e41db591dcc1089b95a1c8ce3849f7f13192f9440415fad25f4d98a2fe6cfe

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-2.6.0-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 d664e92228f5f9e2e4a9a26253d346299ca0a027fb5a0a7209c341a24d880a12
MD5 aedd5ecd334805d52352cf21b2647211
BLAKE2b-256 0c943c058204331d9220c3367bd1232cdaab4a0fe9d74dea95cac4bfab31f5d8

See more details on using hashes here.

Provenance

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