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.3.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.3.1-cp312-abi3-win_amd64.whl (425.0 kB view details)

Uploaded CPython 3.12+Windows x86-64

tree_sitter_al-3.3.1-cp312-abi3-win32.whl (424.0 kB view details)

Uploaded CPython 3.12+Windows x86

tree_sitter_al-3.3.1-cp312-abi3-musllinux_1_2_x86_64.whl (508.2 kB view details)

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

tree_sitter_al-3.3.1-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl (511.3 kB view details)

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

tree_sitter_al-3.3.1-cp312-abi3-macosx_11_0_arm64.whl (488.3 kB view details)

Uploaded CPython 3.12+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tree_sitter_al-3.3.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.3.1.tar.gz
Algorithm Hash digest
SHA256 d6dbf891326bdc4f730deb9179e2df38f0bfc11d30e800d2dcf4fb7d24eb0950
MD5 01b356436211bc6992ed1e9212394221
BLAKE2b-256 7f31c1e44071340398c9f49ac284cdf7aafabe32203abb587f8828a1498346f2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-3.3.1-cp312-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 ca61346643b448faf5f654a50374f62725994f38911dbaa17361ebb2cc330f70
MD5 19f771197f9a9e1e0ec50e8a2465ae25
BLAKE2b-256 6c969a275e56a15476263970ee554fcd5dc8d0b2bbaea02d99903c18571862ec

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: tree_sitter_al-3.3.1-cp312-abi3-win32.whl
  • Upload date:
  • Size: 424.0 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.3.1-cp312-abi3-win32.whl
Algorithm Hash digest
SHA256 ccb0c0c4804abfc8fea407f73d7752f689adec026de00f9eab5bf88521d14a2d
MD5 3d0896dada5cb4464e30baf574acd6c2
BLAKE2b-256 4d7c94f0ecad33f6ec6a9268aca424f629884ba61addb2453f2fdfaf81096a8f

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-3.3.1-cp312-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f1383783c9fa9d0a159fa8bc9b01ac2cb5e8c6d4c776f330914923337049da4f
MD5 30720490912c9d8e047662281477ab9f
BLAKE2b-256 e6480d7da5ab7c3285bc84de460bd058f2b1e48e7b9ed71901fa400c32b010c0

See more details on using hashes here.

Provenance

The following attestation bundles were made for tree_sitter_al-3.3.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.3.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.3.1-cp312-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
Algorithm Hash digest
SHA256 bc3503f24e864485e2490463797d8bc07903a4719e66e30d4aaeab374818972a
MD5 17bad9c1c50faeccb348696aa0b1e768
BLAKE2b-256 5ed2502ae6628a60442399993c7932f4c214c9ff679044ac2b45febd42b953df

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for tree_sitter_al-3.3.1-cp312-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 ed81a8584f474577284787634cc51158c7f813e987a01246fa37e3f293c732f6
MD5 46df3d996ae7f0d1b5941e38e9f13252
BLAKE2b-256 30b686011bd2bc8f0c240c2497470c1d636f80b4b88ff73139f409473013deb9

See more details on using hashes here.

Provenance

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