Skip to main content

A tree-sitter grammar for TLA⁺ and PlusCal

Project description

tree-sitter-tlaplus

Build & Test npm crates.io PyPI

Overview

This is a tree-sitter grammar for the formal specification language TLA⁺ and its embedded variant PlusCal. Tree-sitter is an incremental error-tolerant parser generator primarily aimed at language tooling such as highlighting, code folding, symbol finding, and other tasks making use of its fully-featured syntax tree query API. This grammar is intended to function gracefully while parsing a source file mid-edit, when the syntax isn't fully correct. It is also fast enough to re-parse the file on every keystroke. You can take the parser for a spin at https://tlaplus-community.github.io/tree-sitter-tlaplus/

The most important files in this repo are grammar.js and src/scanner.c. The former is the source of truth for parser code generation and the latter contains logic for parsing the context-sensitive parts of TLA⁺ like nested proofs and conjunction/disjunction lists. This grammar is published as a Rust crate, Node.js package, and Python package. You can see examples of how to consume these packages here. A WASM build is also included in the Node.js package and attached to the releases in this repo.

A blog post detailing the development process of this parser can be found here. This repo is mirrored on sourcehut.

Aims & Capabilities

The aim of this project is to facilitate creation of modern user-assistive language tooling for TLA⁺. To that end, the project provides two main capabilities:

  1. Provide an approximately-correct parse tree for TLA⁺ specifications in standardized form, for easy integration with general projects designed to consume the tree-sitter grammars of many languages.
  2. Provide a tree query API for efficiently querying the TLA⁺ parse tree, in addition to an API for arbitrary programmatic exploration of same, with bindings in multiple languages for easy integration with projects specifically targeting TLA⁺.

The correctness criterion of this parser is as follows: if the TLA⁺ specification being parsed constitutes valid TLA⁺ (both syntactically and semantically), the parse tree will be correct. If the spec is not valid TLA⁺, the parse tree will be approximately correct - perhaps permissively allowing illegal syntax, or interpreting erroneous syntax in strange ways. This permissive behavior makes it excellent for user-assistive language tooling, but a less-compelling choice as the backbone for an interpreter or model-checker. Application possibilities include:

Use & Notable Integrations

There are a number of avenues available for consuming & using the parser in a project of your own; see examples in several different programming languages here.

Notable projects currently using or integrating this grammar include:

  • nvim-treesitter for TLA⁺ syntax highlighting & code folding in Neovim
  • tla-web for a web-based TLA⁺ interpreter and trace explorer
  • GitHub for syntax highlighting of TLA⁺ files and snippets
  • tlauc for translating between ASCII and Unicode TLA⁺ symbols

As applicable, query files for integrations live in the integrations directory.

Build & Test

Be sure to clone the repo with the --recurse-submodules parameter, or run git submodule update --init --recursive if you already cloned it without that parameter.

If using nix:

  1. Run nix-shell
  2. Run tree-sitter test

Otherwise:

  1. Install node.js and npm
  2. Ensure a C compiler is installed and on your path
  3. Run npm install
  4. Run npm test

Corpus Tests

This test ensures the grammar can parse all modules in the tlaplus/examples repo, which is included as a git submodule. To run:

  1. If this is the first time running tree-sitter on your machine, run npx tree-sitter init-config
  2. For Unix-type OSs, run ./test/run-corpus.sh; for Windows, run .\test\run-corpus.ps1
  3. The scripts exit with error code 0 if successful

Build WASM & Start Playground

If using nix:

  1. Run nix-shell
  2. Run tree-sitter build-wasm
  3. Start the playground with tree-sitter playground

Otherwise:

  1. Install node.js and npm
  2. Install Emscripten 3.x
  3. Run npm install
  4. Run npx tree-sitter build-wasm
  5. Start the playground with npx tree-sitter playground

The playground enables you to easily try out the parser in your browser. You can use the playground online (serving the latest release) or run it locally by following the directions above.

The playground consists of a pane containing an editable TLA⁺ spec, and another pane containing the parse tree for that spec. The parse tree is updated in real time as you edit the TLA⁺ spec. You can click parse tree nodes to highlight the corresponding snippet of TLA⁺, and move the cursor around the spec to show the corresponding parse tree node. You can click the "log" checkbox and open your browser's development console to see the parser's debug output as it attempts to parse the TLA⁺ spec. You can also click the "query" checkbox to open a third pane for testing tree queries; for example, enter the following to match all operator names in a capture named @operator (indicated by the names becoming highlighted):

