A tree-sitter grammar for the P programming language.
The grammar follows the ANTLR grammar used by the P compiler:
Comments in grammar.js reference the corresponding parser
rules.
The grammar covers:
- Core declarations:
event,eventset,type(user-defined and foreign),enum,fun(named, foreign withcreates/return/requires/ensurescontracts, and anonymous functions),machine(withreceives/sendsannotations),spec,scenario,interface,module,implementation,test,param - State machines:
start/hot/coldstates,entry/exit,on ... do,on ... goto ... with,defer,ignore,on null/on halt - Statements: blocks,
assert,assume,print,foreach(with loopinvariants),while,if/else,break/continue/return, assignment, insert (+=), remove (-=),new, calls,raise,send,announce,goto,receive/case, and the empty statement; - Expressions: tuples/named tuples and field access (
x.0,x.f), collection indexing,keys/values/sizeof/in,default,choose,format,new, casts (as/to),$,$$,halt,this, decimal floats (1.5,.5) andfloat(base, exp), and all unary/binary operators with the precedence implied byPParser.g4's alternative order (casts bind between+/-and comparisons) - PVerifier extensions:
invariant,Lemma/Theoremgroups,axiom,init-condition,Proofblocks (prove ... using ... except ...),purefunctions, quantifiers (forall/exists ... :: ...),==>,<==>,is,targets,inflight,sent - Module system: primitive modules with bindings (
A -> B),union,compose,hidee,hidei,rename ... to ... in,main ... in,assert ... in, safety and refinement (refines) tests,pairwiseand(N wise)parameterized tests
The generated parser uses Tree-sitter language ABI 15 and requires a Tree-sitter 0.25 or newer runtime. Editor integrations must provide a compatible runtime independently of the editor or plugin version.
cd tree-sitter-p
tree-sitter generate # regenerate src/parser.c after editing grammar.js
tree-sitter test # run the corpus tests in test/corpus/
tree-sitter parse path/to/File.pWhen installed as a Node.js package, the default export is a language object
for the tree-sitter package:
import Parser from "tree-sitter";
import P from "tree-sitter-p";
const parser = new Parser();
parser.setLanguage(P);
const tree = parser.parse("event Ping;");queries/highlights.scm provides syntax highlighting captures for editors
that consume Tree-sitter queries.
The emacs/ directory contains an Emacs IDE layer for P, mirroring the
feature set of Peasy (the P
VS Code extension) and integrating
PeasyAI:
p-ts-mode.el— tree-sitter major mode: highlighting, indentation (4 spaces), imenu/which-func, plus toolchain commands:C-c C-c(p-ts-compile) —p compileat the nearest.pprojroot, with error/warning jumping viacompilation-mode.C-c C-t(p-ts-check) — run a test case chosen with completion fromp check --list-tests; prefix arg prompts for schedule count.
peasy.el— IDE features on top ofp-ts-mode:peasy-visualize-machine(C-c C-v) — render the machine at point as a Graphviz state diagram from the tree-sitter parse (Peasy uses Stately/XState for this; current P has dropped--mode stately).peasy-view-trace(C-c C-r) — browse PChecker*.trace.jsonerror traces as a filterable timeline (Peasy's ShiViz equivalent).peasy-minor-mode— Flymake backend running PeasyAI's 12 static validators (no LLM needed) viapeasy-bridge.py.peasy-apply-auto-fixes(C-c C-f) — apply PeasyAI's deterministic auto-fixes to the buffer.peasy-syntax-help(C-c C-h),peasy-search-examples(C-c C-s),peasy-doctor, and LLM-backed project commands (peasy-generate-project,peasy-fix-project,peasy-check-project) via the PeasyAI CLI.
emacs/snippets/p-ts-mode/— yasnippet templates ported from Peasy's snippet collection (machine, spec, state, handlers, statements).emacs/peasy-bridge.py— headless JSON bridge to PeasyAI's validation pipeline and RAG search (stdlib-only, no LLM calls).
(use-package p-ts-mode
:load-path "path/to/tree-sitter-p/emacs"
:mode "\\.p\\'")
(use-package peasy
:load-path "path/to/tree-sitter-p/emacs"
:custom (peasy-peasyai-directory "~/project/P/Src/PeasyAI")
:hook (p-ts-mode . peasy-minor-mode))
;; Optional: snippets
(with-eval-after-load 'yasnippet
(add-to-list 'yas-snippet-dirs "path/to/tree-sitter-p/emacs/snippets"))