Crates.io | tree-sitter-tlaplus |
lib.rs | tree-sitter-tlaplus |
version | 1.5.0 |
source | src |
created_at | 2021-08-12 21:54:07.969021 |
updated_at | 2024-10-20 15:59:24.168912 |
description | A tree-sitter grammar for TLA⁺ and PlusCal |
homepage | |
repository | https://github.com/tlaplus-community/tree-sitter-tlaplus |
max_upload_size | |
id | 435432 |
size | 37,515,916 |
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.
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:
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:
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:
As applicable, query files for integrations live in the integrations
directory.
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:
nix-shell
tree-sitter test
Otherwise:
npm install
npm test
This test ensures the grammar can parse all modules in the tlaplus/examples repo, which is included as a git submodule. To run:
npx tree-sitter init-config
./test/run-corpus.sh
; for Windows, run .\test\run-corpus.ps1
If using nix:
nix-shell
tree-sitter build-wasm
tree-sitter playground
Otherwise:
npm install
npx tree-sitter build-wasm
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)
You can fuzz the grammar if you're running Linux with a recent version of Clang installed. Do so as follows:
--recurse-submodules
parametertest/fuzzing/build-for-fuzzing.sh
test/fuzzing/out/tree_sitter_tlaplus_fuzzer
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.