(operator_definition name: (identifier) @operator)

Fuzzing

You can fuzz the grammar if you're running Linux with a recent version of Clang installed. Do so as follows:

  1. Clone the repo with the --recurse-submodules parameter
  2. From repo root, run the bash script test/fuzzing/build-for-fuzzing.sh
  3. From repo root, run test/fuzzing/out/tree_sitter_tlaplus_fuzzer

Contributions

One easy way to contribute is to add your TLA⁺ specifications to the tlaplus/examples repo, which this grammar uses as a valuable test corpus!

Pull requests are welcome. If you modify grammar.js, make sure you run npx tree-sitter generate before committing & pushing. Generated files are (unfortunately) currently present in the repo but will hopefully be removed in the future. Their correspondence is enforced during CI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

tree_sitter_tlaplus-1.5.0-cp38-abi3-win_amd64.whl (267.9 kB view details)

Uploaded CPython 3.8+ Windows x86-64

tree_sitter_tlaplus-1.5.0-cp38-abi3-musllinux_1_1_x86_64.whl (317.8 kB view details)

Uploaded CPython 3.8+ musllinux: musl 1.1+ x86-64

tree_sitter_tlaplus-1.5.0-cp38-abi3-musllinux_1_1_aarch64.whl (343.3 kB view details)

Uploaded CPython 3.8+ musllinux: musl 1.1+ ARM64

tree_sitter_tlaplus-1.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (315.6 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ x86-64

tree_sitter_tlaplus-1.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (343.2 kB view details)

Uploaded CPython 3.8+ manylinux: glibc 2.17+ ARM64

tree_sitter_tlaplus-1.5.0-cp38-abi3-macosx_11_0_arm64.whl (302.8 kB view details)

Uploaded CPython 3.8+ macOS 11.0+ ARM64

tree_sitter_tlaplus-1.5.0-cp38-abi3-macosx_10_9_x86_64.whl (263.8 kB view details)

Uploaded CPython 3.8+ macOS 10.9+ x86-64

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 fca488eeedfcdc26ac12f704fc1d3747749d27f0d311b567068db6786d8d5cd5
MD5 fe208787e89830af8e16140b628049c9
BLAKE2b-256 f1e4d365ab2d1ff1631dc384c82478b5187a6895e21a9187c9270c187f043b94

See more details on using hashes here.

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 30d2988235128131ca73e226509ce119e7dee91b4dc7247414d6cb30b27b7ef5
MD5 7b8aa79733d518131f6cc70c3fc7ed4b
BLAKE2b-256 02f40544b6fcfa68ffa3ab6ad163d0f06a908819d83411c96cdd8b08bf94f44e

See more details on using hashes here.

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 2f012891c2216d4217d1de95289d954be9815edfcb57d8418d7cce9ecc5daa27
MD5 5069403ade166dff03ead0b18104fcde
BLAKE2b-256 9d3e20659c15352ef00cef6a7834fcdebedda024d2c63c4856860a83e1f9adf3

See more details on using hashes here.

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 03419e9141e9fbae7fec1eb73013a836682383bc819fe3cbbdb6ae2a32ec2a4d
MD5 9628a419c6f2a79fea1007f7087221b1
BLAKE2b-256 174276e0dfe9206bc3588fb103af7eabfb89bd869e36580c9ca5443930b28bb0

See more details on using hashes here.

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 03d1989b2c53e8eb1dc229bb437ae458213a500a0873e85a74ab539baf52dcb7
MD5 fe1b2cd6ab3de5771f9cb25de450f4c2
BLAKE2b-256 b0bd1489c861a1e8b78da107321889f10d5ccca22d5170b91037fa5ff48629d7

See more details on using hashes here.

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 48ec40a7a29462d6039a34fd9d54346e9f3f1f3efdef2acb071905b92a9ddf6a
MD5 a5d4a55577b3b6cabb09fef7d8906969
BLAKE2b-256 38711c9e151d15d5e76519365e24bb906fc5125ffc74f14effabe6f7c25491d4

See more details on using hashes here.

File details

Details for the file tree_sitter_tlaplus-1.5.0-cp38-abi3-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for tree_sitter_tlaplus-1.5.0-cp38-abi3-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 3f727fe97dae5316f5a29c9281df125139f0c4a8548fcf8a1546e3f30d6d2b83
MD5 af0bd835db456dd0bc16b1ed926f5486
BLAKE2b-256 62f759a5c897f490d39ca39152e8f052fe02bcdc70dcea164cb7bb802365effe

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page