tree-sitter-perga/grammar.js

182 lines
3.2 KiB
JavaScript
Raw Normal View History

2024-11-20 19:29:09 -08:00
/**
* @file Basic proof assistant based on Calculus of Constructions
* @author William Ball <williampi103@gmail.com>
* @license GPL3
*/
/// <reference types="tree-sitter-cli/dsl" />
// @ts-check
module.exports = grammar({
name: "perga",
2024-11-21 13:14:46 -08:00
extras: $ => [
$.comment,
/\s/,
],
2024-11-20 19:29:09 -08:00
rules: {
2024-12-10 21:40:39 -08:00
program : $ => repeat1(choice(
$.definition,
$.preprocess,
$.axiom,
$.section,
$.variable,
$.fixity,
)),
2024-11-20 19:29:09 -08:00
identifier : $ => /[a-zA-Z_]\w*/,
symbol : $ => /[!@#$%^&*-+=<>,./?{}\\|`~'\"∧∨⊙×≅]+/,
2024-11-20 19:29:09 -08:00
comment : $ => token(seq('--', /.*/)),
2024-12-06 15:25:45 -08:00
section : $ => seq(
'section', $.identifier,
$.program,
'end', $.identifier,
),
2024-12-10 21:40:39 -08:00
precedence : $ => /[0-9]+/,
fixity : $ => seq(
choice('infixl', 'infixr'),
$.precedence,
$.symbol,
';'
),
2024-12-06 15:25:45 -08:00
variable : $ => seq(
choice('variable', 'hypothesis'),
2024-12-14 11:10:59 -08:00
repeat1($.param_block),
2024-12-06 15:25:45 -08:00
';'
),
2024-11-20 19:29:09 -08:00
param_block : $ => seq(
'(',
2024-12-14 11:10:59 -08:00
field('param', repeat1(choice($.identifier, $.symbol))),
2024-11-20 19:29:09 -08:00
':',
2024-11-20 21:46:51 -08:00
field('type', $.expr),
2024-11-20 19:29:09 -08:00
')'
),
2024-12-10 21:40:39 -08:00
star : $ => "★",
2024-11-20 19:29:09 -08:00
square : $ => choice('□', '[]'),
2024-12-02 20:40:38 -08:00
sort : $ => choice($.star, $.square, seq($.square, /[0-9₀₁₂₃₄₅₆₇₈₉]+/)),
2024-11-20 19:29:09 -08:00
labs : $ => seq(
2024-11-20 21:46:51 -08:00
choice('λ', 'fun'),
2024-11-20 19:29:09 -08:00
repeat1($.param_block),
choice('=>', '⇒'),
$.expr,
),
labs_alt : $ => seq(
'[',
field('param', repeat1($.identifier)),
':',
field('type', $.expr),
']',
$.expr,
),
2024-11-20 19:29:09 -08:00
pabs : $ => seq(
2024-11-20 21:46:51 -08:00
choice('∏', 'forall'),
2024-11-20 19:29:09 -08:00
repeat1($.param_block),
',',
$.expr,
),
2024-12-10 23:39:53 -08:00
op_section : $ => seq(
'(',
$.symbol,
')',
),
2024-11-20 19:29:09 -08:00
term : $ => choice(
$.identifier,
2024-12-01 23:36:32 -08:00
$.sort,
2024-12-10 23:39:53 -08:00
$.op_section,
2024-11-20 19:29:09 -08:00
seq('(', $.expr, ')'),
),
2024-12-10 21:40:39 -08:00
// HACK:
// completely ignore precedence and associativity for treesitter
// the syntax tree is completely wrong, but it's good enough for syntax
// highlighting
2024-12-10 21:40:39 -08:00
binex : $ => seq(
$.app,
optional(seq($.symbol, $.binex)),
),
2024-11-23 10:06:53 -08:00
binding : $ => seq(
'(',
$.identifier,
2024-11-23 10:39:33 -08:00
repeat($.param_block),
optional($.ascription),
2024-11-23 10:06:53 -08:00
':=',
$.expr,
')',
),
let : $ => seq(
'let',
repeat1($.binding),
'in',
$.expr,
'end',
),
2024-11-20 19:29:09 -08:00
app : $ => repeat1($.term),
arrow : $ => prec.left(1, seq(
$.app_term,
2024-12-10 21:40:39 -08:00
'→',
2024-11-20 19:29:09 -08:00
$.expr,
)),
app_term : $ => choice(
$.labs,
$.labs_alt,
2024-11-20 19:29:09 -08:00
$.pabs,
2024-11-23 10:06:53 -08:00
$.let,
2024-12-10 21:40:39 -08:00
$.binex,
2024-11-20 19:29:09 -08:00
),
expr : $ => choice(
$.app_term,
$.arrow,
),
ascription : $ => seq(
':',
2024-11-20 21:46:51 -08:00
field('type', $.expr),
2024-11-20 19:29:09 -08:00
),
axiom : $ => seq(
'axiom',
2024-12-10 21:40:39 -08:00
field('name', choice($.identifier, $.symbol)),
repeat($.param_block),
$.ascription,
';'
),
2024-11-20 19:29:09 -08:00
definition : $ => seq(
'def',
2024-12-10 21:40:39 -08:00
field('name', choice($.identifier, $.symbol)),
2024-11-20 19:29:09 -08:00
repeat($.param_block),
optional($.ascription),
':=',
2024-12-10 21:40:39 -08:00
$.expr,
2024-11-20 19:29:09 -08:00
';',
),
2024-11-22 10:37:30 -08:00
preprocess : $ => seq($.command, $.post_command),
post_command : $ => /.+/,
command : $ => '@include',
2024-11-20 19:29:09 -08:00
}
});